11 #include <fwRuntime/io/ProfileReader.hpp> 12 #include <fwRuntime/operations.hpp> 13 #include <fwRuntime/profile/Profile.hpp> 15 #include <boost/filesystem.hpp> 16 #include <boost/program_options/options_description.hpp> 17 #include <boost/program_options/parsers.hpp> 18 #include <boost/program_options/positional_options.hpp> 19 #include <boost/program_options/variables_map.hpp> 28 # define CONSOLE_LOG false; 29 # define FILE_LOG true; 31 # define CONSOLE_LOG true; 32 # define FILE_LOG false; 35 #ifndef DEFAULT_PROFILE 36 #define DEFAULT_PROFILE profile.xml 39 #define GET_DEFAULT_PROFILE(x) #x 40 #define GET_DEFAULT_PROFILE2(x) GET_DEFAULT_PROFILE(x) 41 #define DEFAULT_PROFILE_STRING GET_DEFAULT_PROFILE2(DEFAULT_PROFILE) 44 #if defined(_WIN32) && _MSC_VER > 1499 && _MSC_VER < 1600 // Visual C++ 2008 only 46 #pragma message ( "Setting up manifest..." ) 50 #pragma comment(linker,"/manifestdependency:\"type='win32' " \ 51 "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' " \ 52 "version='" _CRT_ASSEMBLY_VERSION "' " \ 53 "processorArchitecture='*' " \ 54 "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "' " \ 58 #pragma comment(linker,"/manifestdependency:\"type='win32' " \ 59 "name='Microsoft.Windows.Common-Controls' " \ 60 "version='6.0.0.0' " \ 61 "processorArchitecture='*' " \ 62 "publicKeyToken='6595b64144ccf1df' " \ 68 namespace po = boost::program_options;
69 namespace fs = boost::filesystem;
71 typedef fs::path PathType;
72 typedef std::vector< PathType > PathListType;
73 typedef std::vector< std::string > StringListType;
79 template<
class A1,
class A2>
80 inline ostream& operator<<(ostream& s, vector<A1, A2>
const& vec)
82 copy(vec.begin(), vec.end(), ostream_iterator<A1>(s,
" "));
90 std::pair<std::string, std::string> parsePns(
const std::string& s)
92 if (s.substr(0, 5) ==
"-psn_")
94 return std::make_pair(std::string(
"psn"), s.substr(5));
96 return std::make_pair(std::string(), std::string());
102 PathType absolute(
const PathType& path )
104 return fs::absolute(path).normalize();
109 volatile sig_atomic_t gSignalStatus = 0;
112 void signal_handler(
int signal)
114 gSignalStatus = signal;
115 ::fwRuntime::profile::getCurrentProfile()->cleanup();
116 ::fwRuntime::profile::getCurrentProfile()->stop();
121 int main(
int argc,
char* argv[])
123 PathListType bundlePaths;
125 PathType profileFile;
126 ::fwRuntime::profile::Profile::ParamsContainer profileArgs;
129 po::options_description options(
"Launcher options");
130 options.add_options()
131 (
"help,h",
"Show help message")
132 (
"bundle-path,B", po::value(&bundlePaths)->default_value
134 "Adds a bundle path")
135 (
"rwd", po::value(&rwd)->default_value(
"./"),
"Sets runtime working directory")
139 bool consoleLog = CONSOLE_LOG;
140 bool fileLog = FILE_LOG;
142 const std::string defaultLogFile =
"SLM.log";
144 typedef ::fwCore::log::SpyLogger SpyLogger;
145 int logLevel = SpyLogger::SL_TRACE;
147 po::options_description logOptions(
"Log options");
148 logOptions.add_options()
149 (
"clog", po::value(&consoleLog)->implicit_value(
true)->zero_tokens(),
"Enable log output to console")
150 (
"no-clog", po::value(&consoleLog)->implicit_value(
false)->zero_tokens(),
"Disable log output to console")
151 (
"flog", po::value(&fileLog)->implicit_value(
true)->zero_tokens(),
"Enable log output to file")
152 (
"no-flog", po::value(&fileLog)->implicit_value(
false)->zero_tokens(),
"Disable log output to file")
153 (
"log-output", po::value(&logFile)->default_value(defaultLogFile),
"Log output filename")
155 (
"log-trace", po::value(&logLevel)->implicit_value(SpyLogger::SL_TRACE)->zero_tokens(),
"Set loglevel to trace")
156 (
"log-debug", po::value(&logLevel)->implicit_value(SpyLogger::SL_DEBUG)->zero_tokens(),
"Set loglevel to debug")
157 (
"log-info", po::value(&logLevel)->implicit_value(SpyLogger::SL_INFO )->zero_tokens(),
"Set loglevel to info")
158 (
"log-warn", po::value(&logLevel)->implicit_value(SpyLogger::SL_WARN )->zero_tokens(),
"Set loglevel to warn")
159 (
"log-error", po::value(&logLevel)->implicit_value(SpyLogger::SL_ERROR)->zero_tokens(),
"Set loglevel to error")
160 (
"log-fatal", po::value(&logLevel)->implicit_value(SpyLogger::SL_FATAL)->zero_tokens(),
"Set loglevel to fatal")
164 po::options_description hidden(
"Hidden options");
167 (
"psn", po::value<std::string>(),
"Application PSN number")
168 (
"NSDocumentRevisionsDebugMode", po::value<std::string>()->zero_tokens(),
"DocumentRevisionsDebugMode")
170 (
"profile", po::value(&profileFile)->default_value(DEFAULT_PROFILE_STRING),
"Profile file")
171 (
"profile-args", po::value(&profileArgs)->multitoken(),
"Profile args")
175 po::options_description cmdline_options;
176 cmdline_options.add(options).add(logOptions).add(hidden);
178 po::positional_options_description p;
179 p.add(
"profile", 1).add(
"profile-args", -1);
182 po::variables_map vm;
186 po::store(po::command_line_parser(argc, argv)
187 .options(cmdline_options)
189 .extra_parser(parsePns)
196 catch(
const po::error& e)
198 std::cerr << e.what() << std::endl;
203 if (vm.count(
"help"))
205 std::cout <<
"usage: " << argv[0] <<
" [options] [profile(=profile.xml)] [profile-args ...]" << std::endl;
206 std::cout <<
" use '--' to stop processing args for fwlauncher" << std::endl << std::endl;
207 std::cout << options << std::endl << logOptions << std::endl;
212 SpyLogger& logger = fwCore::log::SpyLogger::getSpyLogger();
216 logger.addStreamAppender(std::clog, static_cast<SpyLogger::LevelType>(logLevel));
221 FILE* pFile = fopen(logFile.c_str(),
"w");
224 ::boost::system::error_code err;
225 PathType sysTmp = fs::temp_directory_path(err);
229 logger.addStreamAppender(std::clog, static_cast<SpyLogger::LevelType>(logLevel));
234 sysTmp = sysTmp /
"SLM.log";
235 logFile = sysTmp.string();
236 logger.addFileAppender(logFile, static_cast<SpyLogger::LevelType>(logLevel));
242 logger.addFileAppender(logFile, static_cast<SpyLogger::LevelType>(logLevel));
248 fs::path execPath = argv[0];
250 if ( execPath.string().find(
".app/") != std::string::npos || vm.count(
"psn"))
252 bool isChdirOkOSX =
false;
254 fs::path execPath = argv[0];
256 while ( fs::extension(execPath) !=
".app" 257 && execPath != execPath.parent_path()
258 && !fs::is_directory( execPath / fs::path(BUNDLE_RC_PREFIX))
261 execPath = execPath.parent_path();
264 if ( fs::is_directory( execPath /
"Contents" / fs::path(BUNDLE_RC_PREFIX) ) )
266 execPath = execPath /
"Contents";
270 OSLM_ERROR_IF(
"Bundle directory not found.", !fs::is_directory( execPath / fs::path(BUNDLE_RC_PREFIX) ));
273 isChdirOkOSX = (chdir(execPath.string().c_str()) == 0);
275 SLM_ERROR_IF(
"Was not able to find a directory to change to.", !isChdirOkOSX);
279 OSLM_INFO_IF(
"Runtime working directory: " << rwd <<
" => " << ::absolute(rwd), vm.count(
"rwd") );
280 for(
const fs::path& bundlePath : bundlePaths )
282 OSLM_INFO_IF(
"Bundle paths are: " << bundlePath.string() <<
" => " << ::absolute(bundlePath),
283 vm.count(
"bundle-path") );
285 OSLM_INFO_IF(
"Profile path: " << profileFile <<
" => " << ::absolute(profileFile), vm.count(
"profile"));
286 OSLM_INFO_IF(
"Profile-args: " << profileArgs, vm.count(
"profile-args") );
289 OSLM_FATAL_IF(
"Runtime working directory doesn't exist: " << rwd.string() <<
" => " << ::absolute(
290 rwd), !::boost::filesystem::exists(rwd.string()) );
291 for(
const fs::path& bundlePath : bundlePaths )
293 OSLM_FATAL_IF(
"Bundle paths doesn't exist: " << bundlePath.string() <<
" => " << ::absolute(
294 bundlePath), !::boost::filesystem::exists(bundlePath.string()) );
296 OSLM_FATAL_IF(
"Profile path doesn't exist: " << profileFile.string() <<
" => " << ::absolute(
297 profileFile), !::boost::filesystem::exists(profileFile.string()));
299 std::transform( bundlePaths.begin(), bundlePaths.end(), bundlePaths.begin(), ::absolute );
300 profileFile = ::absolute(profileFile);
301 rwd = ::absolute(rwd);
304 const bool isChdirOk =
static_cast<bool>(SetCurrentDirectory(rwd.string().c_str()) != 0);
306 const bool isChdirOk = ( chdir(rwd.string().c_str()) == 0 );
308 OSLM_FATAL_IF(
"Was not able to change directory to : " << rwd, !isChdirOk);
310 for(
const fs::path& bundlePath : bundlePaths )
312 if ( fs::is_directory(bundlePath))
314 ::fwRuntime::addBundles( bundlePath );
318 OSLM_ERROR(
"Bundle path " << bundlePath <<
" do not exists or is not a directory.");
324 if ( fs::is_regular_file(profileFile))
326 ::fwRuntime::profile::Profile::sptr profile;
331 ::fwRuntime::profile::setCurrentProfile(profile);
334 std::signal(SIGINT, signal_handler);
336 profile->setParams(profileArgs);
340 if(gSignalStatus == 0)
345 catch(std::exception& e)
352 SLM_FATAL(
"An unrecoverable error has occurred." );
358 OSLM_ERROR(
"Profile file " << profileFile <<
" do not exists or is not a regular file.");
368 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR args,
int)
370 return main(__argc, __argv);
static FWRUNTIME_API Runtime * getDefault()
Retrieves the default runtime instance.
#define OSLM_INFO_IF(message, cond)
#define SLM_FATAL(message)
#define OSLM_ERROR(message)
#define SLM_ERROR_IF(message, cond)
#define OSLM_FATAL(message)
static FWRUNTIME_API std::shared_ptr< ::fwRuntime::profile::Profile > createProfile(const boost::filesystem::path &path)
Creates a profile from an xml file located at the given path.
#define OSLM_FATAL_IF(message, cond)
#define OSLM_ERROR_IF(message, cond)