diff options
author | Brad King <brad.king@kitware.com> | 2013-11-07 20:30:59 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2013-11-12 13:23:35 (GMT) |
commit | d1526f825e7464b8cb8a82b73718bbf2eb4965c9 (patch) | |
tree | 1830c8bb82b07c4a1c35145b677f975c9104a2b4 /Source/cmSystemTools.cxx | |
parent | 9fc158b6d5ae9902f544fd280c3b087c433fecc6 (diff) | |
download | CMake-d1526f825e7464b8cb8a82b73718bbf2eb4965c9.zip CMake-d1526f825e7464b8cb8a82b73718bbf2eb4965c9.tar.gz CMake-d1526f825e7464b8cb8a82b73718bbf2eb4965c9.tar.bz2 |
Refactor internal resource location APIs and initialization
Rename cmSystemTools::FindExecutableDirectory to FindCMakeResources.
Teach it to compute the locations of cmake, ctest, cpack, ccmake, and
cmake-gui executables, and the location of CMAKE_ROOT. Provide this
information from static cmSystemTools::Get<resource>() methods.
Refactor code that needs these locations to use the new APIs.
Teach FindCMakeResources to use the OS X system API to lookup the
executable location. When running from the CMake build tree itself,
leave a file in the tree that FindCMakeResources can use to read the
location of the source tree. This avoids the need to compile the source
tree location into a binary that may be installed and used without the
source tree.
Teach the QtDialog on OS X to create a "cmake-gui" symlink in the build
tree next to "cmake" and the other tools, as is already done in the
install tree for the application bundle. This ensures a consistent set
of executables are available in one directory.
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r-- | Source/cmSystemTools.cxx | 152 |
1 files changed, 143 insertions, 9 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 1ecda88..f5376eb 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -43,6 +43,10 @@ # include <sys/wait.h> #endif +#if defined(__APPLE__) +# include <mach-o/dyld.h> +#endif + #include <sys/stat.h> #if defined(_WIN32) && \ @@ -2011,16 +2015,59 @@ unsigned int cmSystemTools::RandomSeed() } //---------------------------------------------------------------------------- -static std::string cmSystemToolsExecutableDirectory; -void cmSystemTools::FindExecutableDirectory(const char* argv0) -{ +static std::string cmSystemToolsCMakeCommand; +static std::string cmSystemToolsCTestCommand; +static std::string cmSystemToolsCPackCommand; +static std::string cmSystemToolsCMakeCursesCommand; +static std::string cmSystemToolsCMakeGUICommand; +static std::string cmSystemToolsCMakeRoot; +void cmSystemTools::FindCMakeResources(const char* argv0) +{ + std::string exe_dir; #if defined(_WIN32) && !defined(__CYGWIN__) (void)argv0; // ignore this on windows char modulepath[_MAX_PATH]; ::GetModuleFileName(NULL, modulepath, sizeof(modulepath)); - cmSystemToolsExecutableDirectory = - cmSystemTools::GetFilenamePath(modulepath); - return; + exe_dir = cmSystemTools::GetFilenamePath(modulepath); +#elif defined(__APPLE__) + (void)argv0; // ignore this on OS X +# define CM_EXE_PATH_LOCAL_SIZE 16384 + char exe_path_local[CM_EXE_PATH_LOCAL_SIZE]; +# if defined(MAC_OS_X_VERSION_10_3) && !defined(MAC_OS_X_VERSION_10_4) + unsigned long exe_path_size = CM_EXE_PATH_LOCAL_SIZE; +# else + uint32_t exe_path_size = CM_EXE_PATH_LOCAL_SIZE; +# endif +# undef CM_EXE_PATH_LOCAL_SIZE + char* exe_path = exe_path_local; + if(_NSGetExecutablePath(exe_path, &exe_path_size) < 0) + { + exe_path = (char*)malloc(exe_path_size); + _NSGetExecutablePath(exe_path, &exe_path_size); + } + exe_dir = + cmSystemTools::GetFilenamePath( + cmSystemTools::GetRealPath(exe_path)); + if(exe_path != exe_path_local) + { + free(exe_path); + } + if(cmSystemTools::GetFilenameName(exe_dir) == "MacOS") + { + // The executable is inside an application bundle. + // Look for ../bin (install tree) and then fall back to + // ../../../bin (build tree). + exe_dir = cmSystemTools::GetFilenamePath(exe_dir); + if(cmSystemTools::FileExists((exe_dir+"/bin/cmake").c_str())) + { + exe_dir += "/bin"; + } + else + { + exe_dir = cmSystemTools::GetFilenamePath(exe_dir); + exe_dir = cmSystemTools::GetFilenamePath(exe_dir); + } + } #else std::string errorMsg; std::string exe; @@ -2028,7 +2075,7 @@ void cmSystemTools::FindExecutableDirectory(const char* argv0) { // remove symlinks exe = cmSystemTools::GetRealPath(exe.c_str()); - cmSystemToolsExecutableDirectory = + exe_dir = cmSystemTools::GetFilenamePath(exe.c_str()); } else @@ -2036,12 +2083,99 @@ void cmSystemTools::FindExecutableDirectory(const char* argv0) // ??? } #endif + cmSystemToolsCMakeCommand = exe_dir; + cmSystemToolsCMakeCommand += "/cmake"; + cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCTestCommand = exe_dir; + cmSystemToolsCTestCommand += "/ctest"; + cmSystemToolsCTestCommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCPackCommand = exe_dir; + cmSystemToolsCPackCommand += "/cpack"; + cmSystemToolsCPackCommand += cmSystemTools::GetExecutableExtension(); + cmSystemToolsCMakeGUICommand = exe_dir; + cmSystemToolsCMakeGUICommand += "/cmake-gui"; + cmSystemToolsCMakeGUICommand += cmSystemTools::GetExecutableExtension(); + if(!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand.c_str())) + { + cmSystemToolsCMakeGUICommand = ""; + } + cmSystemToolsCMakeCursesCommand = exe_dir; + cmSystemToolsCMakeCursesCommand += "/ccmake"; + cmSystemToolsCMakeCursesCommand += cmSystemTools::GetExecutableExtension(); + if(!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand.c_str())) + { + cmSystemToolsCMakeCursesCommand = ""; + } + +#ifdef CMAKE_BUILD_WITH_CMAKE + // Install tree has "<prefix>/bin/cmake" and "<prefix><CMAKE_DATA_DIR>". + std::string dir = cmSystemTools::GetFilenamePath(exe_dir); + cmSystemToolsCMakeRoot = dir + CMAKE_DATA_DIR; + if(!cmSystemTools::FileExists( + (cmSystemToolsCMakeRoot+"/Modules/CMake.cmake").c_str())) + { + // Build tree has "<build>/bin[/<config>]/cmake" and + // "<build>/CMakeFiles/CMakeSourceDir.txt". + std::string src_dir_txt = dir + "/CMakeFiles/CMakeSourceDir.txt"; + std::ifstream fin(src_dir_txt.c_str()); + std::string src_dir; + if(fin && cmSystemTools::GetLineFromStream(fin, src_dir) && + cmSystemTools::FileIsDirectory(src_dir.c_str())) + { + cmSystemToolsCMakeRoot = src_dir; + } + else + { + dir = cmSystemTools::GetFilenamePath(dir); + src_dir_txt = dir + "/CMakeFiles/CMakeSourceDir.txt"; + std::ifstream fin2(src_dir_txt.c_str()); + if(fin2 && cmSystemTools::GetLineFromStream(fin2, src_dir) && + cmSystemTools::FileIsDirectory(src_dir.c_str())) + { + cmSystemToolsCMakeRoot = src_dir; + } + } + } +#else + // Bootstrap build knows its source. + cmSystemToolsCMakeRoot = CMAKE_ROOT_DIR; +#endif +} + +//---------------------------------------------------------------------------- +std::string const& cmSystemTools::GetCMakeCommand() +{ + return cmSystemToolsCMakeCommand; +} + +//---------------------------------------------------------------------------- +std::string const& cmSystemTools::GetCTestCommand() +{ + return cmSystemToolsCTestCommand; +} + +//---------------------------------------------------------------------------- +std::string const& cmSystemTools::GetCPackCommand() +{ + return cmSystemToolsCPackCommand; +} + +//---------------------------------------------------------------------------- +std::string const& cmSystemTools::GetCMakeCursesCommand() +{ + return cmSystemToolsCMakeCursesCommand; +} + +//---------------------------------------------------------------------------- +std::string const& cmSystemTools::GetCMakeGUICommand() +{ + return cmSystemToolsCMakeGUICommand; } //---------------------------------------------------------------------------- -const char* cmSystemTools::GetExecutableDirectory() +std::string const& cmSystemTools::GetCMakeRoot() { - return cmSystemToolsExecutableDirectory.c_str(); + return cmSystemToolsCMakeRoot; } //---------------------------------------------------------------------------- |