diff options
Diffstat (limited to 'Source')
456 files changed, 10302 insertions, 5185 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 46bdec6..8bf6c40 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -9,33 +9,33 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -INCLUDE(CheckIncludeFile) +include(CheckIncludeFile) # Check if we can build support for ELF parsing. CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H) -IF(HAVE_ELF_H) - SET(CMAKE_USE_ELF_PARSER 1) -ELSE(HAVE_ELF_H) - SET(CMAKE_USE_ELF_PARSER) -ENDIF(HAVE_ELF_H) +if(HAVE_ELF_H) + set(CMAKE_USE_ELF_PARSER 1) +else() + set(CMAKE_USE_ELF_PARSER) +endif() -SET(EXECUTABLE_OUTPUT_PATH ${CMake_BIN_DIR}) +set(EXECUTABLE_OUTPUT_PATH ${CMake_BIN_DIR}) # configure the .h file -CONFIGURE_FILE( +configure_file( "${CMake_SOURCE_DIR}/Source/cmConfigure.cmake.h.in" "${CMake_BINARY_DIR}/Source/cmConfigure.h" ) -CONFIGURE_FILE( +configure_file( "${CMake_SOURCE_DIR}/Source/cmVersionConfig.h.in" "${CMake_BINARY_DIR}/Source/cmVersionConfig.h" ) -CONFIGURE_FILE( +configure_file( "${CMake_SOURCE_DIR}/Source/CPack/cmCPackConfigure.h.in" "${CMake_BINARY_DIR}/Source/CPack/cmCPackConfigure.h" ) # add the include path to find the .h -INCLUDE_DIRECTORIES( +include_directories( "${CMake_BINARY_DIR}/Source" "${CMake_SOURCE_DIR}/Source" ${CMAKE_ZLIB_INCLUDES} @@ -45,72 +45,72 @@ INCLUDE_DIRECTORIES( ) # let cmake know it is supposed to use it -ADD_DEFINITIONS(-DCMAKE_BUILD_WITH_CMAKE) +add_definitions(-DCMAKE_BUILD_WITH_CMAKE) -OPTION(CMAKE_REGENERATE_YACCLEX +option(CMAKE_REGENERATE_YACCLEX "Regenerate YACC and LEXX files" OFF) -MARK_AS_ADVANCED(CMAKE_REGENERATE_YACCLEX) -IF(CMAKE_REGENERATE_YACCLEX) - SET(parsersLexers cmDependsFortran cmCommandArgument cmExpr) - FIND_PROGRAM(YACC_EXECUTABLE +mark_as_advanced(CMAKE_REGENERATE_YACCLEX) +if(CMAKE_REGENERATE_YACCLEX) + set(parsersLexers cmDependsFortran cmCommandArgument cmExpr) + find_program(YACC_EXECUTABLE NAMES yacc bison PATHS /usr/bin DOC "Yacc or Bison executable") - FIND_PROGRAM(FLEX_EXECUTABLE + find_program(FLEX_EXECUTABLE NAMES flex PATHS /usr/bin DOC "Flex executable") - MARK_AS_ADVANCED(YACC_EXECUTABLE FLEX_EXECUTABLE) - IF(YACC_EXECUTABLE) - SET(BISON_FLAGS) - IF(YACC_EXECUTABLE MATCHES "bison") - SET(BISON_FLAGS "--yacc") - ENDIF(YACC_EXECUTABLE MATCHES "bison") - SET(yacc_files) - FOREACH(name ${parsersLexers}) - SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Parser.y") - SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Parser.cxx") - SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}ParserTokens.h") - ADD_CUSTOM_COMMAND( + mark_as_advanced(YACC_EXECUTABLE FLEX_EXECUTABLE) + if(YACC_EXECUTABLE) + set(BISON_FLAGS) + if(YACC_EXECUTABLE MATCHES "bison") + set(BISON_FLAGS "--yacc") + endif() + set(yacc_files) + foreach(name ${parsersLexers}) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Parser.y") + set(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Parser.cxx") + set(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}ParserTokens.h") + add_custom_command( OUTPUT "${dst}" DEPENDS "${src}" COMMAND ${YACC_EXECUTABLE} --name-prefix=${name}_yy --defines=${hdr} -o${dst} ${src} ) - SET(yacc_files ${yacc_files} "${dst}") - ENDFOREACH(name) - ADD_CUSTOM_TARGET(RerunYacc DEPENDS ${yacc_files}) - ENDIF(YACC_EXECUTABLE) - IF(FLEX_EXECUTABLE) - SET(lex_files) - FOREACH(name ${parsersLexers}) - SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Lexer.in.l") - SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.cxx") - SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.h") - ADD_CUSTOM_COMMAND( + set(yacc_files ${yacc_files} "${dst}") + endforeach() + add_custom_target(RerunYacc DEPENDS ${yacc_files}) + endif() + if(FLEX_EXECUTABLE) + set(lex_files) + foreach(name ${parsersLexers}) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Lexer.in.l") + set(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.cxx") + set(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.h") + add_custom_command( OUTPUT "${dst}" DEPENDS "${src}" COMMAND ${FLEX_EXECUTABLE} --prefix=${name}_yy --header-file=${hdr} -o${dst} ${src} ) - SET(lex_files ${lex_files} "${dst}") - ENDFOREACH(name) - ADD_CUSTOM_TARGET(RerunLex DEPENDS ${lex_files}) - ENDIF(FLEX_EXECUTABLE) + set(lex_files ${lex_files} "${dst}") + endforeach() + add_custom_target(RerunLex DEPENDS ${lex_files}) + endif() -ENDIF(CMAKE_REGENERATE_YACCLEX) +endif() # Check if we can build the ELF parser. -IF(CMAKE_USE_ELF_PARSER) - SET(ELF_SRCS cmELF.h cmELF.cxx) -ENDIF(CMAKE_USE_ELF_PARSER) +if(CMAKE_USE_ELF_PARSER) + set(ELF_SRCS cmELF.h cmELF.cxx) +endif() # # Sources for CMakeLib # -SET(SRCS +set(SRCS cmStandardIncludes.cxx cmArchiveWrite.cxx cmBootstrapCommands.cxx @@ -176,6 +176,10 @@ SET(SRCS cmExportFileGenerator.cxx cmExportInstallFileGenerator.h cmExportInstallFileGenerator.cxx + cmExportSet.h + cmExportSet.cxx + cmExportSetMap.h + cmExportSetMap.cxx cmExtraCodeBlocksGenerator.cxx cmExtraCodeBlocksGenerator.h cmExtraEclipseCDT4Generator.cxx @@ -183,6 +187,14 @@ SET(SRCS cmFileTimeComparison.cxx cmFileTimeComparison.h cmGeneratedFileStream.cxx + cmGeneratorExpressionDAGChecker.cxx + cmGeneratorExpressionDAGChecker.h + cmGeneratorExpressionEvaluator.cxx + cmGeneratorExpressionEvaluator.h + cmGeneratorExpressionLexer.cxx + cmGeneratorExpressionLexer.h + cmGeneratorExpressionParser.cxx + cmGeneratorExpressionParser.h cmGeneratorExpression.cxx cmGeneratorExpression.h cmGeneratorTarget.cxx @@ -219,6 +231,8 @@ SET(SRCS cmMakefileExecutableTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx cmMakefileUtilityTargetGenerator.cxx + cmOSXBundleGenerator.cxx + cmOSXBundleGenerator.h cmNewLineStyle.h cmNewLineStyle.cxx cmOrderDirectories.cxx @@ -249,6 +263,7 @@ SET(SRCS cmSystemTools.h cmTarget.cxx cmTarget.h + cmTargetExport.h cmTest.cxx cmTest.h cmTestGenerator.cxx @@ -273,30 +288,30 @@ SET(SRCS ) # Kdevelop only works on UNIX and not windows -IF(UNIX) - SET(SRCS ${SRCS} cmGlobalKdevelopGenerator.cxx) -ENDIF(UNIX) +if(UNIX) + set(SRCS ${SRCS} cmGlobalKdevelopGenerator.cxx) +endif() # Xcode only works on Apple -IF(APPLE) - SET(SRCS ${SRCS} +if(APPLE) + set(SRCS ${SRCS} cmXCodeObject.cxx cmXCode21Object.cxx cmGlobalXCodeGenerator.cxx cmGlobalXCodeGenerator.h cmLocalXCodeGenerator.cxx cmLocalXCodeGenerator.h) -ENDIF(APPLE) +endif() -IF (WIN32) - SET(SRCS ${SRCS} +if (WIN32) + set(SRCS ${SRCS} cmCallVisualStudioMacro.cxx cmCallVisualStudioMacro.h ) - IF(NOT UNIX) - SET(SRCS ${SRCS} + if(NOT UNIX) + set(SRCS ${SRCS} cmGlobalBorlandMakefileGenerator.cxx cmGlobalBorlandMakefileGenerator.h cmGlobalMSYSMakefileGenerator.cxx @@ -354,60 +369,51 @@ IF (WIN32) cmWin32ProcessExecution.cxx cmWin32ProcessExecution.h ) - ENDIF(NOT UNIX) -ENDIF (WIN32) - -# Turn on Ninja by default, but disable it -# on platforms where it does not pass all tests. -# Enforce Ninja support by setting CMAKE_USE_NINJA -set(_CMAKE_DEFAULT_NINJA_VALUE TRUE) -if(WIN32 OR APPLE) - SET(_CMAKE_DEFAULT_NINJA_VALUE FALSE) + endif() +endif () + +# Ninja support +set(SRCS ${SRCS} + cmGlobalNinjaGenerator.cxx + cmGlobalNinjaGenerator.h + cmNinjaTypes.h + cmLocalNinjaGenerator.cxx + cmLocalNinjaGenerator.h + cmNinjaTargetGenerator.cxx + cmNinjaTargetGenerator.h + cmNinjaNormalTargetGenerator.cxx + cmNinjaNormalTargetGenerator.h + cmNinjaUtilityTargetGenerator.cxx + cmNinjaUtilityTargetGenerator.h + ) +if(WIN32 AND NOT CYGWIN AND NOT BORLAND) + set_source_files_properties(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501) + add_executable(cmcldeps cmcldeps.cxx) + target_link_libraries(cmcldeps CMakeLib) + install_targets(/bin cmcldeps) endif() -SET(CMAKE_ENABLE_NINJA ${_CMAKE_DEFAULT_NINJA_VALUE} CACHE BOOL - "Enable the ninja generator for CMake. On Windows and OSX broken") -MARK_AS_ADVANCED(CMAKE_ENABLE_NINJA) -IF(CMAKE_ENABLE_NINJA) - MESSAGE(STATUS "Ninja generator enabled.") - SET(SRCS ${SRCS} - cmGlobalNinjaGenerator.cxx - cmGlobalNinjaGenerator.h - cmNinjaTypes.h - cmLocalNinjaGenerator.cxx - cmLocalNinjaGenerator.h - cmNinjaTargetGenerator.cxx - cmNinjaTargetGenerator.h - cmNinjaNormalTargetGenerator.cxx - cmNinjaNormalTargetGenerator.h - cmNinjaUtilityTargetGenerator.cxx - cmNinjaUtilityTargetGenerator.h - ) - ADD_DEFINITIONS(-DCMAKE_USE_NINJA) -ELSE() - MESSAGE(STATUS "Ninja generator disabled, enforce with -DCMAKE_ENABLE_NINJA=ON") -ENDIF() # create a library used by the command line and the GUI -ADD_LIBRARY(CMakeLib ${SRCS}) -TARGET_LINK_LIBRARIES(CMakeLib cmsys +add_library(CMakeLib ${SRCS}) +target_link_libraries(CMakeLib cmsys ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES} ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES} ${CMAKE_CURL_LIBRARIES} ) # On Apple we need CoreFoundation -IF(APPLE) - TARGET_LINK_LIBRARIES(CMakeLib "-framework CoreFoundation") -ENDIF(APPLE) +if(APPLE) + target_link_libraries(CMakeLib "-framework CoreFoundation") +endif() # On some platforms we need the rpcrt4 library for the VS 7 generators. -IF(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW) - TARGET_LINK_LIBRARIES(CMakeLib rpcrt4) -ENDIF(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW) +if(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW) + target_link_libraries(CMakeLib rpcrt4) +endif() # # CTestLib # -INCLUDE_DIRECTORIES( +include_directories( "${CMake_SOURCE_DIR}/Source/CTest" ${CMAKE_XMLRPC_INCLUDES} ${CMAKE_CURL_INCLUDES} @@ -415,7 +421,7 @@ INCLUDE_DIRECTORIES( # # Sources for CTestLib # -SET(CTEST_SRCS cmCTest.cxx +set(CTEST_SRCS cmCTest.cxx CTest/cmProcess.cxx CTest/cmCTestBatchTestHandler.cxx CTest/cmCTestBuildAndTestHandler.cxx @@ -468,13 +474,13 @@ SET(CTEST_SRCS cmCTest.cxx ) # Build CTestLib -ADD_LIBRARY(CTestLib ${CTEST_SRCS}) -TARGET_LINK_LIBRARIES(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_LIBRARIES}) +add_library(CTestLib ${CTEST_SRCS}) +target_link_libraries(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_LIBRARIES}) # # Sources for CPack # -SET(CPACK_SRCS +set(CPACK_SRCS CPack/cmCPackArchiveGenerator.cxx CPack/cmCPackComponentGroup.cxx CPack/cmCPackGeneratorFactory.cxx @@ -490,82 +496,82 @@ SET(CPACK_SRCS CPack/cmCPackDocumentMacros.cxx ) -IF(CYGWIN) - SET(CPACK_SRCS ${CPACK_SRCS} +if(CYGWIN) + set(CPACK_SRCS ${CPACK_SRCS} CPack/cmCPackCygwinBinaryGenerator.cxx CPack/cmCPackCygwinSourceGenerator.cxx ) -ENDIF(CYGWIN) +endif() -IF(UNIX) - SET(CPACK_SRCS ${CPACK_SRCS} +if(UNIX) + set(CPACK_SRCS ${CPACK_SRCS} CPack/cmCPackDebGenerator.cxx CPack/cmCPackRPMGenerator.cxx ) -ENDIF(UNIX) +endif() -IF(APPLE) - SET(CPACK_SRCS ${CPACK_SRCS} +if(APPLE) + set(CPACK_SRCS ${CPACK_SRCS} CPack/cmCPackBundleGenerator.cxx CPack/cmCPackDragNDropGenerator.cxx CPack/cmCPackOSXX11Generator.cxx CPack/cmCPackPackageMakerGenerator.cxx ) -ENDIF(APPLE) +endif() # Build CPackLib -ADD_LIBRARY(CPackLib ${CPACK_SRCS}) -TARGET_LINK_LIBRARIES(CPackLib CMakeLib) +add_library(CPackLib ${CPACK_SRCS}) +target_link_libraries(CPackLib CMakeLib) -IF(APPLE) - ADD_EXECUTABLE(cmakexbuild cmakexbuild.cxx) - TARGET_LINK_LIBRARIES(cmakexbuild CMakeLib) - ADD_EXECUTABLE(OSXScriptLauncher +if(APPLE) + add_executable(cmakexbuild cmakexbuild.cxx) + target_link_libraries(cmakexbuild CMakeLib) + add_executable(OSXScriptLauncher CPack/OSXScriptLauncher.cxx) - TARGET_LINK_LIBRARIES(OSXScriptLauncher cmsys) - TARGET_LINK_LIBRARIES(OSXScriptLauncher "-framework CoreFoundation") -ENDIF(APPLE) + target_link_libraries(OSXScriptLauncher cmsys) + target_link_libraries(OSXScriptLauncher "-framework CoreFoundation") +endif() # Build CMake executable -ADD_EXECUTABLE(cmake cmakemain.cxx) -TARGET_LINK_LIBRARIES(cmake CMakeLib) +add_executable(cmake cmakemain.cxx) +target_link_libraries(cmake CMakeLib) # Build special executable for running programs on Windows 98 -IF(WIN32) - IF(NOT UNIX) - ADD_EXECUTABLE(cmw9xcom cmw9xcom.cxx) - TARGET_LINK_LIBRARIES(cmw9xcom CMakeLib) - INSTALL_TARGETS(/bin cmw9xcom) - ENDIF(NOT UNIX) -ENDIF(WIN32) +if(WIN32) + if(NOT UNIX) + add_executable(cmw9xcom cmw9xcom.cxx) + target_link_libraries(cmw9xcom CMakeLib) + install_targets(/bin cmw9xcom) + endif() +endif() # Build CTest executable -ADD_EXECUTABLE(ctest ctest.cxx) -TARGET_LINK_LIBRARIES(ctest CTestLib) +add_executable(ctest ctest.cxx) +target_link_libraries(ctest CTestLib) # Build CPack executable -ADD_EXECUTABLE(cpack CPack/cpack.cxx) -TARGET_LINK_LIBRARIES(cpack CPackLib) +add_executable(cpack CPack/cpack.cxx) +target_link_libraries(cpack CPackLib) # Curses GUI -IF(BUILD_CursesDialog) - INCLUDE(${CMake_SOURCE_DIR}/Source/CursesDialog/CMakeLists.txt) -ENDIF(BUILD_CursesDialog) +if(BUILD_CursesDialog) + include(${CMake_SOURCE_DIR}/Source/CursesDialog/CMakeLists.txt) +endif() # Qt GUI -OPTION(BUILD_QtDialog "Build Qt dialog for CMake" FALSE) -IF(BUILD_QtDialog) - SUBDIRS(QtDialog) -ENDIF(BUILD_QtDialog) - -INCLUDE (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL) -INCLUDE (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL) - -INSTALL_TARGETS(/bin cmake) -INSTALL_TARGETS(/bin ctest) -INSTALL_TARGETS(/bin cpack) -IF(APPLE) - INSTALL_TARGETS(/bin cmakexbuild) -ENDIF(APPLE) - -INSTALL_FILES(${CMAKE_DATA_DIR}/include cmCPluginAPI.h) +option(BUILD_QtDialog "Build Qt dialog for CMake" FALSE) +if(BUILD_QtDialog) + add_subdirectory(QtDialog) +endif() + +include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL) +include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL) + +install_targets(/bin cmake) +install_targets(/bin ctest) +install_targets(/bin cpack) +if(APPLE) + install_targets(/bin cmakexbuild) +endif() + +install_files(${CMAKE_DATA_DIR}/include cmCPluginAPI.h) diff --git a/Source/CMakeVersion.bash b/Source/CMakeVersion.bash index 126adba..4794e60 100755 --- a/Source/CMakeVersion.bash +++ b/Source/CMakeVersion.bash @@ -3,5 +3,5 @@ if test "x$1" = "x-f"; then shift ; n='*' ; else n='\{8\}' ; fi if test "$#" -gt 0; then echo 1>&2 "usage: CMakeVersion.bash [-f]"; exit 1; fi sed -i -e ' -s/\(^SET(CMake_VERSION_TWEAK\) [0-9]'"$n"'\(.*\)/\1 '"$(date +%Y%m%d)"'\2/ +s/\(^set(CMake_VERSION_TWEAK\) [0-9]'"$n"'\(.*\)/\1 '"$(date +%Y%m%d)"'\2/ ' "${BASH_SOURCE%/*}/CMakeVersion.cmake" diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 345a56f..5bd83ca 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,6 +1,6 @@ # CMake version number components. -SET(CMake_VERSION_MAJOR 2) -SET(CMake_VERSION_MINOR 8) -SET(CMake_VERSION_PATCH 8) -SET(CMake_VERSION_TWEAK 20120612) -#SET(CMake_VERSION_RC 1) +set(CMake_VERSION_MAJOR 2) +set(CMake_VERSION_MINOR 8) +set(CMake_VERSION_PATCH 10) +set(CMake_VERSION_TWEAK 20121106) +#set(CMake_VERSION_RC 1) diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx index e0fbe9b..a9842c1 100644 --- a/Source/CPack/OSXScriptLauncher.cxx +++ b/Source/CPack/OSXScriptLauncher.cxx @@ -93,7 +93,7 @@ int main(int argc, char* argv[]) cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); cmsysProcess_SetTimeout(cp, 0); cmsysProcess_Execute(cp); - + std::vector<char> tempOutput; char* data; int length; @@ -111,9 +111,9 @@ int main(int argc, char* argv[]) } cmsys_ios::cout.write(data, length); } - + cmsysProcess_WaitForExit(cp, 0); - + bool result = true; if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { @@ -140,7 +140,7 @@ int main(int argc, char* argv[]) std::cerr << error_str << std::endl; result = false; } - + cmsysProcess_Delete(cp); return 0; diff --git a/Source/CPack/bills-comments.txt b/Source/CPack/bills-comments.txt index f73499d..c3b4ee8 100644 --- a/Source/CPack/bills-comments.txt +++ b/Source/CPack/bills-comments.txt @@ -1,18 +1,18 @@ cpack.cxx - -cmCPackGenerators -- creates cmCPackGenericGenerator's via NewGenerator + +cmCPackGenerators -- creates cmCPackGenericGenerator's via NewGenerator - a cmCPackGenericGenerator factory cmCPackGenericGenerator::Initialize this->InitializeInternal - CPACK_INCLUDE_TOPLEVEL_DIRECTORY = 0 turns off + CPACK_INCLUDE_TOPLEVEL_DIRECTORY = 0 turns off // binary package run cmCPackGenericGenerator::ProcessGenerator // DoPackage cmCPackGenericGenerator::PrepareNames -- sets a bunch of CPACK_vars - cmCPackGenericGenerator::InstallProject + cmCPackGenericGenerator::InstallProject run preinstall (make preinstall/fast) call ReadListFile(cmake_install.cmake) glob recurse in install directory to get list of files @@ -22,9 +22,9 @@ cmCPackGenericGenerator::ProcessGenerator // DoPackage // source package run cmCPackGenericGenerator::ProcessGenerator // DoPackage cmCPackGenericGenerator::PrepareNames -- sets a bunch of CPACK_vars - cmCPackGenericGenerator::InstallProject --> + cmCPackGenericGenerator::InstallProject --> if set CPACK_INSTALLED_DIRECTORIES - glob the files in that directory + glob the files in that directory copy those files to the tmp install directory _CPack something glob recurse in install directory to get list of files this->CompressFiles with the list of files @@ -35,12 +35,12 @@ packages. It is controled based on values set in CPACK_ variables. InstallProject - 1. CPACK_INSTALL_COMMANDS - a list of commands used to install the package + 1. CPACK_INSTALL_COMMANDS - a list of commands used to install the package 2. CPACK_INSTALLED_DIRECTORIES - copy this directory to CPACK_TEMPORARY_DIRECTORY 3. CPACK_INSTALL_CMAKE_PROJECTS - a cmake install script - - run make preinstall + - run make preinstall - run cmake_install.cmake - set CMAKE_INSTALL_PREFIX to the temp directory - CPACK_BUILD_CONFIG check this and set the BUILD_TYPE to it @@ -59,10 +59,10 @@ rename cmCPackGenericGenerator::ProcessGenerator -> cmCPackGenerator::DoPackage break up cmCPackGenerator::InstallProject so it calls the following: // run user provided install commands - cmCPackGenerator::RunInstallCommands(); + cmCPackGenerator::RunInstallCommands(); // copy entire directories that need no processing like source trees - cmCPackGenerator::CopyPreInstalledDirectories(); + cmCPackGenerator::CopyPreInstalledDirectories(); // run the cmake install scripts if provided - cmCPackGenerator::RunCMakeInstallScripts() + cmCPackGenerator::RunCMakeInstallScripts() - diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index b1bbb83..6411b1e 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -33,7 +33,7 @@ public: */ cmCPackArchiveGenerator(cmArchiveWrite::Compress, cmArchiveWrite::Type); virtual ~cmCPackArchiveGenerator(); - // Used to add a header to the archive + // Used to add a header to the archive virtual int GenerateHeader(std::ostream* os); // component support virtual bool SupportsComponentInstallation() const; diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index af78e78..6c994f1 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -91,8 +91,8 @@ int cmCPackBundleGenerator::PackageFiles() } // Get optional arguments ... - const std::string cpack_bundle_startup_command = - this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND") + const std::string cpack_bundle_startup_command = + this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND") ? this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND") : ""; // The staging directory contains everything that will end-up inside the diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx index 1d21fb1..f93eca8 100644 --- a/Source/CPack/cmCPackComponentGroup.cxx +++ b/Source/CPack/cmCPackComponentGroup.cxx @@ -36,7 +36,7 @@ unsigned long cmCPackComponent::GetInstalledSize(const char* installDir) const } //---------------------------------------------------------------------- -unsigned long +unsigned long cmCPackComponent::GetInstalledSizeInKbytes(const char* installDir) const { unsigned long result = (GetInstalledSize(installDir) + 512) / 1024; diff --git a/Source/CPack/cmCPackComponentGroup.h b/Source/CPack/cmCPackComponentGroup.h index cebdd6d..abae372 100644 --- a/Source/CPack/cmCPackComponentGroup.h +++ b/Source/CPack/cmCPackComponentGroup.h @@ -18,7 +18,7 @@ class cmCPackComponentGroup; /** \class cmCPackInstallationType - * \brief A certain type of installation, which encompasses a + * \brief A certain type of installation, which encompasses a * set of components. */ class cmCPackInstallationType @@ -42,7 +42,9 @@ public: class cmCPackComponent { public: - cmCPackComponent() : Group(0), TotalSize(0) { } + cmCPackComponent() : Group(0), IsRequired(true), IsHidden(false), + IsDisabledByDefault(false), IsDownloaded(false), + TotalSize(0) { } /// The name of the component (used to reference the component). std::string Name; @@ -90,7 +92,7 @@ public: std::vector<std::string> Directories; /// Get the total installed size of all of the files in this - /// component, in bytes. installDir is the directory into which the + /// component, in bytes. installDir is the directory into which the /// component was installed. unsigned long GetInstalledSize(const char* installDir) const; diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx index 6c8fc54..6605f16 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx @@ -50,7 +50,7 @@ int cmCPackCygwinBinaryGenerator::PackageFiles() std::string manifest = "/usr/share/doc/"; manifest += packageName; manifest += "/MANIFEST"; - std::string manifestFile + std::string manifestFile = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); // Create a MANIFEST file that contains all of the files in // the tar file @@ -70,8 +70,8 @@ int cmCPackCygwinBinaryGenerator::PackageFiles() } // add the manifest file to the list of all files files.push_back(manifestFile); - - // create the bzip2 tar file + + // create the bzip2 tar file return this->Superclass::PackageFiles(); } @@ -81,8 +81,8 @@ const char* cmCPackCygwinBinaryGenerator::GetOutputExtension() const char* patchNumber =this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); if(!patchNumber) { - patchNumber = "1"; - cmCPackLogger(cmCPackLog::LOG_WARNING, + patchNumber = "1"; + cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER not specified using 1" << std::endl); } diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx index 5979729..f1e8539 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx +++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx @@ -68,18 +68,18 @@ int cmCPackCygwinSourceGenerator::PackageFiles() // and the CPACK_CYGWIN_PATCH_FILE and CPACK_TOPLEVEL_DIRECTORY // files std::string compressOutFile = packageDirFileName; - // at this point compressOutFile is the full path to + // at this point compressOutFile is the full path to // _CPack_Package/.../package-2.5.0.tar.bz2 // we want to create a tar _CPack_Package/.../package-2.5.0-1-src.tar.bz2 - // with these - // _CPack_Package/.../package-2.5.0-1.patch + // with these + // _CPack_Package/.../package-2.5.0-1.patch // _CPack_Package/.../package-2.5.0-1.sh // _CPack_Package/.../package-2.5.0.tar.bz2 // the -1 is CPACK_CYGWIN_PATCH_NUMBER - + // first copy the patch file and the .sh file // to the toplevel cpack temp dir - + // copy the patch file into place if(!this->GetOption("CPACK_CYGWIN_PATCH_FILE")) { @@ -98,7 +98,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles() } if(!this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT")) { - cmCPackLogger(cmCPackLog::LOG_ERROR, + cmCPackLogger(cmCPackLog::LOG_ERROR, "No build script specified for cygwin sources."); return 0; } @@ -168,7 +168,7 @@ const char* cmCPackCygwinSourceGenerator::GetPackagingInstallPrefix() const char* cmCPackCygwinSourceGenerator::GetOutputExtension() { this->OutputExtension = "-"; - const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); + const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER"); if(!patch) { cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER" @@ -179,4 +179,4 @@ const char* cmCPackCygwinSourceGenerator::GetOutputExtension() this->OutputExtension += "-src.tar.bz2"; return this->OutputExtension.c_str(); } - + diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index fa456de..f99db58 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -76,6 +76,11 @@ int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel, packageFileName.c_str()); // Tell CPackDeb.cmake the name of the component GROUP. this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",packageName.c_str()); + // Tell CPackDeb.cmake the path where the component is. + std::string component_path = "/"; + component_path += packageName; + this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", + component_path.c_str()); if (!this->ReadListFile("CPackDeb.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -198,8 +203,11 @@ int cmCPackDebGenerator::PackageComponentsAllInOne() /* replace the TEMPORARY package file name */ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName.c_str()); - // Tell CPackDeb.cmake the name of the component GROUP. - this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",compInstDirName.c_str()); + // Tell CPackDeb.cmake the path where the component is. + std::string component_path = "/"; + component_path += compInstDirName; + this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH", + component_path.c_str()); if (!this->ReadListFile("CPackDeb.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -293,15 +301,15 @@ int cmCPackDebGenerator::createDeb() // debian policy enforce lower case for package name // mandatory entries: - std::string debian_pkg_name = cmsys::SystemTools::LowerCase( + std::string debian_pkg_name = cmsys::SystemTools::LowerCase( this->GetOption("CPACK_DEBIAN_PACKAGE_NAME") ); - const char* debian_pkg_version = + const char* debian_pkg_version = this->GetOption("CPACK_DEBIAN_PACKAGE_VERSION"); - const char* debian_pkg_section = + const char* debian_pkg_section = this->GetOption("CPACK_DEBIAN_PACKAGE_SECTION"); - const char* debian_pkg_priority = + const char* debian_pkg_priority = this->GetOption("CPACK_DEBIAN_PACKAGE_PRIORITY"); - const char* debian_pkg_arch = + const char* debian_pkg_arch = this->GetOption("CPACK_DEBIAN_PACKAGE_ARCHITECTURE"); const char* maintainer = this->GetOption("CPACK_DEBIAN_PACKAGE_MAINTAINER"); const char* desc = this->GetOption("CPACK_DEBIAN_PACKAGE_DESCRIPTION"); @@ -719,8 +727,8 @@ static int copy_ar(CF *cfp, off_t size) FILE* from = cfp->rFile; FILE* to = cfp->wFile; - while (sz && - (nr = fread(buf, 1, sz < static_cast<off_t>(sizeof(buf)) + while (sz && + (nr = fread(buf, 1, sz < static_cast<off_t>(sizeof(buf)) ? static_cast<size_t>(sz) : sizeof(buf), from )) > 0) { sz -= nr; @@ -731,7 +739,7 @@ static int copy_ar(CF *cfp, off_t size) if (sz) return -2; - if (cfp->flags & WPAD && (size + ar_already_written) & 1 + if (cfp->flags & WPAD && (size + ar_already_written) & 1 && fwrite(&pad, 1, 1, to) != 1) return -4; @@ -767,8 +775,8 @@ static int put_arobj(CF *cfp, struct stat *sb) (long long)sb->st_size + lname, ARFMAG); else { lname = 0; - (void)sprintf(ar_hb, HDR2, name, - (long int)sb->st_mtime, uid, gid, sb->st_mode, + (void)sprintf(ar_hb, HDR2, name, + (long int)sb->st_mtime, uid, gid, sb->st_mode, (long long)sb->st_size, ARFMAG); } off_t size = sb->st_size; @@ -790,7 +798,7 @@ static int put_arobj(CF *cfp, struct stat *sb) /* append -- * Append files to the archive - modifies original archive or creates - * a new archive if named archive does not exist. + * a new archive if named archive does not exist. */ static int ar_append(const char* archive,const std::vector<std::string>& files) { diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h index 7f2352f..d678cfa 100644 --- a/Source/CPack/cmCPackDebGenerator.h +++ b/Source/CPack/cmCPackDebGenerator.h @@ -35,7 +35,10 @@ public: { #ifdef __APPLE__ // on MacOS enable CPackDeb iff dpkg is found - return cmSystemTools::FindProgram("dpkg") != "" ? true : false; + std::vector<std::string> locations; + locations.push_back("/sw/bin"); // Fink + locations.push_back("/opt/local/bin"); // MacPorts + return cmSystemTools::FindProgram("dpkg",locations) != "" ? true : false; #else // legacy behavior on other systems return true; diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx index edbef45..6a841fa 100644 --- a/Source/CPack/cmCPackDocumentVariables.cxx +++ b/Source/CPack/cmCPackDocumentVariables.cxx @@ -31,31 +31,42 @@ void cmCPackDocumentVariables::DefineVariables(cmake* cm) "Each CPack generator as a built-in default value for this" " variable. E.g. Archive generators (ZIP, TGZ, ...) includes" " the top level whereas RPM or DEB don't. The user may override" - " the default value byt setting this variable.\n" + " the default value by setting this variable.\n" "There is a similar variable " - "CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY" + "CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY " "which may be used to override the behavior for the component" - "packaging case which may have different default value for" - "historical (now backward compatibility) reason.", false, + " packaging case which may have different default value for" + " historical (now backward compatibility) reason.", false, "Variables common to all CPack generators"); cm->DefineProperty + ("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY", cmProperty::VARIABLE, + "Boolean toggle to include/exclude top level directory " + "(component case).", + "Similar usage as CPACK_INCLUDE_TOPLEVEL_DIRECTORY" + " but for the component case. " + "See CPACK_INCLUDE_TOPLEVEL_DIRECTORY documentation for" + " the detail.", false, + "Variables common to all CPack generators"); + + cm->DefineProperty ("CPACK_SET_DESTDIR", cmProperty::VARIABLE, "Boolean toggle to make CPack use DESTDIR mechanism when" " packaging.", "DESTDIR means DESTination DIRectory." " It is commonly used by makefile " "users in order to install software at non-default location. It " - "is a basic relocation mechanism. " + "is a basic relocation mechanism that should not be used on" + " Windows (see CMAKE_INSTALL_PREFIX documentation). " "It is usually invoked like this:\n" " make DESTDIR=/home/john install\n" "which will install the concerned software using the" - " installation prefix, e.g. \"/usr/local\" prepended with " + " installation prefix, e.g. \"/usr/local\" pre-pended with " "the DESTDIR value which finally gives \"/home/john/usr/local\"." " When preparing a package, CPack first installs the items to be " "packaged in a local (to the build tree) directory by using the " "same DESTDIR mechanism. Nevertheless, if " "CPACK_SET_DESTDIR is set then CPack will set DESTDIR before" - " doing the local install. The most noticeable difference is" + " doing the local install. The most noticeable difference is" " that without CPACK_SET_DESTDIR, CPack uses " "CPACK_PACKAGING_INSTALL_PREFIX as a prefix whereas with " "CPACK_SET_DESTDIR set, CPack will use CMAKE_INSTALL_PREFIX as" diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 6aee401..d973c01 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -17,7 +17,7 @@ #include <cmsys/RegularExpression.hxx> -static const char* SLAHeader = +static const char* SLAHeader = "data 'LPic' (5000) {\n" " $\"0002 0011 0003 0001 0000 0000 0002 0000\"\n" " $\"0008 0003 0000 0001 0004 0000 0004 0005\"\n" @@ -29,7 +29,7 @@ static const char* SLAHeader = "};\n" "\n"; -static const char* SLASTREnglish = +static const char* SLASTREnglish = "resource 'STR#' (5002, \"English\") {\n" " {\n" " \"English\",\n" @@ -90,7 +90,7 @@ int cmCPackDragNDropGenerator::InitializeInternal() return 0; } this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path.c_str()); - + const std::string rez_path = cmSystemTools::FindProgram("Rez", paths, false); if(rez_path.empty()) @@ -222,7 +222,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Get optional arguments ... const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON") ? this->GetOption("CPACK_PACKAGE_ICON") : ""; - + const std::string cpack_dmg_volume_name = this->GetOption("CPACK_DMG_VOLUME_NAME") ? this->GetOption("CPACK_DMG_VOLUME_NAME") @@ -233,8 +233,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, ? this->GetOption("CPACK_DMG_FORMAT") : "UDZO"; // Get optional arguments ... - std::string cpack_license_file = - this->GetOption("CPACK_RESOURCE_FILE_LICENSE") ? + std::string cpack_license_file = + this->GetOption("CPACK_RESOURCE_FILE_LICENSE") ? this->GetOption("CPACK_RESOURCE_FILE_LICENSE") : ""; const std::string cpack_dmg_background_image = @@ -405,7 +405,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, cmOStringStream detach_command; detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); detach_command << " detach"; - detach_command << " \"" << temp_mount.str() << "\""; + detach_command << " \"" << temp_mount.str() << "\""; if(!this->RunCommand(detach_command)) { @@ -416,7 +416,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, return 0; } } - + if(!cpack_license_file.empty()) { std::string sla_r = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); @@ -442,7 +442,22 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, line.replace(pos, 1, "\\\""); pos = line.find('\"', pos+2); } - osf << " \"" << line << "\\n\"\n"; + // break up long lines to avoid Rez errors + std::vector<std::string> lines; + const size_t max_line_length = 512; + for(size_t i=0; i<line.size(); i+= max_line_length) + { + int line_length = max_line_length; + if(i+max_line_length > line.size()) + line_length = line.size()-i; + lines.push_back(line.substr(i, line_length)); + } + + for(size_t i=0; i<lines.size(); i++) + { + osf << " \"" << lines[i] << "\"\n"; + } + osf << " \"\\n\"\n"; } osf << "};\n"; osf << "\n"; @@ -460,7 +475,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, udco_image_command << " convert \"" << temp_image << "\""; udco_image_command << " -format UDCO"; udco_image_command << " -o \"" << temp_udco << "\""; - + std::string error; if(!this->RunCommand(udco_image_command, &error)) { @@ -476,17 +491,17 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); unflatten_command << " unflatten "; unflatten_command << "\"" << temp_udco << "\""; - + if(!this->RunCommand(unflatten_command, &error)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error unflattening dmg for adding SLA." << std::endl - << error + << error << std::endl); return 0; } - - // Rez the SLA + + // Rez the SLA cmOStringStream embed_sla_command; embed_sla_command << this->GetOption("CPACK_COMMAND_REZ"); embed_sla_command << " \"" << sla_r << "\""; @@ -496,8 +511,8 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, if(!this->RunCommand(embed_sla_command, &error)) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Error adding SLA." << std::endl - << error + "Error adding SLA." << std::endl + << error << std::endl); return 0; } @@ -507,7 +522,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); flatten_command << " flatten "; flatten_command << "\"" << temp_udco << "\""; - + if(!this->RunCommand(flatten_command, &error)) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -530,7 +545,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, final_image_command << " -imagekey"; final_image_command << " zlib-level=9"; final_image_command << " -o \"" << output_file << "\""; - + if(!this->RunCommand(final_image_command)) { cmCPackLogger(cmCPackLog::LOG_ERROR, diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 0177653..e964696 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -105,7 +105,7 @@ int cmCPackGenerator::PrepareNames() "CPACK_PACKAGE_FILE_NAME not specified" << std::endl); return 0; } - std::string outName = pfname; + std::string outName = pfname; tempDirectory += "/" + outName; if(!this->GetOutputExtension()) { @@ -149,7 +149,7 @@ int cmCPackGenerator::PrepareNames() if ( !cmSystemTools::FileExists(descFileName) ) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Cannot find description file name: [" + "Cannot find description file name: [" << descFileName << "]" << std::endl); return 0; } @@ -207,7 +207,7 @@ int cmCPackGenerator::InstallProject() if ( !cmsys::SystemTools::MakeDirectory(bareTempInstallDirectory.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem creating temporary directory: " + "Problem creating temporary directory: " << (tempInstallDirectory ? tempInstallDirectory : "(NULL}") << std::endl); return 0; @@ -584,7 +584,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( !(this->IsSet("CPACK_MONOLITHIC_INSTALL"))) { // Determine the installation types for this project (if provided). - std::string installTypesVar = "CPACK_" + std::string installTypesVar = "CPACK_" + cmSystemTools::UpperCase(installComponent) + "_INSTALL_TYPES"; const char *installTypes = this->GetOption(installTypesVar.c_str()); if (installTypes && *installTypes) @@ -596,16 +596,16 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( installTypeIt != installTypesVector.end(); ++installTypeIt) { - this->GetInstallationType(installProjectName.c_str(), + this->GetInstallationType(installProjectName.c_str(), installTypeIt->c_str()); } } // Determine the set of components that will be used in this project - std::string componentsVar + std::string componentsVar = "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent); const char *components = this->GetOption(componentsVar.c_str()); - if (components && *components) + if (components && *components) { cmSystemTools::ExpandListArgument(components, componentsVector); std::vector<std::string>::iterator compIt; @@ -688,10 +688,10 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( if (componentInstall) { cmCPackLogger(cmCPackLog::LOG_OUTPUT, - "- Install component: " << installComponent + "- Install component: " << installComponent << std::endl); } - + cmake cm; cm.AddCMakePaths(); cm.SetProgressCallback(cmCPackGeneratorProgress, this); @@ -758,7 +758,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf->AddDefinition)" << std::endl); cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" + "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" << std::endl); // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory @@ -792,7 +792,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( if ( !cmsys::SystemTools::MakeDirectory(dir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem creating temporary directory: " + "Problem creating temporary directory: " << dir << std::endl); return 0; } @@ -806,7 +806,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( tempInstallDirectory.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem creating temporary directory: " + "Problem creating temporary directory: " << tempInstallDirectory << std::endl); return 0; } @@ -832,7 +832,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( installComponent.c_str()); } - // strip on TRUE, ON, 1, one or several file names, but not on + // strip on TRUE, ON, 1, one or several file names, but not on // FALSE, OFF, 0 and an empty string if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) { @@ -855,7 +855,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION // then forward request to cmake_install.cmake script - if (this->GetOption("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) + if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) { mf->AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); @@ -865,7 +865,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // then ask cmake_install.cmake script to error out // as soon as it occurs (before installing file) if (!SupportsAbsoluteDestination() || - this->GetOption("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) + this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) { mf->AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); @@ -905,7 +905,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( localFileName = cmSystemTools::RelativePath(InstallPrefix, fit->c_str()); localFileName = - localFileName.substr(localFileName.find('/')+1, + localFileName.substr(localFileName.find_first_not_of('/'), std::string::npos); Components[installComponent].Files.push_back(localFileName); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" @@ -1024,7 +1024,7 @@ int cmCPackGenerator::DoPackage() = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); if ( cmSystemTools::FileExists(toplevelDirectory) ) { - cmCPackLogger(cmCPackLog::LOG_VERBOSE, + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove toplevel directory: " << toplevelDirectory << std::endl); if ( !cmSystemTools::RepeatedRemoveDirectory(toplevelDirectory) ) @@ -1153,10 +1153,10 @@ int cmCPackGenerator::Initialize(const char* name, cmMakefile* mf) // set the running generator name this->SetOption("CPACK_GENERATOR", this->Name.c_str()); // Load the project specific config file - const char* config = + const char* config = this->GetOption("CPACK_PROJECT_CONFIG_FILE"); if(config) - { + { mf->ReadListFile(config); } int result = this->InitializeInternal(); @@ -1193,13 +1193,13 @@ bool cmCPackGenerator::IsOn(const char* name) const //---------------------------------------------------------------------- const char* cmCPackGenerator::GetOption(const char* op) const -{ +{ const char* ret = this->MakefileMap->GetDefinition(op); if(!ret) - { - cmCPackLogger(cmCPackLog::LOG_DEBUG, + { + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Warning, GetOption return NULL for: " - << op + << op << std::endl); } return ret; @@ -1222,7 +1222,7 @@ int cmCPackGenerator::SetCMakeRoot() return 1; } cmCPackLogger(cmCPackLog::LOG_ERROR, - "Could not find CMAKE_ROOT !!!" + "Could not find CMAKE_ROOT !!!" << std::endl << "CMake has most likely not been installed correctly." << std::endl @@ -1516,14 +1516,14 @@ cmCPackGenerator::GetInstallationType(const char *projectName, (void) projectName; bool hasInstallationType = this->InstallationTypes.count(name) != 0; cmCPackInstallationType *installType = &this->InstallationTypes[name]; - if (!hasInstallationType) + if (!hasInstallationType) { // Define the installation type - std::string macroPrefix = "CPACK_INSTALL_TYPE_" + std::string macroPrefix = "CPACK_INSTALL_TYPE_" + cmsys::SystemTools::UpperCase(name); installType->Name = name; - const char* displayName + const char* displayName = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str()); if (displayName && *displayName) { @@ -1546,13 +1546,13 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name) { bool hasComponent = this->Components.count(name) != 0; cmCPackComponent *component = &this->Components[name]; - if (!hasComponent) + if (!hasComponent) { // Define the component - std::string macroPrefix = "CPACK_COMPONENT_" + std::string macroPrefix = "CPACK_COMPONENT_" + cmsys::SystemTools::UpperCase(name); component->Name = name; - const char* displayName + const char* displayName = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str()); if (displayName && *displayName) { @@ -1562,7 +1562,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name) { component->DisplayName = component->Name; } - component->IsHidden + component->IsHidden = this->IsSet((macroPrefix + "_HIDDEN").c_str()); component->IsRequired = this->IsSet((macroPrefix + "_REQUIRED").c_str()); @@ -1572,7 +1572,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name) = this->IsSet((macroPrefix + "_DOWNLOADED").c_str()) || cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL")); - const char* archiveFile = this->GetOption((macroPrefix + + const char* archiveFile = this->GetOption((macroPrefix + "_ARCHIVE_FILE").c_str()); if (archiveFile && *archiveFile) { @@ -1580,7 +1580,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name) } const char* groupName = this->GetOption((macroPrefix + "_GROUP").c_str()); - if (groupName && *groupName) + if (groupName && *groupName) { component->Group = GetComponentGroup(projectName, groupName); component->Group->Components.push_back(component); @@ -1598,15 +1598,15 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name) } // Determine the installation types. - const char *installTypes + const char *installTypes = this->GetOption((macroPrefix + "_INSTALL_TYPES").c_str()); - if (installTypes && *installTypes) + if (installTypes && *installTypes) { std::vector<std::string> installTypesVector; cmSystemTools::ExpandListArgument(installTypes, installTypesVector); std::vector<std::string>::iterator installTypesIt; - for (installTypesIt = installTypesVector.begin(); - installTypesIt != installTypesVector.end(); + for (installTypesIt = installTypesVector.begin(); + installTypesIt != installTypesVector.end(); ++installTypesIt) { component->InstallationTypes.push_back( @@ -1616,16 +1616,16 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name) // Determine the component dependencies. const char *depends = this->GetOption((macroPrefix + "_DEPENDS").c_str()); - if (depends && *depends) + if (depends && *depends) { std::vector<std::string> dependsVector; cmSystemTools::ExpandListArgument(depends, dependsVector); std::vector<std::string>::iterator dependIt; - for (dependIt = dependsVector.begin(); - dependIt != dependsVector.end(); + for (dependIt = dependsVector.begin(); + dependIt != dependsVector.end(); ++dependIt) { - cmCPackComponent *child = GetComponent(projectName, + cmCPackComponent *child = GetComponent(projectName, dependIt->c_str()); component->Dependencies.push_back(child); child->ReverseDependencies.push_back(component); @@ -1640,15 +1640,15 @@ cmCPackComponentGroup* cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name) { (void) projectName; - std::string macroPrefix = "CPACK_COMPONENT_GROUP_" + std::string macroPrefix = "CPACK_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(name); bool hasGroup = this->ComponentGroups.count(name) != 0; cmCPackComponentGroup *group = &this->ComponentGroups[name]; - if (!hasGroup) + if (!hasGroup) { // Define the group group->Name = name; - const char* displayName + const char* displayName = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str()); if (displayName && *displayName) { @@ -1669,7 +1669,7 @@ cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name) = this->IsSet((macroPrefix + "_BOLD_TITLE").c_str()); group->IsExpandedByDefault = this->IsSet((macroPrefix + "_EXPANDED").c_str()); - const char* parentGroupName + const char* parentGroupName = this->GetOption((macroPrefix + "_PARENT_GROUP").c_str()); if (parentGroupName && *parentGroupName) { diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 6748512..8fafef9 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -113,7 +113,7 @@ public: //! Display verbose information via logger void DisplayVerboseOutput(const char* msg, float progress); - + bool ReadListFile(const char* moduleName); protected: diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 7b52511..fdbae35 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -102,7 +102,7 @@ int cmCPackNSISGenerator::PackageFiles() } if (!Components.empty()) { - // If this is a component installation, strip off the component + // If this is a component installation, strip off the component // part of the path. std::string::size_type slash = fileN.find('/'); if (slash != std::string::npos) @@ -124,12 +124,12 @@ int cmCPackNSISGenerator::PackageFiles() } cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Dirs: " << dstr.str().c_str() << std::endl); - this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES", + this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES", dstr.str().c_str()); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << nsisInFileName << " to " << nsisFileName << std::endl); - if(this->IsSet("CPACK_NSIS_MUI_ICON") + if(this->IsSet("CPACK_NSIS_MUI_ICON") || this->IsSet("CPACK_NSIS_MUI_UNIICON")) { std::string installerIconCode; @@ -174,7 +174,7 @@ int cmCPackNSISGenerator::PackageFiles() this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", ""); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", ""); this->SetOptionIfNotSet("CPACK_NSIS_PAGE_COMPONENTS", ""); - this->SetOptionIfNotSet("CPACK_NSIS_FULL_INSTALL", + this->SetOptionIfNotSet("CPACK_NSIS_FULL_INSTALL", "File /r \"${INST_DIR}\\*.*\""); this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTIONS", ""); this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST", ""); @@ -194,7 +194,7 @@ int cmCPackNSISGenerator::PackageFiles() // Create installation types. The order is significant, so we first fill // in a vector based on the indices, and print them in that order. - std::vector<cmCPackInstallationType *> + std::vector<cmCPackInstallationType *> installTypes(this->InstallationTypes.size()); std::map<std::string, cmCPackInstallationType>::iterator installTypeIt; for (installTypeIt = this->InstallationTypes.begin(); @@ -221,15 +221,15 @@ int cmCPackNSISGenerator::PackageFiles() { if (groupIt->second.ParentGroup == 0) { - componentCode += + componentCode += this->CreateComponentGroupDescription(&groupIt->second, macrosOut); } // Add the group description, if any. if (!groupIt->second.Description.empty()) { - groupDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${" - + groupIt->first + "} \"" + groupDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${" + + groupIt->first + "} \"" + this->TranslateNewlines(groupIt->second.Description) + "\"\n"; } } @@ -251,7 +251,7 @@ int cmCPackNSISGenerator::PackageFiles() if (!compIt->second.Group) { - componentCode + componentCode += this->CreateComponentDescription(&compIt->second, macrosOut); } @@ -265,8 +265,8 @@ int cmCPackNSISGenerator::PackageFiles() // Add the component description, if any. if (!compIt->second.Description.empty()) { - componentDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${" - + compIt->first + "} \"" + componentDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${" + + compIt->first + "} \"" + this->TranslateNewlines(compIt->second.Description) + "\"\n"; } } @@ -276,17 +276,17 @@ int cmCPackNSISGenerator::PackageFiles() if (componentDescriptions.empty() && groupDescriptions.empty()) { // Turn off the "Description" box - this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", + this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", "!define MUI_COMPONENTSPAGE_NODESC"); } else { - componentDescriptions = + componentDescriptions = "!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN\n" + componentDescriptions + groupDescriptions + "!insertmacro MUI_FUNCTION_DESCRIPTION_END\n"; - this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", + this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", componentDescriptions.c_str()); } @@ -308,12 +308,12 @@ int cmCPackNSISGenerator::PackageFiles() componentCode.c_str()); this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST", sectionList.c_str()); - this->SetOptionIfNotSet("CPACK_NSIS_SECTION_SELECTED_VARS", + this->SetOptionIfNotSet("CPACK_NSIS_SECTION_SELECTED_VARS", selectedVarsList.c_str()); this->SetOption("CPACK_NSIS_DEFINES", defines.c_str()); } - this->ConfigureFile(nsisInInstallOptions.c_str(), + this->ConfigureFile(nsisInInstallOptions.c_str(), nsisInstallOptions.c_str()); this->ConfigureFile(nsisInFileName.c_str(), nsisFileName.c_str()); std::string nsisCmd = "\""; @@ -356,18 +356,30 @@ int cmCPackNSISGenerator::InitializeInternal() << std::endl); std::vector<std::string> path; std::string nsisPath; - bool gotRegValue = true; + bool gotRegValue = false; #ifdef _WIN32 - if ( !cmsys::SystemTools::ReadRegistryValue( + if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath, + cmsys::SystemTools::KeyWOW64_32) ) + { + gotRegValue = true; + } + if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath) ) + { + gotRegValue = true; + } + if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath, cmsys::SystemTools::KeyWOW64_32) ) { - if ( !cmsys::SystemTools::ReadRegistryValue( - "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath) ) - { - gotRegValue = false; - } + gotRegValue = true; + } + if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath) ) + { + gotRegValue = true; } if (gotRegValue) @@ -445,11 +457,11 @@ int cmCPackNSISGenerator::InitializeInternal() { cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_CREATE_DESKTOP_LINKS: " << cpackPackageDeskTopLinks << std::endl); - + cmSystemTools:: ExpandListArgument(cpackPackageDeskTopLinks, cpackPackageDesktopLinksVector); - for(std::vector<std::string>::iterator i = + for(std::vector<std::string>::iterator i = cpackPackageDesktopLinksVector.begin(); i != cpackPackageDesktopLinksVector.end(); ++i) { @@ -499,7 +511,7 @@ int cmCPackNSISGenerator::InitializeInternal() if(cpackPackageDesktopLinksVector.size() && std::find(cpackPackageDesktopLinksVector.begin(), cpackPackageDesktopLinksVector.end(), - execName) + execName) != cpackPackageDesktopLinksVector.end()) { str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n"; @@ -579,7 +591,7 @@ void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str, else { str << " WriteINIStr \"$SMPROGRAMS\\$STARTMENU_FOLDER\\" - << linkName << ".url\" \"InternetShortcut\" \"URL\" \"" + << linkName << ".url\" \"InternetShortcut\" \"URL\" \"" << sourceName << "\"" << std::endl; deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName @@ -651,9 +663,9 @@ bool cmCPackNSISGenerator::SupportsComponentInstallation() const } //---------------------------------------------------------------------- -std::string +std::string cmCPackNSISGenerator:: -CreateComponentDescription(cmCPackComponent *component, +CreateComponentDescription(cmCPackComponent *component, cmOStringStream& macrosOut) { // Basic description of the component @@ -668,7 +680,7 @@ CreateComponentDescription(cmCPackComponent *component, componentCode += "-"; } componentCode += component->DisplayName + "\" " + component->Name + "\n"; - if (component->IsRequired) + if (component->IsRequired) { componentCode += " SectionIn RO\n"; } @@ -701,7 +713,7 @@ CreateComponentDescription(cmCPackComponent *component, } // Create the directory for the upload area - const char* userUploadDirectory = + const char* userUploadDirectory = this->GetOption("CPACK_UPLOAD_DIRECTORY"); std::string uploadDirectory; if (userUploadDirectory && *userUploadDirectory) @@ -727,7 +739,7 @@ CreateComponentDescription(cmCPackComponent *component, // Remove the old archive, if one exists std::string archiveFile = uploadDirectory + '/' + component->ArchiveFile; cmCPackLogger(cmCPackLog::LOG_OUTPUT, - "- Building downloaded component archive: " + "- Building downloaded component archive: " << archiveFile << std::endl); if (cmSystemTools::FileExists(archiveFile.c_str(), true)) { @@ -760,18 +772,18 @@ CreateComponentDescription(cmCPackComponent *component, dirName += component->Name; dirName += '/'; - // Build the list of files to go into this archive, and determine the + // Build the list of files to go into this archive, and determine the // size of the installed component. std::string zipListFileName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); zipListFileName += "/winZip.filelist"; - bool needQuotesInFile + bool needQuotesInFile = cmSystemTools::IsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES")); unsigned long totalSize = 0; { // the scope is needed for cmGeneratedFileStream cmGeneratedFileStream out(zipListFileName.c_str()); std::vector<std::string>::iterator fileIt; - for (fileIt = component->Files.begin(); - fileIt != component->Files.end(); + for (fileIt = component->Files.begin(); + fileIt != component->Files.end(); ++fileIt) { if ( needQuotesInFile ) @@ -792,11 +804,11 @@ CreateComponentDescription(cmCPackComponent *component, // Build the archive in the upload area std::string cmd = this->GetOption("CPACK_ZIP_COMMAND"); cmsys::SystemTools::ReplaceString(cmd, "<ARCHIVE>", archiveFile.c_str()); - cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>", + cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>", zipListFileName.c_str()); std::string output; int retVal = -1; - int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retVal, + int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retVal, dirName.c_str(), cmSystemTools::OUTPUT_NONE, 0); if ( !res || retVal ) @@ -812,7 +824,7 @@ CreateComponentDescription(cmCPackComponent *component, << "Please check " << tmpFile.c_str() << " for errors" << std::endl); return ""; } - + // Create the NSIS code to download this file on-the-fly. unsigned long totalSizeInKbytes = (totalSize + 512) / 1024; if (totalSizeInKbytes == 0) @@ -823,7 +835,7 @@ CreateComponentDescription(cmCPackComponent *component, out << " AddSize " << totalSizeInKbytes << "\n" << " Push \"" << component->ArchiveFile << "\"\n" << " Call DownloadFile\n" - << " ZipDLL::extractall \"$INSTDIR\\" + << " ZipDLL::extractall \"$INSTDIR\\" << component->ArchiveFile << "\" \"$INSTDIR\"\n" << " Pop $2 ; error message\n" " StrCmp $2 \"success\" +2 0\n" @@ -889,7 +901,7 @@ std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription std::set<cmCPackComponent *>& visited) { // Don't visit a component twice - if (visited.count(component)) + if (visited.count(component)) { return std::string(); } @@ -921,7 +933,7 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription std::set<cmCPackComponent *>& visited) { // Don't visit a component twice - if (visited.count(component)) + if (visited.count(component)) { return std::string(); } @@ -939,7 +951,7 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription out << " IntOp $0 $0 & $1\n"; out << " SectionSetFlags ${" << (*dependIt)->Name << "} $0\n"; out << " IntOp $" << (*dependIt)->Name << "_selected 0 + 0\n"; - + // Recurse out << CreateDeselectionDependenciesDescription(*dependIt, visited).c_str(); @@ -949,9 +961,9 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription } //---------------------------------------------------------------------- -std::string +std::string cmCPackNSISGenerator:: -CreateComponentGroupDescription(cmCPackComponentGroup *group, +CreateComponentGroupDescription(cmCPackComponentGroup *group, cmOStringStream& macrosOut) { if (group->Components.empty() && group->Subgroups.empty()) @@ -982,8 +994,8 @@ CreateComponentGroupDescription(cmCPackComponentGroup *group, } std::vector<cmCPackComponent*>::iterator comp; - for (comp = group->Components.begin(); - comp != group->Components.end(); + for (comp = group->Components.begin(); + comp != group->Components.end(); ++comp) { if ((*comp)->Files.empty()) diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 363ccea..76e15fb 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -64,7 +64,7 @@ int cmCPackOSXX11Generator::PackageFiles() { std::string cpackExecutableName = *it; ++ it; - this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME", + this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME", cpackExecutableName.c_str()); } } @@ -113,7 +113,7 @@ int cmCPackOSXX11Generator::PackageFiles() cmSystemTools::CreateSymlink("/Applications", applicationsLinkName.c_str()); if ( - !this->CopyResourcePlistFile("VolumeIcon.icns", + !this->CopyResourcePlistFile("VolumeIcon.icns", diskImageDirectory.c_str(), ".VolumeIcon.icns", true ) || !this->CopyResourcePlistFile("DS_Store", diskImageDirectory.c_str(), @@ -125,9 +125,9 @@ int cmCPackOSXX11Generator::PackageFiles() "Info.plist" ) || !this->CopyResourcePlistFile("OSXX11.main.scpt", scrDir, "main.scpt", true ) || - !this->CopyResourcePlistFile("OSXScriptLauncher.rsrc", dir, + !this->CopyResourcePlistFile("OSXScriptLauncher.rsrc", dir, rsrcFile, true) || - !this->CopyResourcePlistFile("OSXScriptLauncher", appdir, + !this->CopyResourcePlistFile("OSXScriptLauncher", appdir, this->GetOption("CPACK_PACKAGE_FILE_NAME"), true) ) { @@ -167,11 +167,11 @@ int cmCPackOSXX11Generator::PackageFiles() tmpFile += "/hdiutilOutput.log"; cmOStringStream dmgCmd; dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE") - << "\" create -ov -format UDZO -srcfolder \"" - << diskImageDirectory.c_str() + << "\" create -ov -format UDZO -srcfolder \"" + << diskImageDirectory.c_str() << "\" \"" << packageFileNames[0] << "\""; cmCPackLogger(cmCPackLog::LOG_VERBOSE, - "Compress disk image using command: " + "Compress disk image using command: " << dmgCmd.str().c_str() << std::endl); // since we get random dashboard failures with this one // try running it more than once @@ -181,7 +181,7 @@ int cmCPackOSXX11Generator::PackageFiles() while(numTries > 0) { res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output, - &retVal, 0, + &retVal, 0, this->GeneratorVerbose, 0); if ( res && !retVal ) { @@ -219,7 +219,7 @@ int cmCPackOSXX11Generator::InitializeInternal() << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", + this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", pkgPath.c_str()); return this->Superclass::InitializeInternal(); @@ -235,7 +235,7 @@ bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name) if ( !inFileName ) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str() - << " not specified. It should point to " + << " not specified. It should point to " << (name ? name : "(NULL)") << ".rtf, " << name << ".html, or " << name << ".txt file" << std::endl); @@ -243,7 +243,7 @@ bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name) } if ( !cmSystemTools::FileExists(inFileName) ) { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find " + cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find " << (name ? name : "(NULL)") << " resource file: " << inFileName << std::endl); return false; @@ -262,7 +262,7 @@ bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name) destFileName += name + ext; - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << (inFileName ? inFileName : "(NULL)") << " to " << destFileName.c_str() << std::endl); this->ConfigureFile(inFileName, destFileName.c_str()); diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index 3a0e89b..c617a3e 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -52,7 +52,7 @@ int cmCPackPackageMakerGenerator::CopyInstallScript(const char* resdir, cmSystemTools::CopyFileAlways(script, dst.c_str()); cmSystemTools::SetPermissions(dst.c_str(),0777); cmCPackLogger(cmCPackLog::LOG_VERBOSE, - "copy script : " << script << "\ninto " << dst.c_str() << + "copy script : " << script << "\ninto " << dst.c_str() << std::endl); return 1; @@ -79,7 +79,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() if ( !cmsys::SystemTools::MakeDirectory(packageDirFileName.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "unable to create package directory " + "unable to create package directory " << packageDirFileName << std::endl); return 0; } @@ -89,7 +89,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() if ( !cmsys::SystemTools::MakeDirectory(resDir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "unable to create package subdirectory " << resDir + "unable to create package subdirectory " << resDir << std::endl); return 0; } @@ -98,7 +98,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() if ( !cmsys::SystemTools::MakeDirectory(resDir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "unable to create package subdirectory " << resDir + "unable to create package subdirectory " << resDir << std::endl); return 0; } @@ -106,56 +106,101 @@ int cmCPackPackageMakerGenerator::PackageFiles() resDir += "/en.lproj"; } - - // Create directory structure - std::string preflightDirName = resDir + "/PreFlight"; - std::string postflightDirName = resDir + "/PostFlight"; const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT"); const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT"); const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT"); - // if preflight or postflight scripts not there create directories - // of the same name, I think this makes it work - if(!preflight) + + if(this->Components.empty()) { - if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str())) + // Create directory structure + std::string preflightDirName = resDir + "/PreFlight"; + std::string postflightDirName = resDir + "/PostFlight"; + // if preflight or postflight scripts not there create directories + // of the same name, I think this makes it work + if(!preflight) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem creating installer directory: " - << preflightDirName.c_str() << std::endl); - return 0; + if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str())) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem creating installer directory: " + << preflightDirName.c_str() << std::endl); + return 0; + } + } + if(!postflight) + { + if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str())) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem creating installer directory: " + << postflightDirName.c_str() << std::endl); + return 0; + } + } + // if preflight, postflight, or postupgrade are set + // then copy them into the resource directory and make + // them executable + if(preflight) + { + this->CopyInstallScript(resDir.c_str(), + preflight, + "preflight"); + } + if(postflight) + { + this->CopyInstallScript(resDir.c_str(), + postflight, + "postflight"); + } + if(postupgrade) + { + this->CopyInstallScript(resDir.c_str(), + postupgrade, + "postupgrade"); } } - if(!postflight) + else if(postflight) { - if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str())) + // create a postflight component to house the script + this->PostFlightComponent.Name = "PostFlight"; + this->PostFlightComponent.DisplayName = "PostFlight"; + this->PostFlightComponent.Description = "PostFlight"; + this->PostFlightComponent.IsHidden = true; + + // empty directory for pkg contents + std::string packageDir = toplevel + "/" + PostFlightComponent.Name; + if (!cmsys::SystemTools::MakeDirectory(packageDir.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem creating installer directory: " - << postflightDirName.c_str() << std::endl); + "Problem creating component packages directory: " + << packageDir.c_str() << std::endl); return 0; } - } - // if preflight, postflight, or postupgrade are set - // then copy them into the resource directory and make - // them executable - if(preflight) - { - this->CopyInstallScript(resDir.c_str(), - preflight, - "preflight"); - } - if(postflight) - { - this->CopyInstallScript(resDir.c_str(), + + // create package + std::string packageFileDir = packageDirFileName + "/Contents/Packages/"; + if (!cmsys::SystemTools::MakeDirectory(packageFileDir.c_str())) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem creating component PostFlight Packages directory: " + << packageFileDir.c_str() << std::endl); + return 0; + } + std::string packageFile = packageFileDir + + this->GetPackageName(PostFlightComponent); + if (!this->GenerateComponentPackage(packageFile.c_str(), + packageDir.c_str(), + PostFlightComponent)) + { + return 0; + } + + // copy postflight script into resource directory of .pkg + std::string resourceDir = packageFile + "/Contents/Resources"; + this->CopyInstallScript(resourceDir.c_str(), postflight, "postflight"); } - if(postupgrade) - { - this->CopyInstallScript(resDir.c_str(), - postupgrade, - "postupgrade"); - } if (!this->Components.empty()) { @@ -206,7 +251,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "Unable to create package upload directory " + "Unable to create package upload directory " << uploadDirectory << std::endl); return 0; } @@ -254,7 +299,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() std::string packageDir = toplevel; packageDir += '/'; packageDir += compIt->first; - if (!this->GenerateComponentPackage(packageFile.c_str(), + if (!this->GenerateComponentPackage(packageFile.c_str(), packageDir.c_str(), compIt->second)) { @@ -293,7 +338,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() } pkgCmd << "\" -r \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/Resources\" -i \"" - << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") + << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/Info.plist\" -d \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/Description.plist\""; @@ -324,7 +369,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() while(numTries > 0) { res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output, - &retVal, 0, this->GeneratorVerbose, + &retVal, 0, this->GeneratorVerbose, 0); if ( res && !retVal ) { @@ -474,7 +519,7 @@ int cmCPackPackageMakerGenerator::InitializeInternal() const char *packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION"); if (packageCompat && *packageCompat) { - this->PackageCompatibilityVersion = atof(packageCompat); + this->PackageCompatibilityVersion = atof(packageCompat); } else if (this->GetOption("CPACK_DOWNLOAD_SITE")) { @@ -500,7 +545,7 @@ int cmCPackPackageMakerGenerator::InitializeInternal() << std::endl); return 0; } - this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", + this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", pkgPath.c_str()); return this->Superclass::InitializeInternal(); @@ -516,7 +561,7 @@ bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name, if ( !inFileName ) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str() - << " not specified. It should point to " + << " not specified. It should point to " << (name ? name : "(NULL)") << ".rtf, " << name << ".html, or " << name << ".txt file" << std::endl); @@ -524,7 +569,7 @@ bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name, } if ( !cmSystemTools::FileExists(inFileName) ) { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find " + cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find " << (name ? name : "(NULL)") << " resource file: " << inFileName << std::endl); return false; @@ -547,7 +592,7 @@ bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name, this->SetOption(("CPACK_RESOURCE_FILE_" + uname + "_NOPATH").c_str(), (name + ext).c_str()); - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << (inFileName ? inFileName : "(NULL)") << " to " << destFileName.c_str() << std::endl); this->ConfigureFile(inFileName, destFileName.c_str()); @@ -593,7 +638,7 @@ bool cmCPackPackageMakerGenerator::RunPackageMaker(const char *command, cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl); std::string output; int retVal = 1; - bool res = cmSystemTools::RunSingleCommand(command, &output, &retVal, 0, + bool res = cmSystemTools::RunSingleCommand(command, &output, &retVal, 0, this->GeneratorVerbose, 0); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running package maker" << std::endl); @@ -612,7 +657,7 @@ bool cmCPackPackageMakerGenerator::RunPackageMaker(const char *command, // sometimes the command finishes but the directory is not yet // created, so try 10 times to see if it shows up int tries = 10; - while(tries > 0 && + while(tries > 0 && !cmSystemTools::FileExists(packageFile)) { cmSystemTools::Delay(500); @@ -632,7 +677,7 @@ bool cmCPackPackageMakerGenerator::RunPackageMaker(const char *command, } //---------------------------------------------------------------------- -std::string +std::string cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component) { if (component.ArchiveFile.empty()) @@ -664,7 +709,7 @@ GenerateComponentPackage(const char *packageFile, // The command that will be used to run PackageMaker cmOStringStream pkgCmd; - if (this->PackageCompatibilityVersion < 10.5 || + if (this->PackageCompatibilityVersion < 10.5 || this->PackageMakerVersion < 3.0) { // Create Description.plist and Info.plist files for normal Mac OS @@ -680,10 +725,10 @@ GenerateComponentPackage(const char *packageFile, << " <key>IFPkgDescriptionTitle</key>" << std::endl << " <string>" << component.DisplayName << "</string>" << std::endl << " <key>IFPkgDescriptionVersion</key>" << std::endl - << " <string>" << this->GetOption("CPACK_PACKAGE_VERSION") + << " <string>" << this->GetOption("CPACK_PACKAGE_VERSION") << "</string>" << std::endl << " <key>IFPkgDescriptionDescription</key>" << std::endl - << " <string>" + this->EscapeForXML(component.Description) + << " <string>" + this->EscapeForXML(component.Description) << "</string>" << std::endl << "</dict>" << std::endl << "</plist>" << std::endl; @@ -692,7 +737,7 @@ GenerateComponentPackage(const char *packageFile, // Create the Info.plist file for this component std::string moduleVersionSuffix = "."; moduleVersionSuffix += component.Name; - this->SetOption("CPACK_MODULE_VERSION_SUFFIX", + this->SetOption("CPACK_MODULE_VERSION_SUFFIX", moduleVersionSuffix.c_str()); std::string infoFileName = component.Name; infoFileName += "-Info.plist"; @@ -704,9 +749,9 @@ GenerateComponentPackage(const char *packageFile, pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM") << "\" -build -p \"" << packageFile << "\"" << " -f \"" << packageDir << "\"" - << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") + << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/" << infoFileName << "\"" - << " -d \"" << descriptionFile << "\""; + << " -d \"" << descriptionFile << "\""; } else { @@ -729,16 +774,16 @@ GenerateComponentPackage(const char *packageFile, << " --out \"" << packageFile << "\""; } - // Run PackageMaker + // Run PackageMaker return RunPackageMaker(pkgCmd.str().c_str(), packageFile); } //---------------------------------------------------------------------- -void +void cmCPackPackageMakerGenerator:: WriteDistributionFile(const char* metapackageFile) { - std::string distributionTemplate + std::string distributionTemplate = this->FindTemplate("CPack.distribution.dist.in"); if ( distributionTemplate.empty() ) { @@ -757,8 +802,8 @@ WriteDistributionFile(const char* metapackageFile) // Emit the outline for the groups std::map<std::string, cmCPackComponentGroup>::iterator groupIt; - for (groupIt = this->ComponentGroups.begin(); - groupIt != this->ComponentGroups.end(); + for (groupIt = this->ComponentGroups.begin(); + groupIt != this->ComponentGroups.end(); ++groupIt) { if (groupIt->second.ParentGroup == 0) @@ -778,11 +823,16 @@ WriteDistributionFile(const char* metapackageFile) << std::endl; } } + if(!this->PostFlightComponent.Name.empty()) + { + choiceOut << "<line choice=\"" << PostFlightComponent.Name + << "Choice\"></line>" << std::endl; + } choiceOut << "</choices-outline>" << std::endl; // Create the actual choices - for (groupIt = this->ComponentGroups.begin(); - groupIt != this->ComponentGroups.end(); + for (groupIt = this->ComponentGroups.begin(); + groupIt != this->ComponentGroups.end(); ++groupIt) { CreateChoice(groupIt->second, choiceOut); @@ -792,11 +842,17 @@ WriteDistributionFile(const char* metapackageFile) { CreateChoice(compIt->second, choiceOut); } + + if(!this->PostFlightComponent.Name.empty()) + { + CreateChoice(PostFlightComponent, choiceOut); + } + this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str()); // Create the distribution.dist file in the metapackage to turn it // into a distribution package. - this->ConfigureFile(distributionTemplate.c_str(), + this->ConfigureFile(distributionTemplate.c_str(), distributionFile.c_str()); } @@ -824,13 +880,13 @@ CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out) } //---------------------------------------------------------------------- -void +void cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group, cmOStringStream& out) { - out << "<choice id=\"" << group.Name << "Choice\" " + out << "<choice id=\"" << group.Name << "Choice\" " << "title=\"" << group.DisplayName << "\" " - << "start_selected=\"true\" " + << "start_selected=\"true\" " << "start_enabled=\"true\" " << "start_visible=\"true\" "; if (!group.Description.empty()) @@ -842,21 +898,21 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group, } //---------------------------------------------------------------------- -void +void cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, cmOStringStream& out) { std::string packageId = "com."; packageId += this->GetOption("CPACK_PACKAGE_VENDOR"); - packageId += '.'; + packageId += '.'; packageId += this->GetOption("CPACK_PACKAGE_NAME"); packageId += '.'; packageId += component.Name; - out << "<choice id=\"" << component.Name << "Choice\" " + out << "<choice id=\"" << component.Name << "Choice\" " << "title=\"" << component.DisplayName << "\" " - << "start_selected=\"" - << (component.IsDisabledByDefault && + << "start_selected=\"" + << (component.IsDisabledByDefault && !component.IsRequired? "false" : "true") << "\" " << "start_enabled=\"" @@ -905,7 +961,7 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); dirName += '/'; dirName += component.Name; - unsigned long installedSize + unsigned long installedSize = component.GetInstalledSizeInKbytes(dirName.c_str()); out << "<pkg-ref id=\"" << packageId << "\" " @@ -914,7 +970,7 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, << "auth=\"Admin\" onConclusion=\"None\">"; if (component.IsDownloaded) { - out << this->GetOption("CPACK_DOWNLOAD_SITE") + out << this->GetOption("CPACK_DOWNLOAD_SITE") << this->GetPackageName(component); } else @@ -925,9 +981,9 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, } //---------------------------------------------------------------------- -void +void cmCPackPackageMakerGenerator:: -AddDependencyAttributes(const cmCPackComponent& component, +AddDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, cmOStringStream& out) { @@ -942,16 +998,16 @@ AddDependencyAttributes(const cmCPackComponent& component, dependIt != component.Dependencies.end(); ++dependIt) { - out << " && choices['" << + out << " && choices['" << (*dependIt)->Name << "Choice'].selected"; AddDependencyAttributes(**dependIt, visited, out); } } //---------------------------------------------------------------------- -void +void cmCPackPackageMakerGenerator:: -AddReverseDependencyAttributes(const cmCPackComponent& component, +AddReverseDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, cmOStringStream& out) { diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h index 2bab947..ba3d968 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.h +++ b/Source/CPack/cmCPackPackageMakerGenerator.h @@ -67,8 +67,8 @@ protected: // Generate a package in the file packageFile for the given // component. All of the files within this component are stored in // the directory packageDir. Returns true if successful, false - // otherwise. - bool GenerateComponentPackage(const char *packageFile, + // otherwise. + bool GenerateComponentPackage(const char *packageFile, const char *packageDir, const cmCPackComponent& component); @@ -87,14 +87,14 @@ protected: // Subroutine of WriteDistributionFile that writes out the // reverse dependency attributes for inter-component dependencies. - void + void AddReverseDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, cmOStringStream& out); // Generates XML that encodes the hierarchy of component groups and // their components in a form that can be used by distribution - // metapackages. + // metapackages. void CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out); @@ -111,7 +111,10 @@ protected: // Escape the given string to make it usable as an XML attribute // value. std::string EscapeForXML(std::string str); - + + // The PostFlight component when creating a metapackage + cmCPackComponent PostFlightComponent; + double PackageMakerVersion; double PackageCompatibilityVersion; }; diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 413572e..66a4194 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -77,6 +77,11 @@ int cmCPackRPMGenerator::PackageOnePack(std::string initialToplevel, packageFileName.c_str()); // Tell CPackRPM.cmake the name of the component NAME. this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",packageName.c_str()); + // Tell CPackRPM.cmake the path where the component is. + std::string component_path = "/"; + component_path += packageName; + this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", + component_path.c_str()); if (!this->ReadListFile("CPackRPM.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -178,8 +183,11 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne() /* replace the TEMPORARY package file name */ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", packageFileName.c_str()); - // Tell CPackRPM.cmake the name of the component GROUP. - this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compInstDirName.c_str()); + // Tell CPackRPM.cmake the path where the component is. + std::string component_path = "/"; + component_path += compInstDirName; + this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH", + component_path.c_str()); if (!this->ReadListFile("CPackRPM.cmake")) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -230,7 +238,7 @@ int cmCPackRPMGenerator::PackageFiles() } } - if (!this->IsSet("RPMBUILD_EXECUTABLE")) + if (!this->IsSet("RPMBUILD_EXECUTABLE")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find rpmbuild" << std::endl); retval = 0; diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h index eec8204..a7722bc 100644 --- a/Source/CPack/cmCPackRPMGenerator.h +++ b/Source/CPack/cmCPackRPMGenerator.h @@ -39,6 +39,9 @@ public: { #ifdef __APPLE__ // on MacOS enable CPackRPM iff rpmbuild is found + std::vector<std::string> locations; + locations.push_back("/sw/bin"); // Fink + locations.push_back("/opt/local/bin"); // MacPorts return cmSystemTools::FindProgram("rpmbuild") != "" ? true : false; #else // legacy behavior on other systems diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index 966a231..9b6cf14 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -97,7 +97,7 @@ int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os) { licenseText += line + "\n"; } - this->SetOptionIfNotSet("CPACK_RESOURCE_FILE_LICENSE_CONTENT", + this->SetOptionIfNotSet("CPACK_RESOURCE_FILE_LICENSE_CONTENT", licenseText.c_str()); const char headerLengthTag[] = "###CPACK_HEADER_LENGTH###"; @@ -126,7 +126,7 @@ int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os) ++ptr; } counter ++; - cmCPackLogger(cmCPackLog::LOG_DEBUG, + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Number of lines: " << counter << std::endl); char buffer[1024]; sprintf(buffer, "%d", counter); diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx index 971d166..ae73c37 100644 --- a/Source/CPack/cmCPackTarBZip2Generator.cxx +++ b/Source/CPack/cmCPackTarBZip2Generator.cxx @@ -12,7 +12,7 @@ #include "cmCPackTarBZip2Generator.h" //---------------------------------------------------------------------- -cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() +cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, cmArchiveWrite::TypeTAR) { diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx index 7a8f697..df29408 100644 --- a/Source/CPack/cmCPackTarCompressGenerator.cxx +++ b/Source/CPack/cmCPackTarCompressGenerator.cxx @@ -13,7 +13,7 @@ #include "cmCPackTarCompressGenerator.h" //---------------------------------------------------------------------- -cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() +cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, cmArchiveWrite::TypeTAR) { diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 6f5055c..b603585 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -207,8 +207,7 @@ int main (int argc, char *argv[]) std::string helpHTML; std::string cpackProjectName; - std::string cpackProjectDirectory - = cmsys::SystemTools::GetCurrentWorkingDirectory(); + std::string cpackProjectDirectory; std::string cpackBuildConfig; std::string cpackProjectVersion; std::string cpackProjectPatch; @@ -294,8 +293,12 @@ int main (int argc, char *argv[]) cmDocumentation doc; doc.addCPackStandardDocSections(); - /* Were we invoked to display doc or to do some work ? */ - if(doc.CheckOptions(argc, argv,"-G") || nocwd) + /* Were we invoked to display doc or to do some work ? + * Unlike cmake launching cpack with zero argument + * should launch cpack using "cpackConfigFile" if it exists + * in the current directory. + */ + if((doc.CheckOptions(argc, argv,"-G") || nocwd) && !(argc==1)) { help = true; } @@ -370,10 +373,24 @@ int main (int argc, char *argv[]) globalMF->AddDefinition("CPACK_PACKAGE_VENDOR", cpackProjectVendor.c_str()); } + // if this is not empty it has been set on the command line + // go for it. Command line override values set in config file. if ( !cpackProjectDirectory.empty() ) { globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", - cpackProjectDirectory.c_str()); + cpackProjectDirectory.c_str()); + } + // The value has not been set on the command line + else + { + // get a default value (current working directory) + cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory(); + // use default value iff no value has been provided by the config file + if (!globalMF->IsSet("CPACK_PACKAGE_DIRECTORY")) + { + globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", + cpackProjectDirectory.c_str()); + } } if ( !cpackBuildConfig.empty() ) { diff --git a/Source/CPack/cygwin.readme b/Source/CPack/cygwin.readme index 88922d3..c0cd4b9 100644 --- a/Source/CPack/cygwin.readme +++ b/Source/CPack/cygwin.readme @@ -16,11 +16,11 @@ Source- - write diff into toplevel - create tar file call super class -cmake-2.2.3-1 +cmake-2.2.3-1 + - 1. a source release -cmake-2.2.3-2-src.tar.bz2 +cmake-2.2.3-2-src.tar.bz2 cmake-2.2.3-2.patch has cmake-2.2.3/CYGWIN-PATCHES/cmake.README cmake-2.2.3/CYGWIN-PATCHES/setup.hint cmake-2.2.3-2.sh -> script to create cygwin release diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index 36302df..381c70c 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -128,13 +128,12 @@ class cmCTestBZR::RevnoParser: public cmCTestVC::LineParser { public: RevnoParser(cmCTestBZR* bzr, const char* prefix, std::string& rev): - BZR(bzr), Rev(rev) + Rev(rev) { this->SetLog(&bzr->Log, prefix); this->RegexRevno.compile("^([0-9]+)$"); } private: - cmCTestBZR* BZR; std::string& Rev; cmsys::RegularExpression RegexRevno; virtual bool ProcessLine() diff --git a/Source/CTest/cmCTestBatchTestHandler.cxx b/Source/CTest/cmCTestBatchTestHandler.cxx index 00bb6fa..a22c7be 100644 --- a/Source/CTest/cmCTestBatchTestHandler.cxx +++ b/Source/CTest/cmCTestBatchTestHandler.cxx @@ -56,7 +56,7 @@ void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout) fout << "srun "; //fout << "--jobid=" << test << " "; fout << "-J=" << properties->Name << " "; - + //Write dependency information /*if(this->Tests[test].size() > 0) { diff --git a/Source/CTest/cmCTestBatchTestHandler.h b/Source/CTest/cmCTestBatchTestHandler.h index fdfd1be..ab0d081 100644 --- a/Source/CTest/cmCTestBatchTestHandler.h +++ b/Source/CTest/cmCTestBatchTestHandler.h @@ -21,7 +21,7 @@ /** \class cmCTestBatchTestHandler * \brief run parallel ctest * - * cmCTestBatchTestHandler + * cmCTestBatchTestHandler */ class cmCTestBatchTestHandler : public cmCTestMultiProcessHandler { diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 8a2d65a..554efb5 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -67,7 +67,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, generator += this->BuildGenerator; args.push_back(generator); } - + const char* config = 0; if ( this->CTest->GetConfigType().size() > 0 ) { @@ -79,7 +79,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, config = CMAKE_INTDIR; } #endif - + if ( config ) { std::string btype @@ -198,8 +198,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) std::string resultingConfig; std::vector<std::string> extraPaths; std::vector<std::string> failed; - fullPath = - cmCTestTestHandler::FindExecutable(this->CTest, + fullPath = + cmCTestTestHandler::FindExecutable(this->CTest, this->ConfigSample.c_str(), resultingConfig, extraPaths, @@ -211,7 +211,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) out << "Using config sample with results: " << fullPath << " and " << resultingConfig << std::endl; } - + // we need to honor the timeout specified, the timeout include cmake, build // and test time double clock_start = cmSystemTools::GetTime(); @@ -228,7 +228,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) // should we cmake? cmake cm; - cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString); + cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString); cm.SetGlobalGenerator(cm.CreateGlobalGenerator( this->BuildGenerator.c_str())); @@ -247,7 +247,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) { this->BuildTargets.push_back(""); } - for ( tarIt = this->BuildTargets.begin(); + for ( tarIt = this->BuildTargets.begin(); tarIt != this->BuildTargets.end(); ++ tarIt ) { double remainingTime = 0; @@ -284,7 +284,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) this->BuildProject.c_str(), tarIt->c_str(), &output, this->BuildMakeProgram.c_str(), config, - !this->BuildNoClean, + !this->BuildNoClean, false, remainingTime); out << output; // if the build failed then return @@ -322,13 +322,13 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) extraPaths.push_back(tempPath); } std::vector<std::string> failed; - fullPath = - cmCTestTestHandler::FindExecutable(this->CTest, + fullPath = + cmCTestTestHandler::FindExecutable(this->CTest, this->TestCommand.c_str(), resultingConfig, extraPaths, failed); - + if(!cmSystemTools::FileExists(fullPath.c_str())) { out << "Could not find path to executable, perhaps it was not built: " @@ -388,8 +388,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) return 1; } } - - int runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, 0, + + int runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, 0, remainingTime, 0); if(runTestRes != cmsysProcess_State_Exited || retval != 0) diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h index 6e5f7a6..9029600 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.h +++ b/Source/CTest/cmCTestBuildAndTestHandler.h @@ -42,7 +42,7 @@ public: * Get the output variable */ const char* GetOutput(); - + cmCTestBuildAndTestHandler(); virtual void Initialize(); @@ -50,10 +50,10 @@ public: protected: ///! Run CMake and build a test and then run it as a single test. int RunCMakeAndTest(std::string* output); - int RunCMake(std::string* outstring, cmOStringStream &out, + int RunCMake(std::string* outstring, cmOStringStream &out, std::string &cmakeOutString, std::string &cwd, cmake *cm); - + cmStdString Output; std::string BuildGenerator; diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index b984e85..f4d38ce 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -175,7 +175,7 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, { bool ret = cmCTestHandlerCommand::InitialPass(args, status); if ( this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) - { + { cmOStringStream str; str << this->Handler->GetTotalErrors(); this->Makefile->AddDefinition( diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 27bb06c..39eeb70 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -168,7 +168,7 @@ static cmCTestBuildCompileErrorWarningRex cmCTestWarningErrorFileLine[] = { { "^Warning W[0-9]+ ([a-zA-Z.\\:/0-9_+ ~-]+) ([0-9]+):", 1, 2 }, { "^([a-zA-Z./0-9_+ ~-]+):([0-9]+):", 1, 2 }, - { "^([a-zA-Z.\\:/0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 }, + { "^([a-zA-Z.\\:/0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 }, { "^[0-9]+>([a-zA-Z.\\:/0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 }, { "^([a-zA-Z./0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 }, { "\"([a-zA-Z./0-9_+ ~-]+)\", line ([0-9]+)", 1, 2 }, @@ -289,7 +289,7 @@ std::string cmCTestBuildHandler::GetMakeCommand() std::string makeCommand = this->CTest->GetCTestConfiguration("MakeCommand"); cmCTestLog(this->CTest, - HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand << + HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand << "\n"); std::string configType = this->CTest->GetConfigType(); @@ -392,7 +392,7 @@ int cmCTestBuildHandler::ProcessHandler() { this->CustomWarningMatches.push_back(cmCTestWarningMatches[cc]); } - + for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ ) { this->CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]); @@ -557,7 +557,7 @@ void cmCTestBuildHandler::GenerateXMLHeader(std::ostream& os) this->CTest->StartXML(os, this->AppendXML); os << "<Build>\n" << "\t<StartDateTime>" << this->StartBuild << "</StartDateTime>\n" - << "\t<StartBuildTime>" << + << "\t<StartBuildTime>" << static_cast<unsigned int>(this->StartBuildTime) << "</StartBuildTime>\n" << "<BuildCommand>" @@ -998,7 +998,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, // dashboard. cmCTestBuildErrorWarning errorwarning; errorwarning.LogLine = 1; - errorwarning.Text + errorwarning.Text = "*** WARNING non-zero return value in ctest from: "; errorwarning.Text += argv[0]; errorwarning.PreContext = ""; @@ -1150,7 +1150,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, { // This is not an error or warning. // So, figure out if this is a post-context line - if ( this->ErrorsAndWarnings.size() && + if ( this->ErrorsAndWarnings.size() && this->LastErrorOrWarning != this->ErrorsAndWarnings.end() && this->PostContextCount < this->MaxPostContext ) { diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx index 3329756..7c41298 100644 --- a/Source/CTest/cmCTestConfigureHandler.cxx +++ b/Source/CTest/cmCTestConfigureHandler.cxx @@ -106,7 +106,7 @@ int cmCTestConfigureHandler::ProcessHandler() std::string end_time = this->CTest->CurrentTime(); os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n" << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" - << "\t<EndConfigureTime>" << + << "\t<EndConfigureTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) << "</EndConfigureTime>\n" << "<ElapsedMinutes>" diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 81d3669..4d1e249 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -80,15 +80,15 @@ public: { args.push_back(i->c_str()); } - args.push_back(0); // null terminate + args.push_back(0); // null terminate cmsysProcess_SetCommand(this->Process, &*args.begin()); if(this->WorkingDirectory.size()) { cmsysProcess_SetWorkingDirectory(this->Process, this->WorkingDirectory.c_str()); } - - cmsysProcess_SetOption(this->Process, + + cmsysProcess_SetOption(this->Process, cmsysProcess_Option_HideWindow, 1); if(this->TimeOut != -1) { @@ -112,7 +112,7 @@ public: { cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDERR, fname); } - int WaitForExit(double* timeout =0) + int WaitForExit(double* timeout =0) { this->PipeState = cmsysProcess_WaitForExit(this->Process, timeout); @@ -183,7 +183,7 @@ bool cmCTestCoverageHandler::StartCoverageLogFile( this->CTest->StartXML(covLogFile, this->AppendXML); covLogFile << "<CoverageLog>" << std::endl << "\t<StartDateTime>" << local_start_time << "</StartDateTime>" - << "\t<StartTime>" + << "\t<StartTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) << "</StartTime>" << std::endl; @@ -196,7 +196,7 @@ void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr, { std::string local_end_time = this->CTest->CurrentTime(); ostr << "\t<EndDateTime>" << local_end_time << "</EndDateTime>" << std::endl - << "\t<EndTime>" << + << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) << "</EndTime>" << std::endl << "</CoverageLog>" << std::endl; @@ -325,7 +325,7 @@ int cmCTestCoverageHandler::ProcessHandler() { return error; } - + std::string coverage_start_time = this->CTest->CurrentTime(); unsigned int coverage_start_time_time = static_cast<unsigned int>( cmSystemTools::GetTime()); @@ -659,7 +659,7 @@ int cmCTestCoverageHandler::ProcessHandler() covSumFile.precision(2); covSumFile << (percent_coverage)<< "</PercentCoverage>\n" << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" - << "\t<EndTime>" << + << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) << "</EndTime>\n"; covSumFile << "<ElapsedMinutes>" << @@ -871,7 +871,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any GCov coverage files." << std::endl); - // No coverage files is a valid thing, so the exit code is 0 + // No coverage files is a valid thing, so the exit code is 0 return 0; } @@ -1294,7 +1294,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage( cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any Python Trace.py coverage files." << std::endl); - // No coverage files is a valid thing, so the exit code is 0 + // No coverage files is a valid thing, so the exit code is 0 return 0; } @@ -1436,7 +1436,7 @@ std::string cmCTestCoverageHandler::FindFile( // This is a header put on each marked up source file namespace { - const char* bullseyeHelp[] = + const char* bullseyeHelp[] = {" Coverage produced by bullseye covbr tool: ", " www.bullseye.com/help/ref_covbr.html", " * An arrow --> indicates incomplete coverage.", @@ -1451,7 +1451,7 @@ namespace " * The slash / means this probe is excluded from summary results. ", 0}; } - + //---------------------------------------------------------------------- int cmCTestCoverageHandler::RunBullseyeCoverageBranch( cmCTestCoverageHandlerContainer* cont, @@ -1461,7 +1461,7 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( { if(files.size() != filesFullPath.size()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, + cmCTestLog(this->CTest, ERROR_MESSAGE, "Files and full path files not the same size?:\n"); return 0; } @@ -1498,13 +1498,13 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( } std::map<cmStdString, cmStdString> fileMap; std::vector<std::string>::iterator fp = filesFullPath.begin(); - for(std::vector<std::string>::iterator f = files.begin(); + for(std::vector<std::string>::iterator f = files.begin(); f != files.end(); ++f, ++fp) { fileMap[*f] = *fp; } - int count =0; // keep count of the number of files + int count =0; // keep count of the number of files // Now parse each line from the bullseye cov log file std::string lineIn; bool valid = false; // are we in a valid output file @@ -1542,9 +1542,9 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( { return -1; } - count++; // move on one + count++; // move on one } - std::map<cmStdString, cmStdString>::iterator + std::map<cmStdString, cmStdString>::iterator i = fileMap.find(file); // if the file should be covered write out the header for that file if(i != fileMap.end()) @@ -1659,10 +1659,10 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( cmCTestLog(this->CTest, ERROR_MESSAGE, "error running covsrc:\n"); return 0; } - + std::ostream& tmpLog = *cont->OFS; // copen the Coverage.xml file in the Testing directory - cmGeneratedFileStream covSumFile; + cmGeneratedFileStream covSumFile; if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile)) { cmCTestLog(this->CTest, ERROR_MESSAGE, @@ -1673,10 +1673,10 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( double elapsed_time_start = cmSystemTools::GetTime(); std::string coverage_start_time = this->CTest->CurrentTime(); covSumFile << "<Coverage>" << std::endl - << "\t<StartDateTime>" + << "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>" << std::endl - << "\t<StartTime>" + << "\t<StartTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) << "</StartTime>" << std::endl; @@ -1717,7 +1717,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( { // parse the comma separated output this->ParseBullsEyeCovsrcLine(stdline, - sourceFile, + sourceFile, functionsCalled, totalFunctions, percentFunction, @@ -1741,7 +1741,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( file = cmSystemTools::CollapseFullPath(file.c_str()); bool shouldIDoCoverage = this->ShouldIDoCoverage(file.c_str(), - cont->SourceDir.c_str(), + cont->SourceDir.c_str(), cont->BinaryDir.c_str()); if ( !shouldIDoCoverage ) { @@ -1797,20 +1797,20 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( << "\t\t<BranchesTested>" << branchCovered << "</BranchesTested>\n" - << "\t\t<BranchesUnTested>" + << "\t\t<BranchesUnTested>" << totalBranches - branchCovered << "</BranchesUnTested>\n" << "\t\t<FunctionsTested>" << functionsCalled << "</FunctionsTested>\n" - << "\t\t<FunctionsUnTested>" + << "\t\t<FunctionsUnTested>" << totalFunctions - functionsCalled << "</FunctionsUnTested>\n" // Hack for conversion of function to loc assume a function // has 100 lines of code << "\t\t<LOCTested>" << functionsCalled *100 << "</LOCTested>\n" - << "\t\t<LOCUnTested>" + << "\t\t<LOCUnTested>" << (totalFunctions - functionsCalled)*100 << "</LOCUnTested>\n" << "\t\t<PercentCoverage>"; @@ -1832,12 +1832,12 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( << "\t<PercentCoverage>"; covSumFile.setf(std::ios::fixed, std::ios::floatfield); covSumFile.precision(2); - covSumFile + covSumFile << SAFEDIV(percent_coverage,number_files)<< "</PercentCoverage>\n" << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) << "</EndTime>\n"; - covSumFile + covSumFile << "<ElapsedMinutes>" << static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0 << "</ElapsedMinutes>" @@ -1858,22 +1858,22 @@ int cmCTestCoverageHandler::HandleBullseyeCoverage( const char* covfile = cmSystemTools::GetEnv("COVFILE"); if(!covfile || strlen(covfile) == 0) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " COVFILE environment variable not found, not running " + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " COVFILE environment variable not found, not running " " bullseye\n"); return 0; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " run covsrc with COVFILE=[" + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " run covsrc with COVFILE=[" << covfile << "]" << std::endl); if(!this->RunBullseyeSourceSummary(cont)) - { - cmCTestLog(this->CTest, ERROR_MESSAGE, + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Error running bullseye summary.\n"); return 0; } - cmCTestLog(this->CTest, DEBUG, "HandleBullseyeCoverage return 1 " + cmCTestLog(this->CTest, DEBUG, "HandleBullseyeCoverage return 1 " << std::endl); return 1; } @@ -1881,7 +1881,7 @@ int cmCTestCoverageHandler::HandleBullseyeCoverage( bool cmCTestCoverageHandler::GetNextInt(std::string const& inputLine, std::string::size_type& pos, int& value) -{ +{ std::string::size_type start = pos; pos = inputLine.find(',', start); value = atoi(inputLine.substr(start, pos).c_str()); @@ -1892,7 +1892,7 @@ bool cmCTestCoverageHandler::GetNextInt(std::string const& inputLine, pos++; return true; } - + bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine( std::string const& inputLine, std::string& sourceFile, @@ -1906,7 +1906,7 @@ bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine( // find the first comma std::string::size_type pos = inputLine.find(','); if(pos == inputLine.npos) - { + { cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing string : " << inputLine.c_str() << "\n"); return false; @@ -1942,7 +1942,7 @@ bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine( if(pos != inputLine.npos) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing input : " - << inputLine.c_str() << " last pos not npos = " << pos << + << inputLine.c_str() << " last pos not npos = " << pos << "\n"); } return true; diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx index 56312c0..abc33de 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx @@ -28,8 +28,8 @@ bool cmCTestEmptyBinaryDirectoryCommand ostr << "problem removing the binary directory: " << args[0].c_str(); this->SetError(ostr.str().c_str()); return false; - } - + } + return true; } diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index fd75e45..5338f30 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -51,7 +51,7 @@ void cmCTestGenericHandler::SetOption(const char* op, const char* value) } //---------------------------------------------------------------------- -void cmCTestGenericHandler::SetPersistentOption(const char* op, +void cmCTestGenericHandler::SetPersistentOption(const char* op, const char* value) { this->SetOption(op, value); @@ -79,7 +79,7 @@ void cmCTestGenericHandler::Initialize() this->AppendXML = false; this->Options.clear(); t_StringToString::iterator it; - for ( it = this->PersistentOptions.begin(); + for ( it = this->PersistentOptions.begin(); it != this->PersistentOptions.end(); ++ it ) { @@ -117,7 +117,7 @@ bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part, { ostr << "_" << this->SubmitIndex; } - ostr << ".xml"; + ostr << ".xml"; if(this->CTest->GetCurrentTag().empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index 18189ec..ba8febb 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h @@ -73,7 +73,7 @@ public: typedef std::map<cmStdString,cmStdString> t_StringToString; - + void SetPersistentOption(const char* op, const char* value); void SetOption(const char* op, const char* value); const char* GetOption(const char* op); diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 0db2548..453e32c 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -91,7 +91,7 @@ bool cmCTestHandlerCommand } else { - const char* bdir = + const char* bdir = this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY"); if(bdir) { diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index 399fe8b..6db47ae 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h @@ -60,7 +60,7 @@ public: " ctest_memcheck([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n" " [START start number] [END end number]\n" " [STRIDE stride number] [EXCLUDE exclude regex ]\n" - " [INCLUDE include regex] \n" + " [INCLUDE include regex] \n" " [EXCLUDE_LABEL exclude regex] \n" " [INCLUDE_LABEL label regex] \n" " [PARALLEL_LEVEL level] )\n" diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 3e4ecdd..80218ad 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -84,7 +84,7 @@ public: } const char* GetAttribute(const char* name, const char** atts) - { + { int i = 0; for(; atts[i] != 0; ++i) { @@ -117,9 +117,9 @@ public: } if(ptr->ErrorCategory) { - this->Errors.push_back(cmCTestMemCheckHandler::ABW); // do not know + this->Errors.push_back(cmCTestMemCheckHandler::ABW); // do not know cmCTestLog(this->CTest, ERROR_MESSAGE, - "Found unknown Bounds Checker error " + "Found unknown Bounds Checker error " << ptr->ErrorCategory << std::endl); } } @@ -247,7 +247,8 @@ void cmCTestMemCheckHandler::GenerateTestCommand( { std::vector<cmStdString>::size_type pp; std::string memcheckcommand = ""; - memcheckcommand = this->MemoryTester; + memcheckcommand + = cmSystemTools::ConvertToOutputPath(this->MemoryTester.c_str()); for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ ) { args.push_back(this->MemoryTesterOptions[pp]); @@ -410,29 +411,46 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() "MemoryCheckCommand").c_str()) ) { this->MemoryTester - = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration( - "MemoryCheckCommand").c_str()); + = this->CTest->GetCTestConfiguration("MemoryCheckCommand").c_str(); + + // determine the checker type + if ( this->MemoryTester.find("valgrind") != std::string::npos ) + { + this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND; + } + else if ( this->MemoryTester.find("purify") != std::string::npos ) + { + this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY; + } + else if ( this->MemoryTester.find("BC") != std::string::npos ) + { + this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER; + } + else + { + this->MemoryTesterStyle = cmCTestMemCheckHandler::UNKNOWN; + } } else if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( "PurifyCommand").c_str()) ) { this->MemoryTester - = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration( - "PurifyCommand").c_str()); + = this->CTest->GetCTestConfiguration("PurifyCommand").c_str(); + this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY; } else if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( "ValgrindCommand").c_str()) ) { this->MemoryTester - = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration( - "ValgrindCommand").c_str()); + = this->CTest->GetCTestConfiguration("ValgrindCommand").c_str(); + this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND; } else if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( "BoundsCheckerCommand").c_str()) ) { this->MemoryTester - = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration( - "BoundsCheckerCommand").c_str()); + = this->CTest->GetCTestConfiguration("BoundsCheckerCommand").c_str(); + this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER; } else { @@ -470,82 +488,81 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() this->MemoryTesterOutputFile = this->CTest->GetBinaryDir() + "/Testing/Temporary/MemoryChecker.log"; - if ( this->MemoryTester.find("valgrind") != std::string::npos ) + switch ( this->MemoryTesterStyle ) { - this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND; - if ( this->MemoryTesterOptions.empty() ) - { - this->MemoryTesterOptions.push_back("-q"); - this->MemoryTesterOptions.push_back("--tool=memcheck"); - this->MemoryTesterOptions.push_back("--leak-check=yes"); - this->MemoryTesterOptions.push_back("--show-reachable=yes"); - this->MemoryTesterOptions.push_back("--workaround-gcc296-bugs=yes"); - this->MemoryTesterOptions.push_back("--num-callers=50"); - } - if ( this->CTest->GetCTestConfiguration( - "MemoryCheckSuppressionFile").size() ) - { - if ( !cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( - "MemoryCheckSuppressionFile").c_str()) ) + case cmCTestMemCheckHandler::VALGRIND: + if ( this->MemoryTesterOptions.empty() ) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot find memory checker suppression file: " - << this->CTest->GetCTestConfiguration( - "MemoryCheckSuppressionFile").c_str() << std::endl); - return false; - } - std::string suppressions = "--suppressions=" - + this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile"); - this->MemoryTesterOptions.push_back(suppressions); - } - } - else if ( this->MemoryTester.find("purify") != std::string::npos ) - { - this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY; - std::string outputFile; -#ifdef _WIN32 - if( this->CTest->GetCTestConfiguration( + this->MemoryTesterOptions.push_back("-q"); + this->MemoryTesterOptions.push_back("--tool=memcheck"); + this->MemoryTesterOptions.push_back("--leak-check=yes"); + this->MemoryTesterOptions.push_back("--show-reachable=yes"); + this->MemoryTesterOptions.push_back("--workaround-gcc296-bugs=yes"); + this->MemoryTesterOptions.push_back("--num-callers=50"); + } + if ( this->CTest->GetCTestConfiguration( "MemoryCheckSuppressionFile").size() ) + { + if ( !cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( + "MemoryCheckSuppressionFile").c_str()) ) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot find memory checker suppression file: " + << this->CTest->GetCTestConfiguration( + "MemoryCheckSuppressionFile").c_str() << std::endl); + return false; + } + std::string suppressions = "--suppressions=" + + this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile"); + this->MemoryTesterOptions.push_back(suppressions); + } + break; + case cmCTestMemCheckHandler::PURIFY: { - if( !cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( - "MemoryCheckSuppressionFile").c_str()) ) + std::string outputFile; +#ifdef _WIN32 + if( this->CTest->GetCTestConfiguration( + "MemoryCheckSuppressionFile").size() ) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Cannot find memory checker suppression file: " - << this->CTest->GetCTestConfiguration( - "MemoryCheckSuppressionFile").c_str() << std::endl); - return false; - } - std::string filterFiles = "/FilterFiles=" - + this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile"); - this->MemoryTesterOptions.push_back(filterFiles); - } - outputFile = "/SAVETEXTDATA="; + if( !cmSystemTools::FileExists(this->CTest->GetCTestConfiguration( + "MemoryCheckSuppressionFile").c_str()) ) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Cannot find memory checker suppression file: " + << this->CTest->GetCTestConfiguration( + "MemoryCheckSuppressionFile").c_str() << std::endl); + return false; + } + std::string filterFiles = "/FilterFiles=" + + this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile"); + this->MemoryTesterOptions.push_back(filterFiles); + } + outputFile = "/SAVETEXTDATA="; #else - outputFile = "-log-file="; + outputFile = "-log-file="; #endif - outputFile += this->MemoryTesterOutputFile; - this->MemoryTesterOptions.push_back(outputFile); - } - else if ( this->MemoryTester.find("BC") != std::string::npos ) - { - this->BoundsCheckerXMLFile = this->MemoryTesterOutputFile; - std::string dpbdFile = this->CTest->GetBinaryDir() - + "/Testing/Temporary/MemoryChecker.DPbd"; - this->BoundsCheckerDPBDFile = dpbdFile; - this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER; - this->MemoryTesterOptions.push_back("/B"); - this->MemoryTesterOptions.push_back(dpbdFile); - this->MemoryTesterOptions.push_back("/X"); - this->MemoryTesterOptions.push_back(this->MemoryTesterOutputFile); - this->MemoryTesterOptions.push_back("/M"); - } - else - { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Do not understand memory checker: " << this->MemoryTester.c_str() - << std::endl); - return false; + outputFile += this->MemoryTesterOutputFile; + this->MemoryTesterOptions.push_back(outputFile); + break; + } + case cmCTestMemCheckHandler::BOUNDS_CHECKER: + { + this->BoundsCheckerXMLFile = this->MemoryTesterOutputFile; + std::string dpbdFile = this->CTest->GetBinaryDir() + + "/Testing/Temporary/MemoryChecker.DPbd"; + this->BoundsCheckerDPBDFile = dpbdFile; + this->MemoryTesterOptions.push_back("/B"); + this->MemoryTesterOptions.push_back(dpbdFile); + this->MemoryTesterOptions.push_back("/X"); + this->MemoryTesterOptions.push_back(this->MemoryTesterOutputFile); + this->MemoryTesterOptions.push_back("/M"); + break; + } + default: + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Do not understand memory checker: " << this->MemoryTester.c_str() + << std::endl); + return false; } std::vector<cmStdString>::size_type cc; @@ -594,9 +611,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str, bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput( const std::string& str, std::string& log, int* results) -{ +{ std::vector<cmStdString> lines; - cmSystemTools::Split(str.c_str(), lines); + cmSystemTools::Split(str.c_str(), lines); cmOStringStream ostr; log = ""; @@ -604,7 +621,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput( int defects = 0; - for( std::vector<cmStdString>::iterator i = lines.begin(); + for( std::vector<cmStdString>::iterator i = lines.begin(); i != lines.end(); ++i) { int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT; @@ -657,7 +674,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( { unlimitedOutput = true; } - + std::string::size_type cc; cmOStringStream ostr; @@ -782,7 +799,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( } totalOutputSize += lines[cc].size(); ostr << cmXMLSafe(lines[cc]) << std::endl; - } + } else { nonValGrindOutput.push_back(cc); @@ -791,7 +808,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( // Now put all all the non valgrind output into the test output if(!outputFull) { - for(std::vector<std::string::size_type>::iterator i = + for(std::vector<std::string::size_type>::iterator i = nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i) { totalOutputSize += lines[*i].size(); @@ -801,7 +818,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( << cmXMLSafe(lines[*i]) << std::endl); ostr << cmXMLSafe(lines[*i]) << std::endl; - if(!unlimitedOutput && totalOutputSize > + if(!unlimitedOutput && totalOutputSize > static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) { outputFull = true; @@ -833,7 +850,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput( log = ""; double sttime = cmSystemTools::GetTime(); std::vector<cmStdString> lines; - cmSystemTools::Split(str.c_str(), lines); + cmSystemTools::Split(str.c_str(), lines); cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl); std::vector<cmStdString>::size_type cc; for ( cc = 0; cc < lines.size(); cc ++ ) @@ -886,8 +903,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput( // for the test void cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res) -{ - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, +{ + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "PostProcessBoundsCheckerTest for : " << res.Name.c_str() << std::endl); if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) ) @@ -902,22 +919,22 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res) std::ifstream ifs(this->MemoryTesterOutputFile.c_str()); if ( !ifs ) { - std::string log = "Cannot read memory tester output file: " + std::string log = "Cannot read memory tester output file: " + this->MemoryTesterOutputFile; cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl); return; - } + } res.Output += BOUNDS_CHECKER_MARKER; res.Output += "\n"; std::string line; while ( cmSystemTools::GetLineFromStream(ifs, line) ) { - res.Output += line; + res.Output += line; res.Output += "\n"; } } cmSystemTools::Delay(1000); - cmSystemTools::RemoveFile(this->BoundsCheckerDPBDFile.c_str()); + cmSystemTools::RemoveFile(this->BoundsCheckerDPBDFile.c_str()); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: " << this->BoundsCheckerDPBDFile.c_str() << std::endl); cmSystemTools::RemoveFile(this->BoundsCheckerXMLFile.c_str()); @@ -928,7 +945,7 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res) void cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "PostProcessPurifyTest for : " << res.Name.c_str() << std::endl); if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) ) @@ -945,7 +962,7 @@ cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res) + this->MemoryTesterOutputFile; cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl); return; - } + } std::string line; while ( cmSystemTools::GetLineFromStream(ifs, line) ) { diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h index 427d471..1e81c89 100644 --- a/Source/CTest/cmCTestMemCheckHandler.h +++ b/Source/CTest/cmCTestMemCheckHandler.h @@ -30,7 +30,7 @@ public: cmTypeMacro(cmCTestMemCheckHandler, cmCTestTestHandler); void PopulateCustomVectors(cmMakefile *mf); - + cmCTestMemCheckHandler(); void Initialize(); @@ -108,13 +108,13 @@ private: //! Parse Valgrind/Purify/Bounds Checker result out of the output //string. After running, log holds the output and results hold the //different memmory errors. - bool ProcessMemCheckOutput(const std::string& str, + bool ProcessMemCheckOutput(const std::string& str, std::string& log, int* results); - bool ProcessMemCheckValgrindOutput(const std::string& str, + bool ProcessMemCheckValgrindOutput(const std::string& str, std::string& log, int* results); - bool ProcessMemCheckPurifyOutput(const std::string& str, + bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log, int* results); - bool ProcessMemCheckBoundsCheckerOutput(const std::string& str, + bool ProcessMemCheckBoundsCheckerOutput(const std::string& str, std::string& log, int* results); void PostProcessPurifyTest(cmCTestTestResult& res); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 2cae802..ebef1ed 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -48,7 +48,7 @@ cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler() } // Set the tests -void +void cmCTestMultiProcessHandler::SetTests(TestMap& tests, PropertiesMap& properties) { @@ -178,7 +178,7 @@ void cmCTestMultiProcessHandler::EraseTest(int test) //--------------------------------------------------------- inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test) { - size_t processors = + size_t processors = static_cast<int>(this->Properties[test]->Processors); //If this is set to run serially, it must run alone. //Also, if processors setting is set higher than the -j @@ -205,7 +205,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test) } } - // copy the depend tests locally because when + // copy the depend tests locally because when // a test is finished it will be removed from the depend list // and we don't want to be iterating a list while removing from it TestSet depends = this->Tests[test]; @@ -240,7 +240,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test) this->StartTestProcess(test); return true; } - // This test was not able to start because it is waiting + // This test was not able to start because it is waiting // on depends to run return false; } @@ -351,7 +351,7 @@ void cmCTestMultiProcessHandler::UpdateCostData() while(std::getline(fin, line)) { if(line == "---") break; - std::vector<cmsys::String> parts = + std::vector<cmsys::String> parts = cmSystemTools::SplitString(line.c_str(), ' '); //Format: <name> <previous_runs> <avg_cost> if(parts.size() < 3) break; @@ -552,7 +552,7 @@ void cmCTestMultiProcessHandler::PrintTestList() } cmOStringStream indexStr; indexStr << " #" << p.Index << ":"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) << indexStr.str().c_str()); cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); @@ -603,7 +603,7 @@ void cmCTestMultiProcessHandler::CheckResume() << std::endl << "----------------------------------------------------------" << std::endl; - + std::ifstream fin; fin.open(fname.c_str()); std::string line; diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 1483440..cd21d91 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -19,16 +19,16 @@ /** \class cmCTestMultiProcessHandler * \brief run parallel ctest * - * cmCTestMultiProcessHandler + * cmCTestMultiProcessHandler */ -class cmCTestMultiProcessHandler +class cmCTestMultiProcessHandler { friend class TestComparator; public: struct TestSet : public std::set<int> {}; struct TestMap : public std::map<int, TestSet> {}; struct TestList : public std::vector<int> {}; - struct PropertiesMap : public + struct PropertiesMap : public std::map<int, cmCTestTestHandler::cmCTestTestProperties*> {}; cmCTestMultiProcessHandler(); diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h index f382b0f..b984c84 100644 --- a/Source/CTest/cmCTestReadCustomFilesCommand.h +++ b/Source/CTest/cmCTestReadCustomFilesCommand.h @@ -25,11 +25,11 @@ class cmCTestReadCustomFilesCommand : public cmCTestCommand public: cmCTestReadCustomFilesCommand() {} - + /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand; ni->CTest = this->CTest; @@ -55,7 +55,7 @@ public: { return "read CTestCustom files."; } - + /** * More documentation. */ diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h index 6df69af..05e7899 100644 --- a/Source/CTest/cmCTestRunScriptCommand.h +++ b/Source/CTest/cmCTestRunScriptCommand.h @@ -25,11 +25,11 @@ class cmCTestRunScriptCommand : public cmCTestCommand public: cmCTestRunScriptCommand() {} - + /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand; ni->CTest = this->CTest; @@ -56,7 +56,7 @@ public: { return "runs a ctest -S script"; } - + /** * More documentation. */ diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index c3de5dc..5eabf3f 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -59,7 +59,7 @@ bool cmCTestRunTest::CheckOutput() { // Store this line of output. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - this->GetIndex() << ": " << line << std::endl); + this->GetIndex() << ": " << line << std::endl); this->ProcessOutput += line; this->ProcessOutput += "\n"; } @@ -79,7 +79,7 @@ void cmCTestRunTest::CompressOutput() int ret; z_stream strm; - unsigned char* in = + unsigned char* in = reinterpret_cast<unsigned char*>( const_cast<char*>(this->ProcessOutput.c_str())); //zlib makes the guarantee that this is the maximum output size @@ -112,7 +112,7 @@ void cmCTestRunTest::CompressOutput() } (void)deflateEnd(&strm); - + unsigned char *encoded_buffer = new unsigned char[static_cast<int>(outSize * 1.5)]; @@ -169,11 +169,11 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } } if ( !found ) - { + { reason = "Required regular expression not found."; forceFail = true; } - reason += "Regex=["; + reason += "Regex=["; for ( passIt = this->TestProperties->RequiredRegularExpressions.begin(); passIt != this->TestProperties->RequiredRegularExpressions.end(); ++ passIt ) @@ -201,10 +201,10 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } if (res == cmsysProcess_State_Exited) { - bool success = - !forceFail && (retVal == 0 || + bool success = + !forceFail && (retVal == 0 || this->TestProperties->RequiredRegularExpressions.size()); - if((success && !this->TestProperties->WillFail) + if((success && !this->TestProperties->WillFail) || (!success && this->TestProperties->WillFail)) { this->TestResult.Status = cmCTestTestHandler::COMPLETED; @@ -312,10 +312,10 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) << std::endl; if(this->TestResult.Reason.size()) { - *this->TestHandler->LogFile << reasonType << ":\n" + *this->TestHandler->LogFile << reasonType << ":\n" << this->TestResult.Reason << "\n"; } - else + else { if(pass) { @@ -333,14 +333,14 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) << "----------------------------------------------------------" << std::endl << std::endl; } - // if the test actually started and ran - // record the results in TestResult + // if the test actually started and ran + // record the results in TestResult if(started) { bool compress = !this->TestHandler->MemCheck && this->CompressionRatio < 1 && this->CTest->ShouldCompressTestOutput(); - this->TestResult.Output = compress ? this->CompressedOutput + this->TestResult.Output = compress ? this->CompressedOutput : this->ProcessOutput; this->TestResult.CompressOutput = compress; this->TestResult.ReturnValue = this->TestProcess->GetExitValue(); @@ -378,7 +378,7 @@ void cmCTestRunTest::MemCheckPostProcess() { return; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": process test output now: " << this->TestProperties->Name.c_str() << " " << this->TestResult.Name.c_str() << std::endl); @@ -390,7 +390,7 @@ void cmCTestRunTest::MemCheckPostProcess() } else if(handler->MemoryTesterStyle == cmCTestMemCheckHandler::PURIFY) { - handler->PostProcessPurifyTest(this->TestResult); + handler->PostProcessPurifyTest(this->TestResult); } } @@ -411,7 +411,7 @@ bool cmCTestRunTest::StartTest(size_t total) this->TestResult.ReturnValue = -1; this->TestResult.CompletionStatus = "Failed to start"; this->TestResult.Status = cmCTestTestHandler::BAD_COMMAND; - this->TestResult.TestCount = this->TestProperties->Index; + this->TestResult.TestCount = this->TestProperties->Index; this->TestResult.Name = this->TestProperties->Name; this->TestResult.Path = this->TestProperties->Directory.c_str(); @@ -438,7 +438,7 @@ bool cmCTestRunTest::StartTest(size_t total) this->TestResult.Status = cmCTestTestHandler::NOT_RUN; return false; } - + // Check if all required files exist for(std::vector<std::string>::iterator i = this->TestProperties->RequiredFiles.begin(); @@ -465,9 +465,9 @@ bool cmCTestRunTest::StartTest(size_t total) if (this->ActualCommand == "") { // if the command was not found create a TestResult object - // that has that information + // that has that information this->TestProcess = new cmProcess; - *this->TestHandler->LogFile << "Unable to find executable: " + *this->TestHandler->LogFile << "Unable to find executable: " << args[1].c_str() << std::endl; cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to find executable: " << args[1].c_str() << std::endl); @@ -536,7 +536,7 @@ void cmCTestRunTest::ComputeArguments() cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl << this->Index << ": " - << (this->TestHandler->MemCheck?"MemCheck":"Test") + << (this->TestHandler->MemCheck?"MemCheck":"Test") << " command: " << testCommand << std::endl); } @@ -544,7 +544,7 @@ void cmCTestRunTest::ComputeArguments() //---------------------------------------------------------------------- void cmCTestRunTest::DartProcessing() { - if (!this->ProcessOutput.empty() && + if (!this->ProcessOutput.empty() && this->ProcessOutput.find("<DartMeasurement") != this->ProcessOutput.npos) { if (this->TestHandler->DartStuff.find(this->ProcessOutput.c_str())) @@ -695,7 +695,7 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) cmOStringStream indexStr; indexStr << " #" << this->Index << ":"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) << indexStr.str().c_str()); cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); @@ -704,17 +704,17 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) outname.resize(maxTestNameWidth + 4, '.'); *this->TestHandler->LogFile << this->TestProperties->Index << "/" - << this->TestHandler->TotalNumberOfTests << " Testing: " + << this->TestHandler->TotalNumberOfTests << " Testing: " << this->TestProperties->Name << std::endl; *this->TestHandler->LogFile << this->TestProperties->Index << "/" << this->TestHandler->TotalNumberOfTests << " Test: " << this->TestProperties->Name.c_str() << std::endl; *this->TestHandler->LogFile << "Command: \"" << this->ActualCommand << "\""; - + for (std::vector<std::string>::iterator i = this->Arguments.begin(); i != this->Arguments.end(); ++i) { - *this->TestHandler->LogFile + *this->TestHandler->LogFile << " \"" << i->c_str() << "\""; } *this->TestHandler->LogFile << std::endl @@ -730,6 +730,6 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) << this->ProcessOutput.c_str() << "<end of output>" << std::endl; cmCTestLog(this->CTest, HANDLER_OUTPUT, outname.c_str()); - cmCTestLog(this->CTest, DEBUG, "Testing " + cmCTestLog(this->CTest, DEBUG, "Testing " << this->TestProperties->Name.c_str() << " ... "); } diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 89456d5..476f3e1 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -74,7 +74,7 @@ private: cmCTestTestHandler * TestHandler; cmCTest * CTest; cmProcess * TestProcess; - //If the executable to run is ctest, don't create a new process; + //If the executable to run is ctest, don't create a new process; //just instantiate a new cmTest. (Can be disabled for a single test //if this option is set to false.) //bool OptimizeForCTest; diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index fab9a8c..2668c8e 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -18,6 +18,11 @@ #include <cmsys/RegularExpression.hxx> +struct cmCTestSVN::Revision: public cmCTestVC::Revision +{ + cmCTestSVN::SVNInfo* SVNInfo; +}; + //---------------------------------------------------------------------------- cmCTestSVN::cmCTestSVN(cmCTest* ct, std::ostream& log): cmCTestGlobalVC(ct, log) @@ -33,19 +38,22 @@ cmCTestSVN::~cmCTestSVN() //---------------------------------------------------------------------------- void cmCTestSVN::CleanupImpl() { - const char* svn = this->CommandLineTool.c_str(); - const char* svn_cleanup[] = {svn, "cleanup", 0}; + std::vector<const char*> svn_cleanup; + svn_cleanup.push_back("cleanup"); OutputLogger out(this->Log, "cleanup-out> "); OutputLogger err(this->Log, "cleanup-err> "); - this->RunChild(svn_cleanup, &out, &err); + this->RunSVNCommand(svn_cleanup, &out, &err); } //---------------------------------------------------------------------------- class cmCTestSVN::InfoParser: public cmCTestVC::LineParser { public: - InfoParser(cmCTestSVN* svn, const char* prefix, std::string& rev): - SVN(svn), Rev(rev) + InfoParser(cmCTestSVN* svn, + const char* prefix, + std::string& rev, + SVNInfo& svninfo): + Rev(rev), SVNRepo(svninfo) { this->SetLog(&svn->Log, prefix); this->RegexRev.compile("^Revision: ([0-9]+)"); @@ -53,8 +61,8 @@ public: this->RegexRoot.compile("^Repository Root: +([^ ]+) *$"); } private: - cmCTestSVN* SVN; std::string& Rev; + cmCTestSVN::SVNInfo& SVNRepo; cmsys::RegularExpression RegexRev; cmsys::RegularExpression RegexURL; cmsys::RegularExpression RegexRoot; @@ -66,11 +74,11 @@ private: } else if(this->RegexURL.find(this->Line)) { - this->SVN->URL = this->RegexURL.match(1); + this->SVNRepo.URL = this->RegexURL.match(1); } else if(this->RegexRoot.find(this->Line)) { - this->SVN->Root = this->RegexRoot.match(1); + this->SVNRepo.Root = this->RegexRoot.match(1); } return true; } @@ -95,70 +103,110 @@ static bool cmCTestSVNPathStarts(std::string const& p1, std::string const& p2) } //---------------------------------------------------------------------------- -std::string cmCTestSVN::LoadInfo() +std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo) { // Run "svn info" to get the repository info from the work tree. - const char* svn = this->CommandLineTool.c_str(); - const char* svn_info[] = {svn, "info", 0}; + std::vector<const char*> svn_info; + svn_info.push_back("info"); + svn_info.push_back(svninfo.LocalPath.c_str()); std::string rev; - InfoParser out(this, "info-out> ", rev); + InfoParser out(this, "info-out> ", rev, svninfo); OutputLogger err(this->Log, "info-err> "); - this->RunChild(svn_info, &out, &err); + this->RunSVNCommand(svn_info, &out, &err); return rev; } //---------------------------------------------------------------------------- void cmCTestSVN::NoteOldRevision() { - this->OldRevision = this->LoadInfo(); - this->Log << "Revision before update: " << this->OldRevision << "\n"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Old revision of repository is: " - << this->OldRevision << "\n"); + // Info for root repository + this->Repositories.push_back( SVNInfo("") ); + this->RootInfo = &(this->Repositories.back()); + // Info for the external repositories + this->LoadExternals(); + + // Get info for all the repositories + std::list<SVNInfo>::iterator itbeg = this->Repositories.begin(); + std::list<SVNInfo>::iterator itend = this->Repositories.end(); + for( ; itbeg != itend ; itbeg++) + { + SVNInfo& svninfo = *itbeg; + svninfo.OldRevision = this->LoadInfo(svninfo); + this->Log << "Revision for repository '" << svninfo.LocalPath + << "' before update: " << svninfo.OldRevision << "\n"; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + " Old revision of external repository '" + << svninfo.LocalPath << "' is: " + << svninfo.OldRevision << "\n"); + } + + // Set the global old revision to the one of the root + this->OldRevision = this->RootInfo->OldRevision; this->PriorRev.Rev = this->OldRevision; } //---------------------------------------------------------------------------- void cmCTestSVN::NoteNewRevision() { - this->NewRevision = this->LoadInfo(); - this->Log << "Revision after update: " << this->NewRevision << "\n"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, " New revision of repository is: " - << this->NewRevision << "\n"); + // Get info for the external repositories + std::list<SVNInfo>::iterator itbeg = this->Repositories.begin(); + std::list<SVNInfo>::iterator itend = this->Repositories.end(); + for( ; itbeg != itend ; itbeg++) + { + SVNInfo& svninfo = *itbeg; + svninfo.NewRevision = this->LoadInfo(svninfo); + this->Log << "Revision for repository '" << svninfo.LocalPath + << "' after update: " << svninfo.NewRevision << "\n"; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + " New revision of external repository '" + << svninfo.LocalPath << "' is: " + << svninfo.NewRevision << "\n"); + + // svninfo.Root = ""; // uncomment to test GuessBase + this->Log << "Repository '" << svninfo.LocalPath + << "' URL = " << svninfo.URL << "\n"; + this->Log << "Repository '" << svninfo.LocalPath + << "' Root = " << svninfo.Root << "\n"; + + // Compute the base path the working tree has checked out under + // the repository root. + if(!svninfo.Root.empty() + && cmCTestSVNPathStarts(svninfo.URL, svninfo.Root)) + { + svninfo.Base = cmCTest::DecodeURL( + svninfo.URL.substr(svninfo.Root.size())); + svninfo.Base += "/"; + } + this->Log << "Repository '" << svninfo.LocalPath + << "' Base = " << svninfo.Base << "\n"; - // this->Root = ""; // uncomment to test GuessBase - this->Log << "URL = " << this->URL << "\n"; - this->Log << "Root = " << this->Root << "\n"; + } - // Compute the base path the working tree has checked out under - // the repository root. - if(!this->Root.empty() && cmCTestSVNPathStarts(this->URL, this->Root)) - { - this->Base = cmCTest::DecodeURL(this->URL.substr(this->Root.size())); - this->Base += "/"; - } - this->Log << "Base = " << this->Base << "\n"; + // Set the global new revision to the one of the root + this->NewRevision = this->RootInfo->NewRevision; } //---------------------------------------------------------------------------- -void cmCTestSVN::GuessBase(std::vector<Change> const& changes) +void cmCTestSVN::GuessBase(SVNInfo& svninfo, + std::vector<Change> const& changes) { // Subversion did not give us a good repository root so we need to // guess the base path from the URL and the paths in a revision with // changes under it. // Consider each possible URL suffix from longest to shortest. - for(std::string::size_type slash = this->URL.find('/'); - this->Base.empty() && slash != std::string::npos; - slash = this->URL.find('/', slash+1)) + for(std::string::size_type slash = svninfo.URL.find('/'); + svninfo.Base.empty() && slash != std::string::npos; + slash = svninfo.URL.find('/', slash+1)) { // If the URL suffix is a prefix of at least one path then it is the base. - std::string base = cmCTest::DecodeURL(this->URL.substr(slash)); + std::string base = cmCTest::DecodeURL(svninfo.URL.substr(slash)); for(std::vector<Change>::const_iterator ci = changes.begin(); - this->Base.empty() && ci != changes.end(); ++ci) + svninfo.Base.empty() && ci != changes.end(); ++ci) { if(cmCTestSVNPathStarts(ci->Path, base)) { - this->Base = base; + svninfo.Base = base; } } } @@ -167,25 +215,9 @@ void cmCTestSVN::GuessBase(std::vector<Change> const& changes) // base lie under its path. If no base was found then the working // tree must be a checkout of the entire repo and this will match // the leading slash in all paths. - this->Base += "/"; - - this->Log << "Guessed Base = " << this->Base << "\n"; -} + svninfo.Base += "/"; -//---------------------------------------------------------------------------- -const char* cmCTestSVN::LocalPath(std::string const& path) -{ - if(path.size() > this->Base.size() && - strncmp(path.c_str(), this->Base.c_str(), this->Base.size()) == 0) - { - // This path lies under the base, so return a relative path. - return path.c_str() + this->Base.size(); - } - else - { - // This path does not lie under the base, so ignore it. - return 0; - } + this->Log << "Guessed Base = " << svninfo.Base << "\n"; } //---------------------------------------------------------------------------- @@ -254,19 +286,52 @@ bool cmCTestSVN::UpdateImpl() } std::vector<char const*> svn_update; - svn_update.push_back(this->CommandLineTool.c_str()); svn_update.push_back("update"); - svn_update.push_back("--non-interactive"); for(std::vector<cmStdString>::const_iterator ai = args.begin(); ai != args.end(); ++ai) { svn_update.push_back(ai->c_str()); } - svn_update.push_back(0); UpdateParser out(this, "up-out> "); OutputLogger err(this->Log, "up-err> "); - return this->RunUpdateCommand(&svn_update[0], &out, &err); + return this->RunSVNCommand(svn_update, &out, &err); +} + +//---------------------------------------------------------------------------- +bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters, + OutputParser* out, OutputParser* err) +{ + if(parameters.empty()) return false; + + std::vector<char const*> args; + args.push_back(this->CommandLineTool.c_str()); + + args.insert(args.end(), parameters.begin(), parameters.end()); + + args.push_back("--non-interactive"); + + std::string userOptions = + this->CTest->GetCTestConfiguration("SVNOptions"); + + std::vector<cmStdString> parsedUserOptions = + cmSystemTools::ParseArguments(userOptions.c_str()); + for(std::vector<cmStdString>::iterator i = parsedUserOptions.begin(); + i != parsedUserOptions.end(); ++i) + { + args.push_back(i->c_str()); + } + + args.push_back(0); + + if(strcmp(parameters[0], "update") == 0) + { + return RunUpdateCommand(&args[0], out, err); + } + else + { + return RunChild(&args[0], out, err); + } } //---------------------------------------------------------------------------- @@ -274,11 +339,13 @@ class cmCTestSVN::LogParser: public cmCTestVC::OutputLogger, private cmXMLParser { public: - LogParser(cmCTestSVN* svn, const char* prefix): - OutputLogger(svn->Log, prefix), SVN(svn) { this->InitializeParser(); } + LogParser(cmCTestSVN* svn, const char* prefix, SVNInfo& svninfo): + OutputLogger(svn->Log, prefix), SVN(svn), SVNRepo(svninfo) + { this->InitializeParser(); } ~LogParser() { this->CleanupParser(); } private: cmCTestSVN* SVN; + cmCTestSVN::SVNInfo& SVNRepo; typedef cmCTestSVN::Revision Revision; typedef cmCTestSVN::Change Change; @@ -300,6 +367,7 @@ private: if(strcmp(name, "logentry") == 0) { this->Rev = Revision(); + this->Rev.SVNInfo = &SVNRepo; if(const char* rev = this->FindAttribute(atts, "revision")) { this->Rev.Rev = rev; @@ -325,11 +393,13 @@ private: { if(strcmp(name, "logentry") == 0) { - this->SVN->DoRevision(this->Rev, this->Changes); + this->SVN->DoRevisionSVN(this->Rev, this->Changes); } else if(strcmp(name, "path") == 0 && !this->CData.empty()) { - this->CurChange.Path.assign(&this->CData[0], this->CData.size()); + std::string orig_path(&this->CData[0], this->CData.size()); + std::string new_path = SVNRepo.BuildLocalPath( orig_path ); + this->CurChange.Path.assign(new_path); this->Changes.push_back(this->CurChange); } else if(strcmp(name, "author") == 0 && !this->CData.empty()) @@ -356,36 +426,59 @@ private: //---------------------------------------------------------------------------- void cmCTestSVN::LoadRevisions() { + // Get revisions for all the external repositories + std::list<SVNInfo>::iterator itbeg = this->Repositories.begin(); + std::list<SVNInfo>::iterator itend = this->Repositories.end(); + for( ; itbeg != itend ; itbeg++) + { + SVNInfo& svninfo = *itbeg; + LoadRevisions(svninfo); + } +} + +//---------------------------------------------------------------------------- +void cmCTestSVN::LoadRevisions(SVNInfo &svninfo) +{ // We are interested in every revision included in the update. std::string revs; - if(atoi(this->OldRevision.c_str()) < atoi(this->NewRevision.c_str())) + if(atoi(svninfo.OldRevision.c_str()) < atoi(svninfo.NewRevision.c_str())) { - revs = "-r" + this->OldRevision + ":" + this->NewRevision; + revs = "-r" + svninfo.OldRevision + ":" + svninfo.NewRevision; } else { - revs = "-r" + this->NewRevision; + revs = "-r" + svninfo.NewRevision; } // Run "svn log" to get all global revisions of interest. - const char* svn = this->CommandLineTool.c_str(); - const char* svn_log[] = {svn, "log", "--xml", "-v", revs.c_str(), 0}; - { - LogParser out(this, "log-out> "); + std::vector<const char*> svn_log; + svn_log.push_back("log"); + svn_log.push_back("--xml"); + svn_log.push_back("-v"); + svn_log.push_back(revs.c_str()); + svn_log.push_back(svninfo.LocalPath.c_str()); + LogParser out(this, "log-out> ", svninfo); OutputLogger err(this->Log, "log-err> "); - this->RunChild(svn_log, &out, &err); - } + this->RunSVNCommand(svn_log, &out, &err); } //---------------------------------------------------------------------------- -void cmCTestSVN::DoRevision(Revision const& revision, - std::vector<Change> const& changes) +void cmCTestSVN::DoRevisionSVN(Revision const& revision, + std::vector<Change> const& changes) { // Guess the base checkout path from the changes if necessary. - if(this->Base.empty() && !changes.empty()) + if(this->RootInfo->Base.empty() && !changes.empty()) + { + this->GuessBase(*this->RootInfo, changes); + } + + // Ignore changes in the old revision for external repositories + if(revision.Rev == revision.SVNInfo->OldRevision + && revision.SVNInfo->LocalPath != "") { - this->GuessBase(changes); + return; } + this->cmCTestGlobalVC::DoRevision(revision, changes); } @@ -434,11 +527,11 @@ private: void cmCTestSVN::LoadModifications() { // Run "svn status" which reports local modifications. - const char* svn = this->CommandLineTool.c_str(); - const char* svn_status[] = {svn, "status", "--non-interactive", 0}; + std::vector<const char*> svn_status; + svn_status.push_back("status"); StatusParser out(this, "status-out> "); OutputLogger err(this->Log, "status-err> "); - this->RunChild(svn_status, &out, &err); + this->RunSVNCommand(svn_status, &out, &err); } //---------------------------------------------------------------------------- @@ -446,5 +539,81 @@ void cmCTestSVN::WriteXMLGlobal(std::ostream& xml) { this->cmCTestGlobalVC::WriteXMLGlobal(xml); - xml << "\t<SVNPath>" << this->Base << "</SVNPath>\n"; + xml << "\t<SVNPath>" << this->RootInfo->Base << "</SVNPath>\n"; +} + +//---------------------------------------------------------------------------- +class cmCTestSVN::ExternalParser: public cmCTestVC::LineParser +{ +public: + ExternalParser(cmCTestSVN* svn, const char* prefix): SVN(svn) + { + this->SetLog(&svn->Log, prefix); + this->RegexExternal.compile("^X..... +(.+)$"); + } +private: + cmCTestSVN* SVN; + cmsys::RegularExpression RegexExternal; + bool ProcessLine() + { + if(this->RegexExternal.find(this->Line)) + { + this->DoPath(this->RegexExternal.match(1)); + } + return true; + } + + void DoPath(std::string const& path) + { + // Get local path relative to the source directory + std::string local_path; + if(path.size() > this->SVN->SourceDirectory.size() && + strncmp(path.c_str(), this->SVN->SourceDirectory.c_str(), + this->SVN->SourceDirectory.size()) == 0) + { + local_path = path.c_str() + this->SVN->SourceDirectory.size() + 1; + } + else + { + local_path = path; + } + this->SVN->Repositories.push_back( SVNInfo(local_path.c_str()) ); + } +}; + +//---------------------------------------------------------------------------- +void cmCTestSVN::LoadExternals() +{ + // Run "svn status" to get the list of external repositories + std::vector<const char*> svn_status; + svn_status.push_back("status"); + ExternalParser out(this, "external-out> "); + OutputLogger err(this->Log, "external-err> "); + this->RunSVNCommand(svn_status, &out, &err); +} + +//---------------------------------------------------------------------------- +std::string cmCTestSVN::SVNInfo::BuildLocalPath(std::string const& path) const +{ + std::string local_path; + + // Add local path prefix if not empty + if (!this->LocalPath.empty()) + { + local_path += this->LocalPath; + local_path += "/"; + } + + // Add path with base prefix removed + if(path.size() > this->Base.size() && + strncmp(path.c_str(), this->Base.c_str(), this->Base.size()) == 0) + { + local_path += (path.c_str() + this->Base.size()); + } + else + { + local_path += path; + } + + return local_path; } diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h index f72c58f..c6548e3 100644 --- a/Source/CTest/cmCTestSVN.h +++ b/Source/CTest/cmCTestSVN.h @@ -33,24 +33,54 @@ private: virtual void NoteNewRevision(); virtual bool UpdateImpl(); - // URL of repository directory checked out in the working tree. - std::string URL; + bool RunSVNCommand(std::vector<char const*> const& parameters, + OutputParser* out, OutputParser* err); - // URL of repository root directory. - std::string Root; + // Information about an SVN repository (root repository or external) + struct SVNInfo { - // Directory under repository root checked out in working tree. - std::string Base; + SVNInfo(const char* path) : LocalPath(path) {} + // Remove base from the filename + std::string BuildLocalPath(std::string const& path) const; - std::string LoadInfo(); + // LocalPath relative to the main source directory. + std::string LocalPath; + + // URL of repository directory checked out in the working tree. + std::string URL; + + // URL of repository root directory. + std::string Root; + + // Directory under repository root checked out in working tree. + std::string Base; + + // Old and new repository revisions. + std::string OldRevision; + std::string NewRevision; + + }; + + // Extended revision structure to include info about external it refers to. + struct Revision; + friend struct Revision; + + // Info of all the repositories (root, externals and nested ones). + std::list<SVNInfo> Repositories; + + // Pointer to the infos of the root repository. + SVNInfo* RootInfo; + + std::string LoadInfo(SVNInfo& svninfo); + void LoadExternals(); void LoadModifications(); void LoadRevisions(); + void LoadRevisions(SVNInfo& svninfo); - void GuessBase(std::vector<Change> const& changes); - const char* LocalPath(std::string const& path); + void GuessBase(SVNInfo &svninfo, std::vector<Change> const& changes); - void DoRevision(Revision const& revision, - std::vector<Change> const& changes); + void DoRevisionSVN(Revision const& revision, + std::vector<Change> const& changes); void WriteXMLGlobal(std::ostream& xml); @@ -59,10 +89,12 @@ private: class LogParser; class StatusParser; class UpdateParser; + class ExternalParser; friend class InfoParser; friend class LogParser; friend class StatusParser; friend class UpdateParser; + friend class ExternalParser; }; #endif diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index d3ab2ef..8643cb3 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -435,6 +435,15 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) return 2; } + // Add definitions of variables passed in on the command line: + const std::map<std::string, std::string> &defs = + this->CTest->GetDefinitions(); + for (std::map<std::string, std::string>::const_iterator it = defs.begin(); + it != defs.end(); ++it) + { + this->Makefile->AddDefinition(it->first.c_str(), it->second.c_str()); + } + // finally read in the script if (!this->Makefile->ReadListFile(0, script.c_str()) || cmSystemTools::GetErrorOccuredFlag()) diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index a7cf6ba..9d852ca 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h @@ -97,7 +97,7 @@ public: static void SleepInSeconds(unsigned int secondsToWait); void UpdateElapsedTime(); - /** + /** * Return the time remaianing that the script is allowed to run in * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has * not been set it returns 1e7 seconds diff --git a/Source/CTest/cmCTestSleepCommand.cxx b/Source/CTest/cmCTestSleepCommand.cxx index 5b06972..7e87550 100644 --- a/Source/CTest/cmCTestSleepCommand.cxx +++ b/Source/CTest/cmCTestSleepCommand.cxx @@ -47,7 +47,7 @@ bool cmCTestSleepCommand } return true; } - + this->SetError("called with incorrect number of arguments"); return false; } diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 80fd6af..0f51ddf 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h @@ -25,11 +25,11 @@ class cmCTestSleepCommand : public cmCTestCommand public: cmCTestSleepCommand() {} - + /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { cmCTestSleepCommand* ni = new cmCTestSleepCommand; ni->CTest = this->CTest; @@ -56,7 +56,7 @@ public: { return "sleeps for some amount of time"; } - + /** * More documentation. */ diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 5aee035..231f035 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -32,7 +32,7 @@ cmCTestTestCommand::cmCTestTestCommand() cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() { - const char* ctestTimeout = + const char* ctestTimeout = this->Makefile->GetDefinition("CTEST_TEST_TIMEOUT"); double timeout = this->CTest->GetTimeOut(); @@ -86,7 +86,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() } if(this->Values[ctt_INCLUDE_LABEL]) { - handler->SetOption("LabelRegularExpression", + handler->SetOption("LabelRegularExpression", this->Values[ctt_INCLUDE_LABEL]); } if(this->Values[ctt_PARALLEL_LEVEL]) diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index d184ff2..130cb69 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -58,7 +58,7 @@ public: " ctest_test([BUILD build_dir] [APPEND]\n" " [START start number] [END end number]\n" " [STRIDE stride number] [EXCLUDE exclude regex ]\n" - " [INCLUDE include regex] [RETURN_VALUE res] \n" + " [INCLUDE include regex] [RETURN_VALUE res] \n" " [EXCLUDE_LABEL exclude regex] \n" " [INCLUDE_LABEL label regex] \n" " [PARALLEL_LEVEL level] \n" diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index ead449e..b796b83 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1304,9 +1304,10 @@ int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec) for ( it = vec.begin(); it != vec.end(); ++it ) { int retVal = 0; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << *it + std::string cmd = cmSystemTools::ConvertToOutputPath(it->c_str()); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << cmd << std::endl); - if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0, + if ( !cmSystemTools::RunSingleCommand(cmd.c_str(), 0, &retVal, 0, cmSystemTools::OUTPUT_MERGE /*this->Verbose*/) || retVal != 0 ) { diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 8414349..2ca9f6c 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -44,6 +44,8 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS"); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, + "SVNOptions", "CTEST_SVN_OPTIONS"); + this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "BZRCommand", "CTEST_BZR_COMMAND"); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS"); diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h index 44e1dac..9dd0651 100644 --- a/Source/CTest/cmCTestVC.h +++ b/Source/CTest/cmCTestVC.h @@ -67,6 +67,9 @@ protected: virtual void NoteNewRevision(); virtual bool WriteXMLUpdates(std::ostream& xml); +#if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x510 +public: // Sun CC 5.1 needs help to allow cmCTestSVN::Revision to see this +#endif /** Basic information about one revision of a tree or file. */ struct Revision { @@ -80,6 +83,7 @@ protected: std::string Log; }; +protected: struct File; friend struct File; diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 0ee631f..000bc85 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -196,12 +196,12 @@ int cmProcess::ReportStatus() { case cmsysProcess_State_Starting: { - std::cerr << "cmProcess: Never started " + std::cerr << "cmProcess: Never started " << this->Command << " process.\n"; } break; case cmsysProcess_State_Error: { - std::cerr << "cmProcess: Error executing " << this->Command + std::cerr << "cmProcess: Error executing " << this->Command << " process: " << cmsysProcess_GetErrorString(this->Process) << "\n"; @@ -241,19 +241,19 @@ int cmProcess::ReportStatus() } break; case cmsysProcess_State_Executing: { - std::cerr << "cmProcess: Never terminated " << + std::cerr << "cmProcess: Never terminated " << this->Command << " process.\n"; } break; case cmsysProcess_State_Exited: { result = cmsysProcess_GetExitValue(this->Process); - std::cerr << "cmProcess: " << this->Command + std::cerr << "cmProcess: " << this->Command << " process exited with code " << result << "\n"; } break; case cmsysProcess_State_Expired: { - std::cerr << "cmProcess: killed " << this->Command + std::cerr << "cmProcess: killed " << this->Command << " process due to timeout.\n"; } break; case cmsysProcess_State_Killed: diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h index ff99ca2..1479df0 100644 --- a/Source/CTest/cmProcess.h +++ b/Source/CTest/cmProcess.h @@ -22,7 +22,7 @@ * * cmProcess wraps the kwsys process stuff in a c++ class. */ -class cmProcess +class cmProcess { public: cmProcess(); @@ -37,7 +37,7 @@ public: // return the process status int GetProcessStatus(); - // Report the status of the program + // Report the status of the program int ReportStatus(); int GetId() { return this->Id; } void SetId(int id) { this->Id = id;} diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt index 3349ebe..96e28b4 100644 --- a/Source/CursesDialog/CMakeLists.txt +++ b/Source/CursesDialog/CMakeLists.txt @@ -10,7 +10,7 @@ # See the License for more information. #============================================================================= -SET( CURSES_SRCS +set( CURSES_SRCS CursesDialog/cmCursesBoolWidget CursesDialog/cmCursesCacheEntryComposite CursesDialog/cmCursesDummyWidget @@ -25,13 +25,13 @@ SET( CURSES_SRCS CursesDialog/ccmake ) -INCLUDE_DIRECTORIES(${CMake_SOURCE_DIR}/Source/CursesDialog/form +include_directories(${CMake_SOURCE_DIR}/Source/CursesDialog/form ${CMake_BINARY_DIR}/Source/CursesDialog/form) -INCLUDE_DIRECTORIES(${CURSES_INCLUDE_PATH}) +include_directories(${CURSES_INCLUDE_PATH}) -ADD_EXECUTABLE(ccmake ${CURSES_SRCS} ) -TARGET_LINK_LIBRARIES(ccmake CMakeLib) -TARGET_LINK_LIBRARIES(ccmake cmForm) +add_executable(ccmake ${CURSES_SRCS} ) +target_link_libraries(ccmake CMakeLib) +target_link_libraries(ccmake cmForm) -INSTALL_TARGETS(/bin ccmake) +install_targets(/bin ccmake) diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx index 9c4c5a5..fd15b99 100644 --- a/Source/CursesDialog/cmCursesBoolWidget.cxx +++ b/Source/CursesDialog/cmCursesBoolWidget.cxx @@ -12,7 +12,7 @@ #include "cmCursesBoolWidget.h" #include "cmCursesMainForm.h" -cmCursesBoolWidget::cmCursesBoolWidget(int width, int height, +cmCursesBoolWidget::cmCursesBoolWidget(int width, int height, int left, int top) : cmCursesWidget(width, height, left, top) { @@ -38,15 +38,15 @@ bool cmCursesBoolWidget::HandleInput(int& key, cmCursesMainForm*, WINDOW* w) this->SetValueAsBool(true); } - touchwin(w); - wrefresh(w); + touchwin(w); + wrefresh(w); return true; } else { return false; } - + } void cmCursesBoolWidget::SetValueAsBool(bool value) @@ -56,7 +56,7 @@ void cmCursesBoolWidget::SetValueAsBool(bool value) this->SetValue("ON"); } else - { + { this->SetValue("OFF"); } } @@ -68,7 +68,7 @@ bool cmCursesBoolWidget::GetValueAsBool() return true; } else - { + { return false; } } diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h index 0d1d6a6..d2a25ca 100644 --- a/Source/CursesDialog/cmCursesBoolWidget.h +++ b/Source/CursesDialog/cmCursesBoolWidget.h @@ -19,7 +19,7 @@ class cmCursesBoolWidget : public cmCursesWidget { public: cmCursesBoolWidget(int width, int height, int left, int top); - + // Description: // Handle user input. Called by the container of this widget // when this widget has focus. Returns true if the input was diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index 828384d..c58d037 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -19,19 +19,19 @@ #include "../cmSystemTools.h" cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(const char* key, - int labelwidth, + int labelwidth, int entrywidth) : Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth) { this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key); this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " "); - this->Entry = 0; + this->Entry = 0; this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1); } cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( - const char* key, const cmCacheManager::CacheIterator& it, bool isNew, - int labelwidth, int entrywidth) + const char* key, const cmCacheManager::CacheIterator& it, bool isNew, + int labelwidth, int entrywidth) : Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth) { this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key); @@ -74,7 +74,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( it.GetValue()); break; case cmCacheManager::UNINITIALIZED: - cmSystemTools::Error("Found an undefined variable: ", it.GetName()); + cmSystemTools::Error("Found an undefined variable: ", it.GetName()); break; default: // TODO : put warning message here diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h index a40ea28..1357a02 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.h +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h @@ -20,7 +20,7 @@ class cmCursesCacheEntryComposite public: cmCursesCacheEntryComposite(const char* key, int labelwidth, int entrywidth); cmCursesCacheEntryComposite(const char* key, - const cmCacheManager::CacheIterator& it, + const cmCacheManager::CacheIterator& it, bool isNew, int labelwidth, int entrywidth); ~cmCursesCacheEntryComposite(); const char* GetValue(); diff --git a/Source/CursesDialog/cmCursesDummyWidget.cxx b/Source/CursesDialog/cmCursesDummyWidget.cxx index 1d8a45d..60086a5 100644 --- a/Source/CursesDialog/cmCursesDummyWidget.cxx +++ b/Source/CursesDialog/cmCursesDummyWidget.cxx @@ -11,7 +11,7 @@ ============================================================================*/ #include "cmCursesDummyWidget.h" -cmCursesDummyWidget::cmCursesDummyWidget(int width, int height, +cmCursesDummyWidget::cmCursesDummyWidget(int width, int height, int left, int top) : cmCursesWidget(width, height, left, top) { diff --git a/Source/CursesDialog/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h index cc4cc74..9ac1365 100644 --- a/Source/CursesDialog/cmCursesDummyWidget.h +++ b/Source/CursesDialog/cmCursesDummyWidget.h @@ -20,7 +20,7 @@ class cmCursesDummyWidget : public cmCursesWidget { public: cmCursesDummyWidget(int width, int height, int left, int top); - + // Description: // Handle user input. Called by the container of this widget // when this widget has focus. Returns true if the input was diff --git a/Source/CursesDialog/cmCursesFilePathWidget.cxx b/Source/CursesDialog/cmCursesFilePathWidget.cxx index 13bbcc9..01db014 100644 --- a/Source/CursesDialog/cmCursesFilePathWidget.cxx +++ b/Source/CursesDialog/cmCursesFilePathWidget.cxx @@ -11,7 +11,7 @@ ============================================================================*/ #include "cmCursesFilePathWidget.h" -cmCursesFilePathWidget::cmCursesFilePathWidget(int width, int height, +cmCursesFilePathWidget::cmCursesFilePathWidget(int width, int height, int left, int top) : cmCursesPathWidget(width, height, left, top) { diff --git a/Source/CursesDialog/cmCursesForm.h b/Source/CursesDialog/cmCursesForm.h index 7556d74..3cba856 100644 --- a/Source/CursesDialog/cmCursesForm.h +++ b/Source/CursesDialog/cmCursesForm.h @@ -20,7 +20,7 @@ class cmCursesForm public: cmCursesForm(); virtual ~cmCursesForm(); - + // Description: // Handle user input. virtual void HandleInput() = 0; @@ -59,7 +59,7 @@ public: } static cmCursesForm* CurrentForm; - + protected: diff --git a/Source/CursesDialog/cmCursesLabelWidget.cxx b/Source/CursesDialog/cmCursesLabelWidget.cxx index 2ad4813..b5ed312 100644 --- a/Source/CursesDialog/cmCursesLabelWidget.cxx +++ b/Source/CursesDialog/cmCursesLabelWidget.cxx @@ -11,7 +11,7 @@ ============================================================================*/ #include "cmCursesLabelWidget.h" -cmCursesLabelWidget::cmCursesLabelWidget(int width, int height, +cmCursesLabelWidget::cmCursesLabelWidget(int width, int height, int left, int top, const std::string& name) : cmCursesWidget(width, height, left, top) diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h index bbcc586..cc32d11 100644 --- a/Source/CursesDialog/cmCursesLabelWidget.h +++ b/Source/CursesDialog/cmCursesLabelWidget.h @@ -23,7 +23,7 @@ public: cmCursesLabelWidget(int width, int height, int left, int top, const std::string& name); virtual ~cmCursesLabelWidget(); - + // Description: // Handle user input. Called by the container of this widget // when this widget has focus. Returns true if the input was diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx index 0e2cd22..057f8f3 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.cxx +++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx @@ -19,10 +19,10 @@ inline int ctrl(int z) { return (z&037); -} +} -cmCursesLongMessageForm::cmCursesLongMessageForm(std::vector<std::string> - const& messages, const char* +cmCursesLongMessageForm::cmCursesLongMessageForm(std::vector<std::string> + const& messages, const char* title) { // Append all messages into on big string @@ -84,7 +84,7 @@ void cmCursesLongMessageForm::UpdateStatusBar() curses_move(y-4,0); attron(A_STANDOUT); printw(bar); - attroff(A_STANDOUT); + attroff(A_STANDOUT); curses_move(y-3,0); printw(version); pos_form_cursor(this->Form); @@ -94,7 +94,7 @@ void cmCursesLongMessageForm::PrintKeys() { int x,y; getmaxyx(stdscr, y, x); - if ( x < cmCursesMainForm::MIN_WIDTH || + if ( x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT ) { return; @@ -105,7 +105,7 @@ void cmCursesLongMessageForm::PrintKeys() curses_move(y-2,0); printw(firstLine); pos_form_cursor(this->Form); - + } void cmCursesLongMessageForm::Render(int, int, int, int) @@ -155,7 +155,7 @@ void cmCursesLongMessageForm::Render(int, int, int, int) this->UpdateStatusBar(); this->PrintKeys(); - touchwin(stdscr); + touchwin(stdscr); refresh(); } @@ -200,8 +200,8 @@ void cmCursesLongMessageForm::HandleInput() this->UpdateStatusBar(); this->PrintKeys(); - touchwin(stdscr); - wrefresh(stdscr); + touchwin(stdscr); + wrefresh(stdscr); } } diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h index 341f9c6..1e86974 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.h +++ b/Source/CursesDialog/cmCursesLongMessageForm.h @@ -21,10 +21,10 @@ class cmCursesCacheEntryComposite; class cmCursesLongMessageForm : public cmCursesForm { public: - cmCursesLongMessageForm(std::vector<std::string> const& messages, + cmCursesLongMessageForm(std::vector<std::string> const& messages, const char* title); virtual ~cmCursesLongMessageForm(); - + // Description: // Handle user input. virtual void HandleInput(); diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h index 3e191b4..883a2b3 100644 --- a/Source/CursesDialog/cmCursesMainForm.h +++ b/Source/CursesDialog/cmCursesMainForm.h @@ -30,12 +30,12 @@ class cmCursesMainForm : public cmCursesForm public: cmCursesMainForm(std::vector<std::string> const& args, int initwidth); virtual ~cmCursesMainForm(); - + /** * Set the widgets which represent the cache entries. */ void InitializeUI(); - + /** * Handle user input. */ @@ -65,7 +65,7 @@ public: * exception is during a resize. The optional argument specifies the * string to be displayed in the status bar. */ - virtual void UpdateStatusBar() { this->UpdateStatusBar(0); } + virtual void UpdateStatusBar() { this->UpdateStatusBar(0); } virtual void UpdateStatusBar(const char* message); /** @@ -90,7 +90,7 @@ public: int Configure(int noconfigure=0); /** - * Used to generate + * Used to generate */ int Generate(); @@ -98,7 +98,7 @@ public: * Used by main program */ int LoadCache(const char *dir); - + /** * Progress callback */ diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx index b113c2e..14c325b 100644 --- a/Source/CursesDialog/cmCursesPathWidget.cxx +++ b/Source/CursesDialog/cmCursesPathWidget.cxx @@ -14,7 +14,7 @@ #include "cmCursesMainForm.h" #include "cmSystemTools.h" -cmCursesPathWidget::cmCursesPathWidget(int width, int height, +cmCursesPathWidget::cmCursesPathWidget(int width, int height, int left, int top) : cmCursesStringWidget(width, height, left, top) { @@ -75,8 +75,8 @@ void cmCursesPathWidget::OnTab(cmCursesMainForm* fm, WINDOW* w) } this->SetString(cstr.c_str()); - touchwin(w); - wrefresh(w); + touchwin(w); + wrefresh(w); form_driver(form, REQ_END_FIELD); this->LastGlob = glob; this->LastString = cstr; diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx index d363f00..5c7414f 100644 --- a/Source/CursesDialog/cmCursesStringWidget.cxx +++ b/Source/CursesDialog/cmCursesStringWidget.cxx @@ -15,9 +15,9 @@ inline int ctrl(int z) { return (z&037); -} +} -cmCursesStringWidget::cmCursesStringWidget(int width, int height, +cmCursesStringWidget::cmCursesStringWidget(int width, int height, int left, int top) : cmCursesWidget(width, height, left, top) { @@ -63,7 +63,7 @@ void cmCursesStringWidget::OnType(int& key, cmCursesMainForm* fm, WINDOW*) form_driver(fm->GetForm(), key); } -bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, +bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w) { int x,y; @@ -90,7 +90,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, getmaxyx(stdscr, y, x); // If window too small, handle 'q' only - if ( x < cmCursesMainForm::MIN_WIDTH || + if ( x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT ) { // quit @@ -100,7 +100,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, } else { - key=getch(); + key=getch(); continue; } } @@ -111,7 +111,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, return false; } // 10 == enter - if (key == 10 || key == KEY_ENTER) + if (key == 10 || key == KEY_ENTER) { this->OnReturn(fm, w); } @@ -121,7 +121,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, key == KEY_PPAGE || key == ctrl('u')) { this->InEdit = false; - delete[] this->OriginalString; + delete[] this->OriginalString; // trick to force forms to update the field buffer form_driver(form, REQ_NEXT_FIELD); form_driver(form, REQ_PREV_FIELD); @@ -136,8 +136,8 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, fm->PrintKeys(); this->SetString(this->OriginalString); delete[] this->OriginalString; - touchwin(w); - wrefresh(w); + touchwin(w); + wrefresh(w); return true; } } @@ -165,7 +165,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, { form_driver(form, REQ_END_FIELD); } - else if ( key == 127 || + else if ( key == 127 || key == KEY_BACKSPACE ) { if ( form->curcol > 0 ) @@ -186,10 +186,10 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm, } if ( !this->Done ) { - touchwin(w); - wrefresh(w); - - key=getch(); + touchwin(w); + wrefresh(w); + + key=getch(); } } return true; @@ -214,7 +214,7 @@ bool cmCursesStringWidget::PrintKeys() { int x,y; getmaxyx(stdscr, y, x); - if ( x < cmCursesMainForm::MIN_WIDTH || + if ( x < cmCursesMainForm::MIN_WIDTH || y < cmCursesMainForm::MIN_HEIGHT ) { return false; diff --git a/Source/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h index cd54f24..e939049 100644 --- a/Source/CursesDialog/cmCursesStringWidget.h +++ b/Source/CursesDialog/cmCursesStringWidget.h @@ -26,7 +26,7 @@ class cmCursesStringWidget : public cmCursesWidget { public: cmCursesStringWidget(int width, int height, int left, int top); - + /** * Handle user input. Called by the container of this widget * when this widget has focus. Returns true if the input was diff --git a/Source/CursesDialog/cmCursesWidget.h b/Source/CursesDialog/cmCursesWidget.h index ee36af6..952c67a 100644 --- a/Source/CursesDialog/cmCursesWidget.h +++ b/Source/CursesDialog/cmCursesWidget.h @@ -22,7 +22,7 @@ class cmCursesWidget public: cmCursesWidget(int width, int height, int left, int top); virtual ~cmCursesWidget(); - + /** * Handle user input. Called by the container of this widget * when this widget has focus. Returns true if the input was diff --git a/Source/CursesDialog/form/CMakeLists.txt b/Source/CursesDialog/form/CMakeLists.txt index 2435f393..4e07fa0 100644 --- a/Source/CursesDialog/form/CMakeLists.txt +++ b/Source/CursesDialog/form/CMakeLists.txt @@ -9,14 +9,14 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -PROJECT(CMAKE_FORM) +project(CMAKE_FORM) -INCLUDE_REGULAR_EXPRESSION("^.*$") -INCLUDE_DIRECTORIES(${CURSES_INCLUDE_PATH} "${CMAKE_CURRENT_BINARY_DIR}") +include_regular_expression("^.*$") +include_directories(${CURSES_INCLUDE_PATH} "${CMAKE_CURRENT_BINARY_DIR}") -CONFIGURE_FILE(cmFormConfigure.h.in "${CMAKE_CURRENT_BINARY_DIR}/cmFormConfigure.h") +configure_file(cmFormConfigure.h.in "${CMAKE_CURRENT_BINARY_DIR}/cmFormConfigure.h") -SET( FORM_SRCS +set( FORM_SRCS fld_arg.c fld_attr.c fld_current.c @@ -58,9 +58,9 @@ SET( FORM_SRCS fty_regex.c ) -INCLUDE_DIRECTORIES(${CMAKE_FORM_SOURCE_DIR}) -ADD_LIBRARY(cmForm ${FORM_SRCS} ) -TARGET_LINK_LIBRARIES(cmForm ${CURSES_LIBRARY}) -IF(CURSES_EXTRA_LIBRARY) - TARGET_LINK_LIBRARIES(cmForm ${CURSES_EXTRA_LIBRARY}) -ENDIF(CURSES_EXTRA_LIBRARY) +include_directories(${CMAKE_FORM_SOURCE_DIR}) +add_library(cmForm ${FORM_SRCS} ) +target_link_libraries(cmForm ${CURSES_LIBRARY}) +if(CURSES_EXTRA_LIBRARY) + target_link_libraries(cmForm ${CURSES_EXTRA_LIBRARY}) +endif() diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index 00aaf69..e7fedc5 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -15,7 +15,7 @@ #include <QCompleter> static const int NumTypes = 4; -static const QString TypeStrings[NumTypes] = +static const QByteArray TypeStrings[NumTypes] = { "BOOL", "PATH", "FILEPATH", "STRING" }; static const QCMakeProperty::PropertyType Types[NumTypes] = { QCMakeProperty::BOOL, QCMakeProperty::PATH, diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 056e48e..29daffd 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -9,114 +9,131 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -PROJECT(QtDialog) -SET(QT_MIN_VERSION "4.4.0") -FIND_PACKAGE(Qt4 REQUIRED) -IF(NOT QT4_FOUND) - MESSAGE(SEND_ERROR "Failed to find Qt 4.4 or greater.") -ELSE(NOT QT4_FOUND) +project(QtDialog) +find_package(Qt5Widgets QUIET) +if (Qt5Widgets_FOUND) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + add_definitions(${Qt5Widgets_DEFINITONS}) + macro(qt4_wrap_ui) + qt5_wrap_ui(${ARGN}) + endmacro() + macro(qt4_wrap_cpp) + qt5_wrap_cpp(${ARGN}) + endmacro() + macro(qt4_add_resources) + qt5_add_resources(${ARGN}) + endmacro() + set(QT_LIBRARIES ${Qt5Widgets_LIBRARIES}) + # Remove this when the minimum version of Qt is 4.6. + add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0) +else() + set(QT_MIN_VERSION "4.4.0") + find_package(Qt4 REQUIRED) + if(NOT QT4_FOUND) + message(SEND_ERROR "Failed to find Qt 4.4 or greater.") + return() + endif() - INCLUDE(${QT_USE_FILE}) - SET(CMAKE_PACKAGE_QTGUI TRUE) - SET(SRCS - AddCacheEntry.cxx - AddCacheEntry.h - CMakeSetup.cxx - CMakeSetupDialog.cxx - CMakeSetupDialog.h - FirstConfigure.cxx - FirstConfigure.h - QCMake.cxx - QCMake.h - QCMakeCacheView.cxx - QCMakeCacheView.h - QCMakeWidgets.cxx - QCMakeWidgets.h - QMacInstallDialog.cxx - QMacInstallDialog.h - ) - QT4_WRAP_UI(UI_SRCS - CMakeSetupDialog.ui - Compilers.ui - CrossCompiler.ui - AddCacheEntry.ui - MacInstallDialog.ui - ) - QT4_WRAP_CPP(MOC_SRCS - AddCacheEntry.h - Compilers.h - CMakeSetupDialog.h - FirstConfigure.h - QCMake.h - QCMakeCacheView.h - QCMakeWidgets.h - QMacInstallDialog.h - ) - QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc) + include(${QT_USE_FILE}) +endif() - SET(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS}) - IF(Q_WS_WIN) - SET(SRCS ${SRCS} CMakeSetup.rc) - ENDIF(Q_WS_WIN) - IF(Q_WS_MAC) - SET(SRCS ${SRCS} CMakeSetup.icns) - SET(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns) - SET_SOURCE_FILES_PROPERTIES(CMakeSetup.icns PROPERTIES - MACOSX_PACKAGE_LOCATION Resources) - ENDIF(Q_WS_MAC) +set(SRCS + AddCacheEntry.cxx + AddCacheEntry.h + CMakeSetup.cxx + CMakeSetupDialog.cxx + CMakeSetupDialog.h + FirstConfigure.cxx + FirstConfigure.h + QCMake.cxx + QCMake.h + QCMakeCacheView.cxx + QCMakeCacheView.h + QCMakeWidgets.cxx + QCMakeWidgets.h + QMacInstallDialog.cxx + QMacInstallDialog.h + ) +QT4_WRAP_UI(UI_SRCS + CMakeSetupDialog.ui + Compilers.ui + CrossCompiler.ui + AddCacheEntry.ui + MacInstallDialog.ui + ) +QT4_WRAP_CPP(MOC_SRCS + AddCacheEntry.h + Compilers.h + CMakeSetupDialog.h + FirstConfigure.h + QCMake.h + QCMakeCacheView.h + QCMakeWidgets.h + QMacInstallDialog.h + ) +QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) +set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS}) +if(WIN32) + set(SRCS ${SRCS} CMakeSetup.rc) +endif() +if(APPLE) + set(SRCS ${SRCS} CMakeSetup.icns) + set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns) + set_source_files_properties(CMakeSetup.icns PROPERTIES + MACOSX_PACKAGE_LOCATION Resources) +endif() - ADD_EXECUTABLE(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS}) - TARGET_LINK_LIBRARIES(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES}) - IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) - IF(APPLE) - SET_TARGET_PROPERTIES(cmake-gui PROPERTIES - OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) - ENDIF(APPLE) - SET(CMAKE_INSTALL_DESTINATION_ARGS - BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") - ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) +set(CMAKE_INCLUDE_CURRENT_DIR ON) - INSTALL(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) +add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS}) +target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES}) - IF(UNIX) - # install a desktop file so CMake appears in the application start menu - # with an icon - INSTALL(FILES CMake.desktop DESTINATION share/applications ) - INSTALL(FILES CMakeSetup32.png DESTINATION share/pixmaps ) - INSTALL(FILES cmakecache.xml DESTINATION share/mime/packages ) - ENDIF(UNIX) +if(APPLE) + set_target_properties(cmake-gui PROPERTIES + OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) +endif() +set(CMAKE_INSTALL_DESTINATION_ARGS + BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") - IF(APPLE) - SET(CMAKE_POSTFLIGHT_SCRIPT - "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") - SET(CMAKE_POSTUPGRADE_SCRIPT - "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") - configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postflight.sh.in" - "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") - configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in" - "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") - INSTALL(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui - WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)") - ENDIF(APPLE) +install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) - if(APPLE OR WIN32) - # install rules for including 3rd party libs such as Qt - # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation - set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}") - if(APPLE) - set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}") - endif(APPLE) - install(CODE " - include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") - fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") - ") - endif(APPLE OR WIN32) +if(UNIX) + # install a desktop file so CMake appears in the application start menu + # with an icon + install(FILES CMake.desktop DESTINATION share/applications ) + install(FILES CMakeSetup32.png DESTINATION share/pixmaps ) + install(FILES cmakecache.xml DESTINATION share/mime/packages ) +endif() - CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" - "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) -ENDIF(NOT QT4_FOUND) +if(APPLE) + set(CMAKE_POSTFLIGHT_SCRIPT + "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") + set(CMAKE_POSTUPGRADE_SCRIPT + "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") + configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postflight.sh.in" + "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") + configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in" + "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") + install(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui + WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)") +endif() +if(APPLE OR WIN32) + # install rules for including 3rd party libs such as Qt + # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation + set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}") + if(APPLE) + set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}") + endif() + install(CODE " + include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS ON) + fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") + ") +endif() + +set(CMAKE_PACKAGE_QTGUI TRUE) +configure_file("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" + "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index b4f3d72..01893f5 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -99,15 +99,15 @@ int main(int argc, char** argv) } QApplication app(argc, argv); - + // clean out standard Qt paths for plugins, which we don't use anyway // when creating Mac bundles, it potentially causes problems foreach(QString p, QApplication::libraryPaths()) { QApplication::removeLibraryPath(p); } - - // if arg for install + + // if arg for install for(int i =0; i < argc; i++) { if(strcmp(argv[i], "--mac-install") == 0) @@ -117,7 +117,7 @@ int main(int argc, char** argv) return 0; } } - // tell the cmake library where cmake is + // tell the cmake library where cmake is QDir cmExecDir(QApplication::applicationDirPath()); #if defined(Q_OS_MAC) cmExecDir.cd("../../../"); @@ -125,13 +125,13 @@ int main(int argc, char** argv) // pick up translation files if they exists in the data directory QDir translationsDir = cmExecDir; - translationsDir.cd(".." CMAKE_DATA_DIR); + translationsDir.cd(QString::fromLocal8Bit(".." CMAKE_DATA_DIR)); translationsDir.cd("i18n"); QTranslator translator; QString transfile = QString("cmake_%1").arg(QLocale::system().name()); translator.load(transfile, translationsDir.path()); app.installTranslator(&translator); - + // app setup app.setApplicationName("CMakeSetup"); app.setOrganizationName("Kitware"); @@ -139,16 +139,16 @@ int main(int argc, char** argv) appIcon.addFile(":/Icons/CMakeSetup32.png"); appIcon.addFile(":/Icons/CMakeSetup128.png"); app.setWindowIcon(appIcon); - + CMakeSetupDialog dialog; dialog.show(); - + cmsys::CommandLineArguments arg; arg.Initialize(argc, argv); std::string binaryDirectory; std::string sourceDirectory; typedef cmsys::CommandLineArguments argT; - arg.AddArgument("-B", argT::CONCAT_ARGUMENT, + arg.AddArgument("-B", argT::CONCAT_ARGUMENT, &binaryDirectory, "Binary Directory"); arg.AddArgument("-H", argT::CONCAT_ARGUMENT, &sourceDirectory, "Source Directory"); @@ -157,15 +157,15 @@ int main(int argc, char** argv) arg.Parse(); if(!sourceDirectory.empty() && !binaryDirectory.empty()) { - dialog.setSourceDirectory(sourceDirectory.c_str()); - dialog.setBinaryDirectory(binaryDirectory.c_str()); + dialog.setSourceDirectory(QString::fromLocal8Bit(sourceDirectory.c_str())); + dialog.setBinaryDirectory(QString::fromLocal8Bit(binaryDirectory.c_str())); } else { QStringList args = app.arguments(); if(args.count() == 2) { - cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toAscii().data()); + cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data()); // check if argument is a directory containing CMakeCache.txt cmsys_stl::string buildFilePath = @@ -184,16 +184,22 @@ int main(int argc, char** argv) if(cmSystemTools::FileExists(buildFilePath.c_str())) { - dialog.setBinaryDirectory(cmSystemTools::GetFilenamePath(buildFilePath).c_str()); + dialog.setBinaryDirectory( + QString::fromLocal8Bit( + cmSystemTools::GetFilenamePath(buildFilePath).c_str() + ) + ); } else if(cmSystemTools::FileExists(srcFilePath.c_str())) { - dialog.setSourceDirectory(filePath.c_str()); - dialog.setBinaryDirectory(cmSystemTools::CollapseFullPath(".").c_str()); + dialog.setSourceDirectory(QString::fromLocal8Bit(filePath.c_str())); + dialog.setBinaryDirectory( + QString::fromLocal8Bit(cmSystemTools::CollapseFullPath(".").c_str()) + ); } } } - + return app.exec(); } diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 5cd4f29..c0dde1c 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -299,9 +299,8 @@ bool CMakeSetupDialog::prepareConfigure() if(!dir.exists()) { QString msg = tr("Build directory does not exist, " - "should I create it?") - + "\n\n" - + tr("Directory: "); + "should I create it?\n\n" + "Directory: "); msg += bindir; QString title = tr("Create Directory"); QMessageBox::StandardButton btn; @@ -490,9 +489,9 @@ void CMakeSetupDialog::closeEvent(QCloseEvent* e) // don't close if we're busy, unless the user really wants to if(this->CurrentState == Configuring) { - QString msg = "You are in the middle of a Configure.\n" + QString msg = tr("You are in the middle of a Configure.\n" "If you Exit now the configure information will be lost.\n" - "Are you sure you want to Exit?"; + "Are you sure you want to Exit?"); QString title = tr("Confirm Exit"); QMessageBox::StandardButton btn; btn = QMessageBox::critical(this, title, msg, @@ -715,33 +714,33 @@ bool CMakeSetupDialog::setupFirstConfigure() QString mode = dialog.getCrossIncludeMode(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE", - "CMake Find Include Mode", mode, false); + tr("CMake Find Include Mode"), mode, false); mode = dialog.getCrossLibraryMode(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY", - "CMake Find Library Mode", mode, false); + tr("CMake Find Library Mode"), mode, false); mode = dialog.getCrossProgramMode(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM", - "CMake Find Program Mode", mode, false); + tr("CMake Find Program Mode"), mode, false); QString rootPath = dialog.getCrossRoot(); m->insertProperty(QCMakeProperty::PATH, "CMAKE_FIND_ROOT_PATH", - "CMake Find Root Path", rootPath, false); + tr("CMake Find Root Path"), rootPath, false); QString systemName = dialog.getSystemName(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME", - "CMake System Name", systemName, false); + tr("CMake System Name"), systemName, false); QString cxxCompiler = dialog.getCXXCompiler(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER", - "CXX compiler.", cxxCompiler, false); + tr("CXX compiler."), cxxCompiler, false); QString cCompiler = dialog.getCCompiler(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER", - "C compiler.", cCompiler, false); + tr("C compiler."), cCompiler, false); } else if(dialog.crossCompilerToolChainFile()) { QString toolchainFile = dialog.getCrossCompilerToolChainFile(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE", - "Cross Compile ToolChain File", toolchainFile, false); + tr("Cross Compile ToolChain File"), toolchainFile, false); } return true; } @@ -772,7 +771,7 @@ void CMakeSetupDialog::doReloadCache() void CMakeSetupDialog::doDeleteCache() { QString title = tr("Delete Cache"); - QString msg = "Are you sure you want to delete the cache?"; + QString msg = tr("Are you sure you want to delete the cache?"); QMessageBox::StandardButton btn; btn = QMessageBox::information(this, title, msg, QMessageBox::Yes | QMessageBox::No); @@ -786,9 +785,9 @@ void CMakeSetupDialog::doDeleteCache() void CMakeSetupDialog::doAbout() { - QString msg = "CMake %1\n" + QString msg = tr("CMake %1\n" "Using Qt %2\n" - "www.cmake.org"; + "www.cmake.org"); msg = msg.arg(cmVersion::GetCMakeVersion()); msg = msg.arg(qVersion()); diff --git a/Source/QtDialog/Compilers.h b/Source/QtDialog/Compilers.h index e9c90a5..3f7b834 100644 --- a/Source/QtDialog/Compilers.h +++ b/Source/QtDialog/Compilers.h @@ -10,7 +10,7 @@ class Compilers : public QWidget, public Ui::Compilers { Q_OBJECT public: - Compilers(QWidget* p=NULL) : + Compilers(QWidget* p=NULL) : QWidget(p) { this->setupUi(this); diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index f522760..6de9f00 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -17,15 +17,15 @@ StartCompilerSetup::StartCompilerSetup(QWidget* p) l->addWidget(this->GeneratorOptions); l->addSpacing(6); - this->CompilerSetupOptions[0] = new QRadioButton("Use default native compilers", this); - this->CompilerSetupOptions[1] = new QRadioButton("Specify native compilers", this); - this->CompilerSetupOptions[2] = new QRadioButton("Specify toolchain file for cross-compiling", this); - this->CompilerSetupOptions[3] = new QRadioButton("Specify options for cross-compiling", this); + this->CompilerSetupOptions[0] = new QRadioButton(tr("Use default native compilers"), this); + this->CompilerSetupOptions[1] = new QRadioButton(tr("Specify native compilers"), this); + this->CompilerSetupOptions[2] = new QRadioButton(tr("Specify toolchain file for cross-compiling"), this); + this->CompilerSetupOptions[3] = new QRadioButton(tr("Specify options for cross-compiling"), this); l->addWidget(this->CompilerSetupOptions[0]); l->addWidget(this->CompilerSetupOptions[1]); l->addWidget(this->CompilerSetupOptions[2]); l->addWidget(this->CompilerSetupOptions[3]); - + this->CompilerSetupOptions[0]->setChecked(true); QObject::connect(this->CompilerSetupOptions[0], SIGNAL(toggled(bool)), @@ -47,7 +47,7 @@ void StartCompilerSetup::setGenerators(const QStringList& gens) this->GeneratorOptions->clear(); this->GeneratorOptions->addItems(gens); }; - + void StartCompilerSetup::setCurrentGenerator(const QString& gen) { int idx = this->GeneratorOptions->findText(gen); @@ -159,9 +159,9 @@ CrossCompilerSetup::CrossCompilerSetup(QWidget* p) // fill in combo boxes QStringList modes; - modes << "Search in Target Root, then native system"; - modes << "Search only in Target Root"; - modes << "Search only in native system"; + modes << tr("Search in Target Root, then native system"); + modes << tr("Search only in Target Root"); + modes << tr("Search only in native system"); crossProgramMode->addItems(modes); crossLibraryMode->addItems(modes); crossIncludeMode->addItems(modes); @@ -237,7 +237,7 @@ void CrossCompilerSetup::setProcessor(const QString& t) { this->systemProcessor->setText(t); } - + QString CrossCompilerSetup::getFindRoot() const { return this->crossFindRoot->text(); @@ -313,10 +313,10 @@ FirstConfigure::FirstConfigure() this->mNativeCompilerSetupPage = new NativeCompilerSetup(this); this->setPage(NativeSetup, this->mNativeCompilerSetupPage); - + this->mCrossCompilerSetupPage = new CrossCompilerSetup(this); this->setPage(CrossSetup, this->mCrossCompilerSetupPage); - + this->mToolchainCompilerSetupPage = new ToolchainCompilerSetup(this); this->setPage(ToolchainSetup, this->mToolchainCompilerSetupPage); } @@ -370,14 +370,14 @@ void FirstConfigure::loadFromSettings() void FirstConfigure::saveToSettings() { QSettings settings; - + // save generator settings.beginGroup("Settings/StartPath"); QString lastGen = this->mStartCompilerSetupPage->getGenerator(); settings.setValue("LastGenerator", lastGen); settings.endGroup(); - // save compiler setup + // save compiler setup settings.beginGroup("Settings/Compiler"); settings.setValue("CCompiler", this->mNativeCompilerSetupPage->getCCompiler()); settings.setValue("CXXCompiler", this->mNativeCompilerSetupPage->getCXXCompiler()); @@ -419,7 +419,7 @@ bool FirstConfigure::crossCompilerToolChainFile() const { return this->mStartCompilerSetupPage->crossCompilerToolChainFile(); } - + QString FirstConfigure::getCrossCompilerToolChainFile() const { return this->mToolchainCompilerSetupPage->toolchainFile(); diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h index f4e368b..be390b0 100644 --- a/Source/QtDialog/FirstConfigure.h +++ b/Source/QtDialog/FirstConfigure.h @@ -30,14 +30,14 @@ class StartCompilerSetup : public QWizardPage void setGenerators(const QStringList& gens); void setCurrentGenerator(const QString& gen); QString getGenerator() const; - + bool defaultSetup() const; bool compilerSetup() const; bool crossCompilerSetup() const; bool crossCompilerToolChainFile() const; int nextId() const; - + signals: void selectionChanged(); @@ -56,7 +56,7 @@ class NativeCompilerSetup : public QWizardPage, protected Ui::Compilers public: NativeCompilerSetup(QWidget* p); ~NativeCompilerSetup(); - + QString getCCompiler() const; void setCCompiler(const QString&); @@ -65,7 +65,7 @@ class NativeCompilerSetup : public QWizardPage, protected Ui::Compilers QString getFortranCompiler() const; void setFortranCompiler(const QString&); - + int nextId() const { return -1; } }; @@ -76,13 +76,13 @@ class CrossCompilerSetup : public QWizardPage, protected Ui::CrossCompiler public: CrossCompilerSetup(QWidget* p); ~CrossCompilerSetup(); - + QString getSystem() const; void setSystem(const QString&); - + QString getVersion() const; void setVersion(const QString&); - + QString getProcessor() const; void setProcessor(const QString&); @@ -94,7 +94,7 @@ class CrossCompilerSetup : public QWizardPage, protected Ui::CrossCompiler QString getFortranCompiler() const; void setFortranCompiler(const QString&); - + QString getFindRoot() const; void setFindRoot(const QString&); @@ -104,14 +104,14 @@ class CrossCompilerSetup : public QWizardPage, protected Ui::CrossCompiler ONLY, NEVER }; - + int getProgramMode() const; void setProgramMode(int); int getLibraryMode() const; void setLibraryMode(int); int getIncludeMode() const; void setIncludeMode(int); - + int nextId() const { return -1; } }; @@ -127,7 +127,7 @@ class ToolchainCompilerSetup : public QWizardPage void setToolchainFile(const QString&); int nextId() const { return -1; } - + protected: QCMakeFilePathEditor* ToolchainFile; }; @@ -151,7 +151,7 @@ public: QString getCCompiler() const; QString getCXXCompiler() const; QString getFortranCompiler() const; - + QString getSystemName() const; QString getSystemVersion() const; QString getSystemProcessor() const; @@ -159,7 +159,7 @@ public: QString getCrossProgramMode() const; QString getCrossLibraryMode() const; QString getCrossIncludeMode() const; - + QString getCrossCompilerToolChainFile() const; void loadFromSettings(); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 73050f3..0d01181 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -32,9 +32,9 @@ QCMake::QCMake(QObject* p) this->WarnUnusedMode = false; qRegisterMetaType<QCMakeProperty>(); qRegisterMetaType<QCMakePropertyList>(); - + QDir execDir(QCoreApplication::applicationDirPath()); - + #if defined(Q_OS_MAC) if(execDir.exists("../bin/cmake")) { @@ -45,20 +45,20 @@ QCMake::QCMake(QObject* p) execDir.cd("../../../"); // path to cmake in build directory (need to fix for deployment) } #endif - - QString cmakeCommand = QString("cmake")+cmSystemTools::GetExecutableExtension(); + + QString cmakeCommand = QString("cmake")+QString::fromLocal8Bit(cmSystemTools::GetExecutableExtension()); cmakeCommand = execDir.filePath(cmakeCommand); cmSystemTools::DisableRunCommandOutput(); cmSystemTools::SetRunCommandHideConsole(true); cmSystemTools::SetErrorCallback(QCMake::errorCallback, this); - cmSystemTools::FindExecutableDirectory(cmakeCommand.toAscii().data()); + cmSystemTools::FindExecutableDirectory(cmakeCommand.toLocal8Bit().data()); this->CMakeInstance = new cmake; - this->CMakeInstance->SetCMakeCommand(cmakeCommand.toAscii().data()); + this->CMakeInstance->SetCMakeCommand(cmakeCommand.toLocal8Bit().data()); #if defined(Q_OS_MAC) this->CMakeInstance->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui"); -#else +#else this->CMakeInstance->SetCMakeEditCommand("cmake-gui"); #endif this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this); @@ -79,7 +79,7 @@ QCMake::QCMake(QObject* p) { continue; } - this->AvailableGenerators.append(iter->c_str()); + this->AvailableGenerators.append(QString::fromLocal8Bit(iter->c_str())); } } @@ -96,8 +96,8 @@ void QCMake::loadCache(const QString& dir) void QCMake::setSourceDirectory(const QString& _dir) { - QString dir = - cmSystemTools::GetActualCaseForPath(_dir.toAscii().data()).c_str(); + QString dir = + QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str()); if(this->SourceDirectory != dir) { this->SourceDirectory = QDir::fromNativeSeparators(dir); @@ -107,8 +107,8 @@ void QCMake::setSourceDirectory(const QString& _dir) void QCMake::setBinaryDirectory(const QString& _dir) { - QString dir = - cmSystemTools::GetActualCaseForPath(_dir.toAscii().data()).c_str(); + QString dir = + QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str()); if(this->BinaryDirectory != dir) { this->BinaryDirectory = QDir::fromNativeSeparators(dir); @@ -126,20 +126,20 @@ void QCMake::setBinaryDirectory(const QString& _dir) "Please check the permissions of the directory you are trying to run CMake on."); } } - + QCMakePropertyList props = this->properties(); emit this->propertiesChanged(props); cmCacheManager::CacheIterator itm = cachem->NewIterator(); if ( itm.Find("CMAKE_HOME_DIRECTORY")) { - setSourceDirectory(itm.GetValue()); + setSourceDirectory(QString::fromLocal8Bit(itm.GetValue())); } if ( itm.Find("CMAKE_GENERATOR")) { const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR"); std::string curGen = cmExternalMakefileProjectGenerator:: CreateFullGeneratorName(itm.GetValue(), extraGen); - this->setGenerator(curGen.c_str()); + this->setGenerator(QString::fromLocal8Bit(curGen.c_str())); } } } @@ -160,12 +160,12 @@ void QCMake::configure() UINT lastErrorMode = SetErrorMode(0); #endif - this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toAscii().data()); - this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toAscii().data()); - this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toAscii().data()); - this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toLocal8Bit().data()); this->CMakeInstance->SetGlobalGenerator( - this->CMakeInstance->CreateGlobalGenerator(this->Generator.toAscii().data())); + this->CMakeInstance->CreateGlobalGenerator(this->Generator.toLocal8Bit().data())); this->CMakeInstance->LoadCache(); this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings); this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode); @@ -202,7 +202,7 @@ void QCMake::generate() emit this->generateDone(err); } - + void QCMake::setProperties(const QCMakePropertyList& newProps) { QCMakePropertyList props = newProps; @@ -222,11 +222,11 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) } QCMakeProperty prop; - prop.Key = i.GetName(); + prop.Key = QString::fromLocal8Bit(i.GetName()); int idx = props.indexOf(prop); if(idx == -1) { - toremove.append(i.GetName()); + toremove.append(QString::fromLocal8Bit(i.GetName())); } else { @@ -237,7 +237,7 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) } else { - i.SetValue(prop.Value.toString().toAscii().data()); + i.SetValue(prop.Value.toString().toLocal8Bit().data()); } props.removeAt(idx); } @@ -247,47 +247,47 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) // remove some properites foreach(QString s, toremove) { - this->CMakeInstance->UnwatchUnusedCli(s.toAscii().data()); + this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data()); - cachem->RemoveCacheEntry(s.toAscii().data()); + cachem->RemoveCacheEntry(s.toLocal8Bit().data()); } - + // add some new properites foreach(QCMakeProperty s, props) { - this->CMakeInstance->WatchUnusedCli(s.Key.toAscii().data()); + this->CMakeInstance->WatchUnusedCli(s.Key.toLocal8Bit().data()); if(s.Type == QCMakeProperty::BOOL) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), s.Value.toBool() ? "ON" : "OFF", - s.Help.toAscii().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::BOOL); } else if(s.Type == QCMakeProperty::STRING) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), - s.Value.toString().toAscii().data(), - s.Help.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::STRING); } else if(s.Type == QCMakeProperty::PATH) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), - s.Value.toString().toAscii().data(), - s.Help.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::PATH); } else if(s.Type == QCMakeProperty::FILEPATH) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), - s.Value.toString().toAscii().data(), - s.Help.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::FILEPATH); } } - - cachem->SaveCache(this->BinaryDirectory.toAscii().data()); + + cachem->SaveCache(this->BinaryDirectory.toLocal8Bit().data()); } QCMakePropertyList QCMake::properties() const @@ -307,9 +307,9 @@ QCMakePropertyList QCMake::properties() const } QCMakeProperty prop; - prop.Key = i.GetName(); - prop.Help = i.GetProperty("HELPSTRING"); - prop.Value = i.GetValue(); + prop.Key = QString::fromLocal8Bit(i.GetName()); + prop.Help = QString::fromLocal8Bit(i.GetProperty("HELPSTRING")); + prop.Value = QString::fromLocal8Bit(i.GetValue()); prop.Advanced = i.GetPropertyAsBool("ADVANCED"); if(i.GetType() == cmCacheManager::BOOL) @@ -330,7 +330,7 @@ QCMakePropertyList QCMake::properties() const prop.Type = QCMakeProperty::STRING; if (i.PropertyExists("STRINGS")) { - prop.Strings = QString(i.GetProperty("STRINGS")).split(";"); + prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";"); } } @@ -339,7 +339,7 @@ QCMakePropertyList QCMake::properties() const return ret; } - + void QCMake::interrupt() { this->InterruptFlag.ref(); @@ -348,7 +348,11 @@ void QCMake::interrupt() bool QCMake::interruptCallback(void* cd) { QCMake* self = reinterpret_cast<QCMake*>(cd); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) return self->InterruptFlag; +#else + return self->InterruptFlag.load(); +#endif } void QCMake::progressCallback(const char* msg, float percent, void* cd) @@ -356,11 +360,11 @@ void QCMake::progressCallback(const char* msg, float percent, void* cd) QCMake* self = reinterpret_cast<QCMake*>(cd); if(percent >= 0) { - emit self->progressChanged(msg, percent); + emit self->progressChanged(QString::fromLocal8Bit(msg), percent); } else { - emit self->outputMessage(msg); + emit self->outputMessage(QString::fromLocal8Bit(msg)); } QCoreApplication::processEvents(); } @@ -369,7 +373,7 @@ void QCMake::errorCallback(const char* msg, const char* /*title*/, bool& /*stop*/, void* cd) { QCMake* self = reinterpret_cast<QCMake*>(cd); - emit self->errorMessage(msg); + emit self->errorMessage(QString::fromLocal8Bit(msg)); QCoreApplication::processEvents(); } @@ -396,9 +400,9 @@ QStringList QCMake::availableGenerators() const void QCMake::deleteCache() { // delete cache - this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data()); // reload to make our cache empty - this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); // emit no generator and no properties this->setGenerator(QString()); QCMakePropertyList props = this->properties(); @@ -411,12 +415,12 @@ void QCMake::reloadCache() QCMakePropertyList props; emit this->propertiesChanged(props); // reload - this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); // emit new cache properties props = this->properties(); emit this->propertiesChanged(props); } - + void QCMake::setDebugOutput(bool flag) { if(flag != this->CMakeInstance->GetDebugOutput()) diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index 0d68586..93ac8ab 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -38,12 +38,12 @@ struct QCMakeProperty QString Help; PropertyType Type; bool Advanced; - bool operator==(const QCMakeProperty& other) const - { + bool operator==(const QCMakeProperty& other) const + { return this->Key == other.Key; } - bool operator<(const QCMakeProperty& other) const - { + bool operator<(const QCMakeProperty& other) const + { return this->Key < other.Key; } }; @@ -56,7 +56,7 @@ Q_DECLARE_METATYPE(QCMakeProperty) Q_DECLARE_METATYPE(QCMakePropertyList) /// Qt API for CMake library. -/// Wrapper like class allows for easier integration with +/// Wrapper like class allows for easier integration with /// Qt features such as, signal/slot connections, multi-threading, etc.. class QCMake : public QObject { @@ -136,7 +136,7 @@ protected: static bool interruptCallback(void*); static void progressCallback(const char* msg, float percent, void* cd); - static void errorCallback(const char* msg, const char* title, + static void errorCallback(const char* msg, const char* title, bool&, void* cd); bool SuppressDevWarnings; bool WarnUninitializedMode; diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 72e9b24..1d21d42 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -64,7 +64,7 @@ protected: return true; } } - + return false; } }; @@ -73,11 +73,11 @@ protected: class QCMakeAdvancedFilter : public QSortFilterProxyModel { public: - QCMakeAdvancedFilter(QObject* o) + QCMakeAdvancedFilter(QObject* o) : QSortFilterProxyModel(o), ShowAdvanced(false) {} - void setShowAdvanced(bool f) - { + void setShowAdvanced(bool f) + { this->ShowAdvanced = f; this->invalidate(); } @@ -102,7 +102,7 @@ protected: } return false; } - + // check children int num = m->rowCount(idx); for(int i=0; i<num; i++) @@ -134,9 +134,9 @@ QCMakeCacheView::QCMakeCacheView(QWidget* p) // our delegate for creating our editors QCMakeCacheModelDelegate* delegate = new QCMakeCacheModelDelegate(this); this->setItemDelegate(delegate); - + this->setUniformRowHeights(true); - + this->setEditTriggers(QAbstractItemView::AllEditTriggers); // tab, backtab doesn't step through items @@ -153,13 +153,13 @@ bool QCMakeCacheView::event(QEvent* e) } return QTreeView::event(e); } - + QCMakeCacheModel* QCMakeCacheView::cacheModel() const { return this->CacheModel; } - -QModelIndex QCMakeCacheView::moveCursor(CursorAction act, + +QModelIndex QCMakeCacheView::moveCursor(CursorAction act, Qt::KeyboardModifiers mod) { // want home/end to go to begin/end of rows, not columns @@ -173,7 +173,7 @@ QModelIndex QCMakeCacheView::moveCursor(CursorAction act, } return QTreeView::moveCursor(act, mod); } - + void QCMakeCacheView::setShowAdvanced(bool s) { #if QT_VERSION >= 040300 @@ -224,7 +224,7 @@ void QCMakeCacheModel::clear() { this->QStandardItemModel::clear(); this->NewPropertyCount = 0; - + QStringList labels; labels << tr("Name") << tr("Value"); this->setHorizontalHeaderLabels(labels); @@ -281,7 +281,7 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props) this->breakProperties(newProps2, newPropsTree2); QStandardItem* root = this->invisibleRootItem(); - + foreach(QString key, newPropsTree.keys()) { QCMakePropertyList props2 = newPropsTree[key]; @@ -308,12 +308,12 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props) this->setPropertyData(this->indexFromItem(items[0]), prop, true); } } - + foreach(QString key, newPropsTree2.keys()) { QCMakePropertyList props2 = newPropsTree2[key]; - QStandardItem* parentItem = + QStandardItem* parentItem = new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key); root->appendRow(parentItem); parentItem->setData(1, GroupRole); @@ -330,7 +330,7 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props) } } } - + this->blockSignals(b); this->reset(); } @@ -361,7 +361,7 @@ void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t) this->reset(); } -void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1, +void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1, const QCMakeProperty& prop, bool isNew) { QModelIndex idx2 = idx1.sibling(idx1.row(), 1); @@ -370,7 +370,7 @@ void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1, this->setData(idx1, prop.Help, QCMakeCacheModel::HelpRole); this->setData(idx1, prop.Type, QCMakeCacheModel::TypeRole); this->setData(idx1, prop.Advanced, QCMakeCacheModel::AdvancedRole); - + if(prop.Type == QCMakeProperty::BOOL) { int check = prop.Value.toBool() ? Qt::Checked : Qt::Unchecked; @@ -394,7 +394,7 @@ void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1, } } -void QCMakeCacheModel::getPropertyData(const QModelIndex& idx1, +void QCMakeCacheModel::getPropertyData(const QModelIndex& idx1, QCMakeProperty& prop) const { QModelIndex idx2 = idx1.sibling(idx1.row(), 1); @@ -457,7 +457,7 @@ void QCMakeCacheModel::breakProperties(const QSet<QCMakeProperty>& props, } result = tmp; } - + QCMakePropertyList QCMakeCacheModel::properties() const { QCMakePropertyList props; @@ -488,7 +488,7 @@ QCMakePropertyList QCMakeCacheModel::properties() const this->getPropertyData(idx, prop); props.append(prop); } - + // go to the next in the tree while(!idxs.isEmpty() && !idxs.last().sibling(idxs.last().row()+1, 0).isValid()) { @@ -503,7 +503,7 @@ QCMakePropertyList QCMakeCacheModel::properties() const return props; } - + bool QCMakeCacheModel::insertProperty(QCMakeProperty::PropertyType t, const QString& name, const QString& description, const QVariant& value, bool advanced) @@ -554,7 +554,7 @@ Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& idx) const QModelIndex QCMakeCacheModel::buddy(const QModelIndex& idx) const { - if(!this->hasChildren(idx) && + if(!this->hasChildren(idx) && this->data(idx, TypeRole).toInt() != QCMakeProperty::BOOL) { return this->index(idx.row(), 1, idx.parent()); @@ -572,7 +572,7 @@ void QCMakeCacheModelDelegate::setFileDialogFlag(bool f) this->FileDialogFlag = f; } -QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, +QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, const QStyleOptionViewItem&, const QModelIndex& idx) const { QModelIndex var = idx.sibling(idx.row(), 0); @@ -584,7 +584,7 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, else if(type == QCMakeProperty::PATH) { QCMakePathEditor* editor = - new QCMakePathEditor(p, + new QCMakePathEditor(p, var.data(Qt::DisplayRole).toString()); QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this, SLOT(setFileDialogFlag(bool))); @@ -593,7 +593,7 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, else if(type == QCMakeProperty::FILEPATH) { QCMakeFilePathEditor* editor = - new QCMakeFilePathEditor(p, + new QCMakeFilePathEditor(p, var.data(Qt::DisplayRole).toString()); QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this, SLOT(setFileDialogFlag(bool))); @@ -602,7 +602,7 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, else if(type == QCMakeProperty::STRING && var.data(QCMakeCacheModel::StringsRole).isValid()) { - QCMakeComboBox* editor = + QCMakeComboBox* editor = new QCMakeComboBox(p, var.data(QCMakeCacheModel::StringsRole).toStringList()); editor->setFrame(false); return editor; @@ -613,7 +613,7 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, return editor; } -bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, +bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) { Qt::ItemFlags flags = model->flags(index); @@ -637,7 +637,7 @@ bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, { return true; } - } + } else if (e->type() == QEvent::KeyPress) { if(static_cast<QKeyEvent*>(e)->key() != Qt::Key_Space && @@ -645,8 +645,8 @@ bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, { return false; } - } - else + } + else { return false; } @@ -660,7 +660,7 @@ bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, } return success; } - + // Issue 205903 fixed in Qt 4.5.0. // Can remove this function and FileDialogFlag when minimum Qt version is 4.5 bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt) @@ -682,7 +682,7 @@ void QCMakeCacheModelDelegate::setModelData(QWidget* editor, QItemDelegate::setModelData(editor, model, index); const_cast<QCMakeCacheModelDelegate*>(this)->recordChange(model, index); } - + QSize QCMakeCacheModelDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize sz = QItemDelegate::sizeHint(option, index); @@ -695,7 +695,7 @@ QSize QCMakeCacheModelDelegate::sizeHint(const QStyleOptionViewItem& option, con return sz; } - + QSet<QCMakeProperty> QCMakeCacheModelDelegate::changes() const { return mChanges; @@ -721,7 +721,7 @@ void QCMakeCacheModelDelegate::recordChange(QAbstractItemModel* model, const QMo QCMakeProperty prop; idx = idx.sibling(idx.row(), 0); cache_model->getPropertyData(idx, prop); - + // clean out an old one QSet<QCMakeProperty>::iterator iter = mChanges.find(prop); if(iter != mChanges.end()) diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h index 0a628b9..41f0bd8 100644 --- a/Source/QtDialog/QCMakeCacheView.h +++ b/Source/QtDialog/QCMakeCacheView.h @@ -33,7 +33,7 @@ public: // retrieve the QCMakeCacheModel storing all the pointers // this isn't necessarily the model one would get from model() QCMakeCacheModel* cacheModel() const; - + // get whether to show advanced entries bool showAdvanced() const; @@ -65,7 +65,7 @@ public: // roles used to retrieve extra data such has help strings, types of // properties, and the advanced flag enum { HelpRole = Qt::ToolTipRole, - TypeRole = Qt::UserRole, + TypeRole = Qt::UserRole, AdvancedRole, StringsRole, GroupRole @@ -102,7 +102,7 @@ public slots: public: // get the properties QCMakePropertyList properties() const; - + // editing enabled bool editEnabled() const; @@ -112,7 +112,7 @@ public: // return flags (overloaded to modify flag based on EditEnabled flag) Qt::ItemFlags flags (const QModelIndex& index) const; QModelIndex buddy(const QModelIndex& idx) const; - + // get the data in the model for this property void getPropertyData(const QModelIndex& idx1, QCMakeProperty& prop) const; @@ -124,20 +124,20 @@ protected: ViewType View; // set the data in the model for this property - void setPropertyData(const QModelIndex& idx1, + void setPropertyData(const QModelIndex& idx1, const QCMakeProperty& p, bool isNew); // breaks up he property list into groups // where each group has the same prefix up to the first underscore static void breakProperties(const QSet<QCMakeProperty>& props, QMap<QString, QCMakePropertyList>& result); - + // gets the prefix of a string up to the first _ static QString prefix(const QString& s); }; -/// Qt delegate class for interaction (or other customization) +/// Qt delegate class for interaction (or other customization) /// with cache properties class QCMakeCacheModelDelegate : public QItemDelegate { @@ -145,9 +145,9 @@ class QCMakeCacheModelDelegate : public QItemDelegate public: QCMakeCacheModelDelegate(QObject* p); /// create our own editors for cache properties - QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - bool editorEvent (QEvent* event, QAbstractItemModel* model, + bool editorEvent (QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index); bool eventFilter(QObject* object, QEvent* event); void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const; diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx index 144e1f3..a0c5e17 100644 --- a/Source/QtDialog/QCMakeWidgets.cxx +++ b/Source/QtDialog/QCMakeWidgets.cxx @@ -69,7 +69,7 @@ void QCMakeFilePathEditor::chooseFile() this->fileDialogExists(true); path = QFileDialog::getOpenFileName(this, title, info.absolutePath()); this->fileDialogExists(false); - + if(!path.isEmpty()) { this->setText(QDir::fromNativeSeparators(path)); diff --git a/Source/QtDialog/QMacInstallDialog.cxx b/Source/QtDialog/QMacInstallDialog.cxx index 3aa509d..8b8c531 100644 --- a/Source/QtDialog/QMacInstallDialog.cxx +++ b/Source/QtDialog/QMacInstallDialog.cxx @@ -15,11 +15,11 @@ QMacInstallDialog::QMacInstallDialog(QWidget*w) { this->Internals = new QMacInstallDialogInternals; this->Internals->setupUi(this); - QObject::connect(this->Internals->choosePathButton, SIGNAL(pressed()), + QObject::connect(this->Internals->choosePathButton, SIGNAL(pressed()), this, SLOT(ShowBrowser())); - QObject::connect(this->Internals->skipInstallButton, SIGNAL(pressed()), + QObject::connect(this->Internals->skipInstallButton, SIGNAL(pressed()), this, SLOT(SkipInstall())); - QObject::connect(this->Internals->doInstallButton, SIGNAL(pressed()), + QObject::connect(this->Internals->doInstallButton, SIGNAL(pressed()), this, SLOT(DoInstall())); this->Internals->InstallPrefix->setText("/usr/bin/"); @@ -31,29 +31,28 @@ QMacInstallDialog::~QMacInstallDialog() } void QMacInstallDialog::DoInstall() -{ +{ QDir installDir(this->Internals->InstallPrefix->text()); QString installTo = installDir.path(); - if(!cmSystemTools::FileExists(installTo.toAscii().data())) + if(!cmSystemTools::FileExists(installTo.toLocal8Bit().data())) { QString message = tr("Build install does not exist, " - "should I create it?") - + "\n\n" - + tr("Directory: "); + "should I create it?\n\n" + "Directory: "); message += installDir.path(); QString title = tr("Create Directory"); QMessageBox::StandardButton btn; - btn = QMessageBox::information(this, title, message, + btn = QMessageBox::information(this, title, message, QMessageBox::Yes | QMessageBox::No); if(btn == QMessageBox::Yes) { - cmSystemTools::MakeDirectory(installTo.toAscii().data()); + cmSystemTools::MakeDirectory(installTo.toLocal8Bit().data()); } } QDir cmExecDir(QApplication::applicationDirPath()); cmExecDir.cd("../bin"); QFileInfoList list = cmExecDir.entryInfoList(); - for (int i = 0; i < list.size(); ++i) + for (int i = 0; i < list.size(); ++i) { QFileInfo fileInfo = list.at(i); QString filename = fileInfo.fileName(); @@ -66,17 +65,17 @@ void QMacInstallDialog::DoInstall() newName += "/"; newName += filename; // Remove the old files - if(cmSystemTools::FileExists(newName.toAscii().data())) + if(cmSystemTools::FileExists(newName.toLocal8Bit().data())) { - std::cout << "rm [" << newName.toAscii().data() << "]\n"; - if(!cmSystemTools::RemoveFile(newName.toAscii().data())) + std::cout << "rm [" << newName.toLocal8Bit().data() << "]\n"; + if(!cmSystemTools::RemoveFile(newName.toLocal8Bit().data())) { QString message = tr("Failed to remove file " "installation may be incomplete: "); - message += newName.toAscii().data(); + message += newName; QString title = tr("Error Removing file"); QMessageBox::StandardButton btn = - QMessageBox::critical(this, title, message, + QMessageBox::critical(this, title, message, QMessageBox::Ok|QMessageBox::Abort); if(btn == QMessageBox::Abort) { @@ -84,17 +83,17 @@ void QMacInstallDialog::DoInstall() } } } - std::cout << "ln -s [" << file.toAscii().data() << "] ["; - std::cout << newName.toAscii().data() << "]\n"; - if(!cmSystemTools::CreateSymlink(file.toAscii().data(), - newName.toAscii().data())) + std::cout << "ln -s [" << file.toLocal8Bit().data() << "] ["; + std::cout << newName.toLocal8Bit().data() << "]\n"; + if(!cmSystemTools::CreateSymlink(file.toLocal8Bit().data(), + newName.toLocal8Bit().data())) { QString message = tr("Failed create symlink " "installation may be incomplete: "); - message += newName.toAscii().data(); + message += newName; QString title = tr("Error Creating Symlink"); QMessageBox::StandardButton btn = - QMessageBox::critical(this, title, message, + QMessageBox::critical(this, title, message, QMessageBox::Ok|QMessageBox::Abort); if(btn == QMessageBox::Abort) { @@ -113,7 +112,7 @@ void QMacInstallDialog::SkipInstall() void QMacInstallDialog::ShowBrowser() { - QString dir = QFileDialog::getExistingDirectory(this, + QString dir = QFileDialog::getExistingDirectory(this, tr("Enter Install Prefix"), this->Internals->InstallPrefix->text()); if(!dir.isEmpty()) { diff --git a/Source/QtDialog/QtDialogCPack.cmake.in b/Source/QtDialog/QtDialogCPack.cmake.in index 701991b..3196471 100644 --- a/Source/QtDialog/QtDialogCPack.cmake.in +++ b/Source/QtDialog/QtDialogCPack.cmake.in @@ -1,18 +1,18 @@ -SET(IS_APPLE @APPLE@) -SET(CMAKE_PACKAGE_QTGUI @CMAKE_PACKAGE_QTGUI@) +set(IS_APPLE @APPLE@) +set(CMAKE_PACKAGE_QTGUI @CMAKE_PACKAGE_QTGUI@) -IF(CMAKE_PACKAGE_QTGUI) - SET(CPACK_PACKAGE_EXECUTABLES "cmake-gui" "CMake (cmake-gui)" ${CPACK_PACKAGE_EXECUTABLES}) - SET(CPACK_CREATE_DESKTOP_LINKS "cmake-gui" ${CPACK_CREATE_DESKTOP_LINKS}) - IF(IS_APPLE) +if(CMAKE_PACKAGE_QTGUI) + set(CPACK_PACKAGE_EXECUTABLES "cmake-gui" "CMake (cmake-gui)" ${CPACK_PACKAGE_EXECUTABLES}) + set(CPACK_CREATE_DESKTOP_LINKS "cmake-gui" ${CPACK_CREATE_DESKTOP_LINKS}) + if(IS_APPLE) # for apple install we set the install prefix to # / and then install # cmake into the bundle for cmake-gui and must use DESTDIR - SET(CPACK_SET_DESTDIR TRUE) + set(CPACK_SET_DESTDIR TRUE) # we also want to run post install stuff to setup command line - SET(CPACK_POSTFLIGHT_SCRIPT "@CMAKE_POSTFLIGHT_SCRIPT@") - SET(CPACK_POSTUPGRADE_SCRIPT "@CMAKE_POSTUPGRADE_SCRIPT@") - ENDIF(IS_APPLE) -ENDIF(CMAKE_PACKAGE_QTGUI) + set(CPACK_POSTFLIGHT_SCRIPT "@CMAKE_POSTFLIGHT_SCRIPT@") + set(CPACK_POSTUPGRADE_SCRIPT "@CMAKE_POSTUPGRADE_SCRIPT@") + endif() +endif() diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index 1f770ed..1cc1e3a 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -16,7 +16,7 @@ #include "cmDocumentGeneratorExpressions.h" /** \class cmAddCustomCommandCommand - * \brief + * \brief * * cmAddCustomCommandCommand defines a new command (rule) that can * be executed within the build process @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAddCustomCommandCommand; } @@ -45,7 +45,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "add_custom_command";} - + /** * Succinct documentation. */ @@ -53,7 +53,7 @@ public: { return "Add a custom build rule to the generated build system."; } - + /** * More documentation. */ @@ -68,7 +68,8 @@ public: " [COMMAND command2 [ARGS] [args2...] ...]\n" " [MAIN_DEPENDENCY depend]\n" " [DEPENDS [depends...]]\n" - " [IMPLICIT_DEPENDS <lang1> depend1 ...]\n" + " [IMPLICIT_DEPENDS <lang1> depend1\n" + " [<lang2> depend2] ...]\n" " [WORKING_DIRECTORY dir]\n" " [COMMENT comment] [VERBATIM] [APPEND])\n" "This defines a command to generate specified OUTPUT file(s). " @@ -142,6 +143,8 @@ public: "dependencies of an input file. The language given specifies the " "programming language whose corresponding dependency scanner should " "be used. Currently only C and CXX language scanners are supported. " + "The language has to be specified for every file in the " + "IMPLICIT_DEPENDS list. " "Dependencies discovered from the scanning are added to those of " "the custom command at build time. Note that the IMPLICIT_DEPENDS " "option is currently supported only for Makefile generators and " @@ -177,7 +180,7 @@ public: "is recompiled.\n" ; } - + cmTypeMacro(cmAddCustomCommandCommand, cmCommand); protected: bool CheckOutputs(const std::vector<std::string>& outputs); diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h index 50bffef..d4ed450 100644 --- a/Source/cmAddCustomTargetCommand.h +++ b/Source/cmAddCustomTargetCommand.h @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAddCustomTargetCommand; } @@ -38,13 +38,13 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "add_custom_target";} - + /** * Succinct documentation. */ @@ -52,7 +52,7 @@ public: { return "Add a target with no output so it will always be built."; } - + /** * More documentation. */ @@ -101,7 +101,7 @@ public: "convenience in editing even if they have not build rules." ; } - + cmTypeMacro(cmAddCustomTargetCommand, cmCommand); }; diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h index 14a7741..ed80067 100644 --- a/Source/cmAddDependenciesCommand.h +++ b/Source/cmAddDependenciesCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAddDependenciesCommand; } @@ -49,7 +49,7 @@ public: { return "Add a dependency between top-level targets."; } - + /** * More documentation. */ @@ -70,7 +70,7 @@ public: "SET_SOURCE_FILES_PROPERTIES to add file-level dependencies to object " "files."; } - + cmTypeMacro(cmAddDependenciesCommand, cmCommand); }; diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index c1d0e9d..fd39eec 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -102,16 +102,17 @@ bool cmAddLibraryCommand STATIC. But at this point we know only the name of the target, but not yet its linker language. */ if ((type != cmTarget::STATIC_LIBRARY) && + (type != cmTarget::OBJECT_LIBRARY) && (this->Makefile->GetCMakeInstance()->GetPropertyAsBool( "TARGET_SUPPORTS_SHARED_LIBS") == false)) { - std::string msg = "ADD_LIBRARY for library "; - msg += args[0]; - msg += " is used with the "; - msg += type==cmTarget::SHARED_LIBRARY ? "SHARED" : "MODULE"; - msg += " option, but the target platform supports only STATIC libraries. " - "Building it STATIC instead. This may lead to problems."; - cmSystemTools::Message(msg.c_str() ,"Warning"); + cmOStringStream w; + w << + "ADD_LIBRARY called with " << + (type==cmTarget::SHARED_LIBRARY ? "SHARED" : "MODULE") << + " option but the target platform does not support dynamic linking. " + "Building a STATIC library instead. This may lead to problems."; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); type = cmTarget::STATIC_LIBRARY; } diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h index b1ae202..c144565 100644 --- a/Source/cmAddLibraryCommand.h +++ b/Source/cmAddLibraryCommand.h @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAddLibraryCommand; } @@ -50,7 +50,7 @@ public: { return "Add a library to the project using the specified source files."; } - + /** * More documentation. */ @@ -78,7 +78,9 @@ public: "functionality. " "If no type is given explicitly the type is STATIC or SHARED based " "on whether the current value of the variable BUILD_SHARED_LIBS is " - "true." + "true. " + "For SHARED and MODULE libraries the POSITION_INDEPENDENT_CODE " + "target property is set to TRUE automatically." "\n" "By default the library file will be created in the build tree " "directory corresponding to the source tree directory in which " @@ -134,7 +136,7 @@ public: "Object libraries cannot be imported, exported, installed, or linked." ; } - + cmTypeMacro(cmAddLibraryCommand, cmCommand); }; diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 5fca527..9efeda4 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -20,11 +20,11 @@ bool cmAddSubDirectoryCommand::InitialPass this->SetError("called with incorrect number of arguments"); return false; } - + // store the binpath std::string srcArg = args[0]; std::string binArg; - + bool excludeFromAll = false; // process the rest of the arguments looking for optional args diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h index 3d6f51e..fa322b0 100644 --- a/Source/cmAddSubDirectoryCommand.h +++ b/Source/cmAddSubDirectoryCommand.h @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAddSubDirectoryCommand; } @@ -51,7 +51,7 @@ public: { return "Add a subdirectory to the build."; } - + /** * More documentation. */ @@ -90,7 +90,7 @@ public: "project build system to satisfy the dependency." ; } - + cmTypeMacro(cmAddSubDirectoryCommand, cmCommand); }; diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index 59f10f6..6a0cd9d 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAddTestCommand; } @@ -50,7 +50,7 @@ public: { return "Add a test to the project with the specified arguments."; } - + /** * More documentation. */ @@ -81,7 +81,7 @@ public: "\n" "Arguments after COMMAND may use \"generator expressions\" with the " "syntax \"$<...>\". " - CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS "Example usage:\n" " add_test(NAME mytest\n" " COMMAND testDriver --config $<CONFIGURATION>\n" @@ -91,7 +91,7 @@ public: "executable file produced by target \"myexe\"." ; } - + cmTypeMacro(cmAddTestCommand, cmCommand); private: bool HandleNameMode(std::vector<std::string> const& args); diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index dc6b749..b410e44 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -240,6 +240,7 @@ bool cmArchiveWrite::AddFile(const char* file, // Clear acl and xattr fields not useful for distribution. archive_entry_acl_clear(e); archive_entry_xattr_clear(e); + archive_entry_set_fflags(e, 0, 0); if(archive_write_header(this->Archive, e) != ARCHIVE_OK) { this->Error = "archive_write_header: "; diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index f88be3d..01f64b7 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -23,7 +23,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass this->SetError("called with incorrect number of arguments"); return false; } - + std::string sourceListValue; std::string templateDirectory = args[0]; this->Makefile->AddExtraDirectory(templateDirectory.c_str()); @@ -40,12 +40,12 @@ bool cmAuxSourceDirectoryCommand::InitialPass } // was the list already populated - const char *def = this->Makefile->GetDefinition(args[1].c_str()); + const char *def = this->Makefile->GetDefinition(args[1].c_str()); if (def) { sourceListValue = def; } - + // Load all the files in the directory cmsys::Directory dir; if(dir.Load(tdir.c_str())) @@ -69,7 +69,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass std::string fullname = templateDirectory; fullname += "/"; fullname += file; - // add the file as a class file so + // add the file as a class file so // depends can be done cmSourceFile* sf = this->Makefile->GetOrCreateSource(fullname.c_str()); @@ -83,7 +83,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass } } } - this->Makefile->AddDefinition(args[1].c_str(), sourceListValue.c_str()); + this->Makefile->AddDefinition(args[1].c_str(), sourceListValue.c_str()); return true; } diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h index f059e44..8a70f19 100644 --- a/Source/cmAuxSourceDirectoryCommand.h +++ b/Source/cmAuxSourceDirectoryCommand.h @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmAuxSourceDirectoryCommand; } @@ -45,7 +45,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const { return "aux_source_directory";} - + /** * Succinct documentation. */ @@ -53,7 +53,7 @@ public: { return "Find all source files in a directory."; } - + /** * More documentation. */ @@ -77,7 +77,7 @@ public: "one would have to manually rerun CMake to generate a build system " "incorporating the new file."; } - + cmTypeMacro(cmAuxSourceDirectoryCommand, cmCommand); }; diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h index 67ef37e..17f57cf 100644 --- a/Source/cmBreakCommand.h +++ b/Source/cmBreakCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmBreakCommand; } @@ -46,7 +46,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "break";} - + /** * Succinct documentation. */ @@ -54,7 +54,7 @@ public: { return "Break from an enclosing foreach or while loop."; } - + /** * More documentation. */ @@ -64,7 +64,7 @@ public: " break()\n" "Breaks from an enclosing foreach loop or while loop"; } - + cmTypeMacro(cmBreakCommand, cmCommand); }; diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h index a333c5d..1bab453 100644 --- a/Source/cmBuildCommand.h +++ b/Source/cmBuildCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmBuildCommand; } diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx index fa69830..f95a79e 100644 --- a/Source/cmBuildNameCommand.cxx +++ b/Source/cmBuildNameCommand.cxx @@ -25,7 +25,7 @@ bool cmBuildNameCommand const char* cacheValue = this->Makefile->GetDefinition(args[0].c_str()); if(cacheValue) { - // do we need to correct the value? + // do we need to correct the value? cmsys::RegularExpression reg("[()/]"); if (reg.find(cacheValue)) { @@ -41,7 +41,7 @@ bool cmBuildNameCommand return true; } - + std::string buildname = "WinNT"; if(this->Makefile->GetDefinition("UNIX")) { @@ -67,7 +67,7 @@ bool cmBuildNameCommand "(", "_"); cmSystemTools::ReplaceString(buildname, ")", "_"); - + this->Makefile->AddCacheDefinition(args[0].c_str(), buildname.c_str(), "Name of build.", diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index 126934c..49c585f 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -120,7 +120,7 @@ bool cmCMakeMinimumRequired { this->Makefile->SetPolicyVersion(version_string.c_str()); } - + return true; } diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h index d23ce79..acf2829 100644 --- a/Source/cmCMakeMinimumRequired.h +++ b/Source/cmCMakeMinimumRequired.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmCMakeMinimumRequired; } @@ -46,7 +46,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "cmake_minimum_required";} - + /** * Succinct documentation. */ @@ -54,7 +54,7 @@ public: { return "Set the minimum required version of cmake for a project."; } - + /** * More documentation. */ @@ -77,7 +77,7 @@ public: "It should be specified so CMake versions 2.4 and lower fail with an " "error instead of just a warning."; } - + cmTypeMacro(cmCMakeMinimumRequired, cmCommand); private: diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h index 4f1ed36..4f9faa1 100644 --- a/Source/cmCMakePolicyCommand.h +++ b/Source/cmCMakePolicyCommand.h @@ -17,8 +17,8 @@ /** \class cmCMakePolicyCommand * \brief Set how CMake should handle policies * - * cmCMakePolicyCommand sets how CMake should deal with backwards - * compatibility policies. + * cmCMakePolicyCommand sets how CMake should deal with backwards + * compatibility policies. */ class cmCMakePolicyCommand : public cmCommand { @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmCMakePolicyCommand; } @@ -47,7 +47,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "cmake_policy";} - + /** * Succinct documentation. */ @@ -55,7 +55,7 @@ public: { return "Manage CMake Policy settings."; } - + /** * More documentation. */ @@ -129,7 +129,7 @@ public: "closest nested policy stack entry." ; } - + cmTypeMacro(cmCMakePolicyCommand, cmCommand); private: bool HandleSetMode(std::vector<std::string> const& args); diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index e237913..48ae50e 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -389,7 +389,7 @@ void CCONV cmAddLibrary(void *arg, const char *libname, int shared, { srcs2.push_back(srcs[i]); } - mf->AddLibrary(libname, + mf->AddLibrary(libname, (shared? cmTarget::SHARED_LIBRARY : cmTarget::STATIC_LIBRARY), srcs2); } @@ -859,13 +859,13 @@ void CCONV cmFree(void *data) } void CCONV DefineSourceFileProperty (void *arg, const char *name, - const char *briefDocs, + const char *briefDocs, const char *longDocs, int chained) { cmMakefile *mf = static_cast<cmMakefile *>(arg); mf->GetCMakeInstance()->DefineProperty(name,cmProperty::SOURCE_FILE, - briefDocs, longDocs, + briefDocs, longDocs, chained != 0); } diff --git a/Source/cmCPluginAPI.h b/Source/cmCPluginAPI.h index fd5a4f8..5c832c3 100644 --- a/Source/cmCPluginAPI.h +++ b/Source/cmCPluginAPI.h @@ -168,10 +168,10 @@ typedef struct /* new functions added after 2.4 */ void *(CCONV *CreateNewSourceFile) (void *mf); void (CCONV *DefineSourceFileProperty) (void *mf, const char *name, - const char *briefDocs, + const char *briefDocs, const char *longDocs, int chained); - + /* this is the end of the C function stub API structure */ } cmCAPI; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index b12cf40..bb6f3f2 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -75,8 +75,8 @@ struct tm* cmCTest::GetNightlyTime(std::string str, char buf[1024]; // add todays year day and month to the time in str because // curl_getdate no longer assumes the day is today - sprintf(buf, "%d%02d%02d %s", - lctime->tm_year+1900, + sprintf(buf, "%d%02d%02d %s", + lctime->tm_year+1900, lctime->tm_mon +1, lctime->tm_mday, str.c_str()); @@ -223,7 +223,7 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method, default: break; } - + ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); @@ -237,7 +237,7 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method, ::curl_easy_cleanup(curl); ::curl_global_cleanup(); - + return static_cast<int>(res); } #endif @@ -300,7 +300,7 @@ cmCTest::cmCTest() this->ForceNewCTestProcess = false; this->TomorrowTag = false; this->Verbose = false; - + this->Debug = false; this->ShowLineNumbers = false; this->Quiet = false; @@ -763,7 +763,7 @@ bool cmCTest::UpdateCTestConfiguration() } else { - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Parse Config file:" + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Parse Config file:" << fileName.c_str() << "\n"); // parse the dart test file std::ifstream fin(fileName.c_str()); @@ -947,7 +947,7 @@ bool cmCTest::AddIfExists(Part part, const char* file) //---------------------------------------------------------------------- bool cmCTest::CTestFileExists(const std::string& filename) { - std::string testingDir = this->BinaryDir + "/Testing/" + + std::string testingDir = this->BinaryDir + "/Testing/" + this->CurrentTag + "/" + filename; return cmSystemTools::FileExists(testingDir.c_str()); } @@ -955,7 +955,7 @@ bool cmCTest::CTestFileExists(const std::string& filename) //---------------------------------------------------------------------- cmCTestGenericHandler* cmCTest::GetInitializedHandler(const char* handler) { - cmCTest::t_TestingHandlers::iterator it = + cmCTest::t_TestingHandlers::iterator it = this->TestingHandlers.find(handler); if ( it == this->TestingHandlers.end() ) { @@ -968,7 +968,7 @@ cmCTestGenericHandler* cmCTest::GetInitializedHandler(const char* handler) //---------------------------------------------------------------------- cmCTestGenericHandler* cmCTest::GetHandler(const char* handler) { - cmCTest::t_TestingHandlers::iterator it = + cmCTest::t_TestingHandlers::iterator it = this->TestingHandlers.find(handler); if ( it == this->TestingHandlers.end() ) { @@ -1317,8 +1317,8 @@ int cmCTest::RunTest(std::vector<const char*> argv, { if(argv[i]) { - // make sure we pass the timeout in for any build and test - // invocations. Since --build-generator is required this is a + // make sure we pass the timeout in for any build and test + // invocations. Since --build-generator is required this is a // good place to check for it, and to add the arguments in if (strcmp(argv[i],"--build-generator") == 0 && timeout > 0) { @@ -1527,18 +1527,18 @@ void cmCTest::StartXML(std::ostream& ostr, bool append) << "\tNumberOfPhysicalCPU=\""<< info.GetNumberOfPhysicalCPU() << "\"\n" << "\tTotalVirtualMemory=\"" << info.GetTotalVirtualMemory() << "\"\n" << "\tTotalPhysicalMemory=\""<< info.GetTotalPhysicalMemory() << "\"\n" - << "\tLogicalProcessorsPerPhysical=\"" + << "\tLogicalProcessorsPerPhysical=\"" << info.GetLogicalProcessorsPerPhysical() << "\"\n" - << "\tProcessorClockFrequency=\"" - << info.GetProcessorClockFrequency() << "\"\n" + << "\tProcessorClockFrequency=\"" + << info.GetProcessorClockFrequency() << "\"\n" << ">" << std::endl; - this->AddSiteProperties(ostr); + this->AddSiteProperties(ostr); } //---------------------------------------------------------------------- void cmCTest::AddSiteProperties(std::ostream& ostr) { - cmCTestScriptHandler* ch = + cmCTestScriptHandler* ch = static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); cmake* cm = ch->GetCMake(); // if no CMake then this is the old style script and props like @@ -1550,9 +1550,9 @@ void cmCTest::AddSiteProperties(std::ostream& ostr) // This code should go when cdash is changed to use labels only const char* subproject = cm->GetProperty("SubProject", cmProperty::GLOBAL); if(subproject) - { + { ostr << "<Subproject name=\"" << subproject << "\">\n"; - const char* labels = + const char* labels = ch->GetCMake()->GetProperty("SubProjectLabels", cmProperty::GLOBAL); if(labels) { @@ -1569,11 +1569,11 @@ void cmCTest::AddSiteProperties(std::ostream& ostr) } ostr << "</Subproject>\n"; } - + // This code should stay when cdash only does label based sub-projects const char* label = cm->GetProperty("Label", cmProperty::GLOBAL); if(label) - { + { ostr << "<Labels>\n"; ostr << " <Label>" << label << "</Label>\n"; ostr << "</Labels>\n"; @@ -1765,7 +1765,7 @@ bool cmCTest::SubmitExtraFiles(const char* cfiles) //------------------------------------------------------- -// for a -D argument convert the next argument into +// for a -D argument convert the next argument into // the proper list of dashboard steps via SetTest bool cmCTest::AddTestsForDashboardType(std::string &targ) { @@ -1947,29 +1947,6 @@ bool cmCTest::AddTestsForDashboardType(std::string &targ) } else { - cmCTestLog(this, ERROR_MESSAGE, - "CTest -D called with incorrect option: " - << targ << std::endl); - cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl - << " " << "ctest" << " -D Continuous" << std::endl - << " " << "ctest" - << " -D Continuous(Start|Update|Configure|Build)" << std::endl - << " " << "ctest" - << " -D Continuous(Test|Coverage|MemCheck|Submit)" - << std::endl - << " " << "ctest" << " -D Experimental" << std::endl - << " " << "ctest" - << " -D Experimental(Start|Update|Configure|Build)" - << std::endl - << " " << "ctest" - << " -D Experimental(Test|Coverage|MemCheck|Submit)" - << std::endl - << " " << "ctest" << " -D Nightly" << std::endl - << " " << "ctest" - << " -D Nightly(Start|Update|Configure|Build)" << std::endl - << " " << "ctest" - << " -D Nightly(Test|Coverage|MemCheck|Submit)" << std::endl - << " " << "ctest" << " -D NightlyMemoryCheck" << std::endl); return false; } return true; @@ -1977,6 +1954,27 @@ bool cmCTest::AddTestsForDashboardType(std::string &targ) //---------------------------------------------------------------------- +void cmCTest::ErrorMessageUnknownDashDValue(std::string &val) +{ + cmCTestLog(this, ERROR_MESSAGE, + "CTest -D called with incorrect option: " << val << std::endl); + + cmCTestLog(this, ERROR_MESSAGE, + "Available options are:" << std::endl + << " ctest -D Continuous" << std::endl + << " ctest -D Continuous(Start|Update|Configure|Build)" << std::endl + << " ctest -D Continuous(Test|Coverage|MemCheck|Submit)" << std::endl + << " ctest -D Experimental" << std::endl + << " ctest -D Experimental(Start|Update|Configure|Build)" << std::endl + << " ctest -D Experimental(Test|Coverage|MemCheck|Submit)" << std::endl + << " ctest -D Nightly" << std::endl + << " ctest -D Nightly(Start|Update|Configure|Build)" << std::endl + << " ctest -D Nightly(Test|Coverage|MemCheck|Submit)" << std::endl + << " ctest -D NightlyMemoryCheck" << std::endl); +} + + +//---------------------------------------------------------------------- bool cmCTest::CheckArgument(const std::string& arg, const char* varg1, const char* varg2) { @@ -1985,9 +1983,9 @@ bool cmCTest::CheckArgument(const std::string& arg, const char* varg1, //---------------------------------------------------------------------- -// Processes one command line argument (and its arguments if any) +// Processes one command line argument (and its arguments if any) // for many simple options and then returns -void cmCTest::HandleCommandLineArguments(size_t &i, +void cmCTest::HandleCommandLineArguments(size_t &i, std::vector<std::string> &args) { std::string arg = args[i]; @@ -2036,14 +2034,14 @@ void cmCTest::HandleCommandLineArguments(size_t &i, i++; this->SetStopTime(args[i]); } - + if(this->CheckArgument(arg, "-C", "--build-config") && i < args.size() - 1) { i++; this->SetConfigType(args[i].c_str()); } - + if(this->CheckArgument(arg, "--debug")) { this->Debug = true; @@ -2083,7 +2081,7 @@ void cmCTest::HandleCommandLineArguments(size_t &i, { this->OutputTestOutputOnTestFailure = true; } - + if(this->CheckArgument(arg, "-N", "--show-only")) { this->ShowOnly = true; @@ -2123,7 +2121,7 @@ void cmCTest::HandleCommandLineArguments(size_t &i, this->SubmitIndex = 0; } } - + if(this->CheckArgument(arg, "--overwrite") && i < args.size() - 1) { i++; @@ -2176,7 +2174,7 @@ void cmCTest::HandleCommandLineArguments(size_t &i, this->GetHandler("memcheck")-> SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str()); } - + if(this->CheckArgument(arg, "-E", "--exclude-regex") && i < args.size() - 1) { @@ -2185,17 +2183,17 @@ void cmCTest::HandleCommandLineArguments(size_t &i, SetPersistentOption("ExcludeRegularExpression", args[i].c_str()); this->GetHandler("memcheck")-> SetPersistentOption("ExcludeRegularExpression", args[i].c_str()); - } + } } //---------------------------------------------------------------------- // handle the -S -SR and -SP arguments -void cmCTest::HandleScriptArguments(size_t &i, +void cmCTest::HandleScriptArguments(size_t &i, std::vector<std::string> &args, bool &SRArgumentSpecified) { std::string arg = args[i]; - if(this->CheckArgument(arg, "-SP", "--script-new-process") && + if(this->CheckArgument(arg, "-SP", "--script-new-process") && i < args.size() - 1 ) { this->RunConfigurationScript = true; @@ -2208,8 +2206,8 @@ void cmCTest::HandleScriptArguments(size_t &i, ch->AddConfigurationScript(args[i].c_str(),false); } } - - if(this->CheckArgument(arg, "-SR", "--script-run") && + + if(this->CheckArgument(arg, "-SR", "--script-run") && i < args.size() - 1 ) { SRArgumentSpecified = true; @@ -2219,7 +2217,7 @@ void cmCTest::HandleScriptArguments(size_t &i, = static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); ch->AddConfigurationScript(args[i].c_str(),true); } - + if(this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1 ) { this->RunConfigurationScript = true; @@ -2235,13 +2233,29 @@ void cmCTest::HandleScriptArguments(size_t &i, } //---------------------------------------------------------------------- +bool cmCTest::AddVariableDefinition(const std::string &arg) +{ + std::string name; + std::string value; + cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; + + if (cmCacheManager::ParseEntry(arg.c_str(), name, value, type)) + { + this->Definitions[name] = value; + return true; + } + + return false; +} + +//---------------------------------------------------------------------- // the main entry point of ctest, called from main int cmCTest::Run(std::vector<std::string> &args, std::string* output) { this->FindRunningCMake(); const char* ctestExec = "ctest"; bool cmakeAndTest = false; - bool performSomeTest = true; + bool executeTests = true; bool SRArgumentSpecified = false; // copy the command line @@ -2266,14 +2280,29 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) this->ProduceXML = true; i++; std::string targ = args[i]; - // AddTestsForDashboard parses the dashborad type and converts it + // AddTestsForDashboard parses the dashboard type and converts it // into the separate stages if (!this->AddTestsForDashboardType(targ)) { - performSomeTest = false; + if (!this->AddVariableDefinition(targ)) + { + this->ErrorMessageUnknownDashDValue(targ); + executeTests = false; + } } } + // If it's not exactly -D, but it starts with -D, then try to parse out + // a variable definition from it, same as CMake does. Unsuccessful + // attempts are simply ignored since previous ctest versions ignore + // this too. (As well as many other unknown command line args.) + // + if(arg != "-D" && cmSystemTools::StringStartsWith(arg.c_str(), "-D")) + { + std::string input = arg.substr(2); + this->AddVariableDefinition(input); + } + if(this->CheckArgument(arg, "-T", "--test-action") && (i < args.size() -1) ) { @@ -2281,7 +2310,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) i++; if ( !this->SetTest(args[i].c_str(), false) ) { - performSomeTest = false; + executeTests = false; cmCTestLog(this, ERROR_MESSAGE, "CTest -T called with incorrect option: " << args[i].c_str() << std::endl); @@ -2319,7 +2348,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) } else { - performSomeTest = false; + executeTests = false; cmCTestLog(this, ERROR_MESSAGE, "CTest -M called with incorrect option: " << str.c_str() << std::endl); @@ -2370,7 +2399,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) } // the close of the for argument loop - // now what sould cmake do? if --build-and-test was specified then + // now what sould cmake do? if --build-and-test was specified then // we run the build and test handler and return if(cmakeAndTest) { @@ -2384,14 +2413,13 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) #endif if(retv != 0) { - cmCTestLog(this, DEBUG, "build and test failing returing: " << retv + cmCTestLog(this, DEBUG, "build and test failing returing: " << retv << std::endl); } return retv; } - // if some tests must be run - if(performSomeTest) + if(executeTests) { int res; // call process directory @@ -2413,14 +2441,14 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) res = this->GetHandler("script")->ProcessHandler(); if(res != 0) { - cmCTestLog(this, DEBUG, "running script failing returning: " << res + cmCTestLog(this, DEBUG, "running script failing returning: " << res << std::endl); } } else { - // What is this? -V seems to be the same as -VV, + // What is this? -V seems to be the same as -VV, // and Verbose is always on in this case this->ExtraVerbose = this->Verbose; this->Verbose = true; @@ -2447,7 +2475,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) } if(res != 0) { - cmCTestLog(this, DEBUG, "Running a test(s) failed returning : " << res + cmCTestLog(this, DEBUG, "Running a test(s) failed returning : " << res << std::endl); } return res; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 7baf0a2..587a6db 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -93,7 +93,7 @@ public: */ static int HTTPRequest(std::string url, HTTPMethod method, std::string& response, - std::string fields = "", + std::string fields = "", std::string putFile = "", int timeout = 0); #endif @@ -198,13 +198,13 @@ public: //! base64 encode a file std::string Base64EncodeFile(std::string file); - /** + /** * Return the time remaining that the script is allowed to run in * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has * not been set it returns 1e7 seconds */ double GetRemainingTimeAllowed(); - + ///! Open file in the output directory and set the stream bool OpenOutputFile(const std::string& path, const std::string& name, @@ -418,6 +418,12 @@ public: bool GetLabelSummary() { return this->LabelSummary;} std::string GetCostDataFile(); + + const std::map<std::string, std::string> &GetDefinitions() + { + return this->Definitions; + } + private: std::string ConfigType; std::string ScheduleType; @@ -517,12 +523,18 @@ private: //! parse the option after -D and convert it into the appropriate steps bool AddTestsForDashboardType(std::string &targ); + //! read as "emit an error message for an unknown -D value" + void ErrorMessageUnknownDashDValue(std::string &val); + + //! add a variable definition from a command line -D value + bool AddVariableDefinition(const std::string &arg); + //! parse and process most common command line arguments - void HandleCommandLineArguments(size_t &i, + void HandleCommandLineArguments(size_t &i, std::vector<std::string> &args); //! hande the -S -SP and -SR arguments - void HandleScriptArguments(size_t &i, + void HandleScriptArguments(size_t &i, std::vector<std::string> &args, bool &SRArgumentSpecified); @@ -560,6 +572,8 @@ private: int OutputLogFileLastTag; bool OutputTestOutputOnTestFailure; + + std::map<std::string, std::string> Definitions; }; class cmCTestLogWrite diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 47a0e85..4231243 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -267,7 +267,7 @@ bool cmCacheManager::LoadCache(const char* path, // If the entry is not internal to the cache being loaded // or if it is in the list of internal entries to be // imported, load it. - if ( internal || (e.Type != INTERNAL) || + if ( internal || (e.Type != INTERNAL) || (includes.find(entryKey) != includes.end()) ) { // If we are loading the cache from another project, @@ -478,7 +478,7 @@ bool cmCacheManager::SaveCache(const char* path) = this->GetCacheEntry("CMAKE_COMMAND"); if ( cmakeCacheEntry ) { - fout << "# It was generated by CMake: " << + fout << "# It was generated by CMake: " << cmakeCacheEntry->Value << std::endl; } @@ -500,10 +500,10 @@ bool cmCacheManager::SaveCache(const char* path) fout << "########################\n"; fout << "\n"; - for( std::map<cmStdString, CacheEntry>::const_iterator i = + for( std::map<cmStdString, CacheEntry>::const_iterator i = this->Cache.begin(); i != this->Cache.end(); ++i) { - const CacheEntry& ce = (*i).second; + const CacheEntry& ce = (*i).second; CacheEntryType t = ce.Type; if(!ce.Initialized) { @@ -641,7 +641,7 @@ void cmCacheManager::OutputHelpString(std::ostream& fout, std::string::size_type pos = 0; for (std::string::size_type i=0; i<=end; i++) { - if ((i==end) + if ((i==end) || (helpString[i]=='\n') || ((i-pos >= 60) && (helpString[i]==' '))) { @@ -700,12 +700,12 @@ void cmCacheManager::PrintCache(std::ostream& out) const { out << "=================================================" << std::endl; out << "CMakeCache Contents:" << std::endl; - for(std::map<cmStdString, CacheEntry>::const_iterator i = + for(std::map<cmStdString, CacheEntry>::const_iterator i = this->Cache.begin(); i != this->Cache.end(); ++i) { if((*i).second.Type != INTERNAL) { - out << (*i).first.c_str() << " = " << (*i).second.Value.c_str() + out << (*i).first.c_str() << " = " << (*i).second.Value.c_str() << std::endl; } } @@ -768,7 +768,7 @@ bool cmCacheManager::CacheIterator::IsAtEnd() const void cmCacheManager::CacheIterator::Begin() { - this->Position = this->Container.Cache.begin(); + this->Position = this->Container.Cache.begin(); } bool cmCacheManager::CacheIterator::Find(const char* key) @@ -781,7 +781,7 @@ void cmCacheManager::CacheIterator::Next() { if (!this->IsAtEnd()) { - ++this->Position; + ++this->Position; } } diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index 9c94d21..4a5ee45 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -22,7 +22,7 @@ class cmake; * \brief Control class for cmake's cache * * Load and Save CMake cache files. - * + * */ class cmCacheManager { @@ -30,7 +30,7 @@ public: cmCacheManager(cmake* cm); class CacheIterator; friend class cmCacheManager::CacheIterator; - enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC, + enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC, UNINITIALIZED }; private: @@ -57,7 +57,7 @@ public: bool IsAtEnd() const; void Next(); const char *GetName() const { - return this->Position->first.c_str(); } + return this->Position->first.c_str(); } const char* GetProperty(const char*) const ; bool GetPropertyAsBool(const char*) const ; bool PropertyExists(const char*) const; @@ -76,7 +76,7 @@ public: CacheIterator(cmCacheManager &cm) : Container(cm) { this->Begin(); } - CacheIterator(cmCacheManager &cm, const char* key) : Container(cm) + CacheIterator(cmCacheManager &cm, const char* key) : Container(cm) { if ( key ) { @@ -87,30 +87,30 @@ public: CacheEntry const& GetEntry() const { return this->Position->second; } CacheEntry& GetEntry() { return this->Position->second; } }; - + ///! return an iterator to iterate through the cache map - cmCacheManager::CacheIterator NewIterator() + cmCacheManager::CacheIterator NewIterator() { return CacheIterator(*this); - } - + } + /** * Types for the cache entries. These are useful as * hints for a cache editor program. Path should bring - * up a file chooser, BOOL a check box, and STRING a + * up a file chooser, BOOL a check box, and STRING a * text entry box, FILEPATH is a full path to a file which * can be different than just a path input */ static CacheEntryType StringToType(const char*); static const char* TypeToString(CacheEntryType); static bool IsType(const char*); - + ///! Load a cache for given makefile. Loads from ouput home. - bool LoadCache(cmMakefile*); + bool LoadCache(cmMakefile*); ///! Load a cache for given makefile. Loads from path/CMakeCache.txt. bool LoadCache(const char* path); bool LoadCache(const char* path, bool internal); - bool LoadCache(const char* path, bool internal, + bool LoadCache(const char* path, bool internal, std::set<cmStdString>& excludes, std::set<cmStdString>& includes); @@ -124,19 +124,19 @@ public: ///! Print the cache to a stream void PrintCache(std::ostream&) const; - + ///! Get the iterator for an entry with a given key. cmCacheManager::CacheIterator GetCacheIterator(const char *key=0); - + ///! Remove an entry from the cache void RemoveCacheEntry(const char* key); - + ///! Get the number of entries in the cache int GetSize() { return static_cast<int>(this->Cache.size()); } - + ///! Break up a line like VAR:type="value" into var, type and value - static bool ParseEntry(const char* entry, + static bool ParseEntry(const char* entry, std::string& var, std::string& value, CacheEntryType& type); @@ -154,7 +154,7 @@ public: protected: ///! Add an entry into the cache - void AddCacheEntry(const char* key, const char* value, + void AddCacheEntry(const char* key, const char* value, const char* helpString, CacheEntryType type); ///! Get a cache entry object for a key diff --git a/Source/cmCommand.h b/Source/cmCommand.h index 4faaee3..49f451b 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -23,8 +23,8 @@ * cmCommand is the base class for all commands in CMake. A command * manifests as an entry in CMakeLists.txt and produces one or * more makefile rules. Commands are associated with a particular - * makefile. This base class cmCommand defines the API for commands - * to support such features as enable/disable, inheritance, + * makefile. This base class cmCommand defines the API for commands + * to support such features as enable/disable, inheritance, * documentation, and construction. */ class cmCommand : public cmObject @@ -35,18 +35,18 @@ public: /** * Construct the command. By default it is enabled with no makefile. */ - cmCommand() + cmCommand() {this->Makefile = 0; this->Enabled = true;} /** * Need virtual destructor to destroy real command type. */ virtual ~cmCommand() {} - + /** * Specify the makefile. */ - void SetMakefile(cmMakefile*m) + void SetMakefile(cmMakefile*m) {this->Makefile = m; } cmMakefile* GetMakefile() { return this->Makefile; } @@ -87,12 +87,12 @@ public: * Does this command have a final pass? Query after InitialPass. */ virtual bool HasFinalPass() const { return false; } - + /** * This is a virtual constructor for the command. */ virtual cmCommand* Clone() = 0; - + /** * This determines if the command is invoked when in script mode. */ @@ -139,13 +139,13 @@ public: /** * Enable the command. */ - void EnabledOn() + void EnabledOn() {this->Enabled = true;} /** * Disable the command. */ - void EnabledOff() + void EnabledOff() {this->Enabled = false;} /** @@ -157,13 +157,13 @@ public: /** * Disable or enable the command. */ - void SetEnabled(bool enabled) + void SetEnabled(bool enabled) {this->Enabled = enabled;} /** * Return the last error string. */ - const char* GetError() + const char* GetError() { if(this->Error.length() == 0) { diff --git a/Source/cmCommandArgumentLexer.h b/Source/cmCommandArgumentLexer.h index 828122b..2ea3fa2 100644 --- a/Source/cmCommandArgumentLexer.h +++ b/Source/cmCommandArgumentLexer.h @@ -45,7 +45,7 @@ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -62,7 +62,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; @@ -192,7 +192,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ diff --git a/Source/cmCommandArgumentLexer.in.l b/Source/cmCommandArgumentLexer.in.l index d10e50d..fdca61b 100644 --- a/Source/cmCommandArgumentLexer.in.l +++ b/Source/cmCommandArgumentLexer.in.l @@ -66,43 +66,43 @@ Modify cmCommandArgumentLexer.h: return cal_ENVCURLY; } -\$[A-Za-z0-9/_.+-]+\{ { +\$[A-Za-z0-9/_.+-]+\{ { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2); - return cal_NCURLY; -} + yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2); + return cal_NCURLY; +} -@[A-Za-z0-9/_.+-]+@ { +@[A-Za-z0-9/_.+-]+@ { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2); - return cal_ATNAME; -} + yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2); + return cal_ATNAME; +} "${" { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yylvalp->str = yyextra->DCURLYVariable; return cal_DCURLY; } "}" { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yylvalp->str = yyextra->RCURLYVariable; return cal_RCURLY; } "@" { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yylvalp->str = yyextra->ATVariable; return cal_AT; } -[A-Za-z0-9/_.+-]+ { +[A-Za-z0-9/_.+-]+ { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - return cal_NAME; + yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + return cal_NAME; } <ESCAPES>\\. { @@ -110,31 +110,31 @@ Modify cmCommandArgumentLexer.h: { return cal_ERROR; } - return cal_SYMBOL; + return cal_SYMBOL; } -[^\${}\\@]+ { +[^\${}\\@]+ { //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl; - yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - return cal_SYMBOL; + yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + return cal_SYMBOL; } "$" { - //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yylvalp->str = yyextra->DOLLARVariable; - return cal_DOLLAR; + return cal_DOLLAR; } "{" { - //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yylvalp->str = yyextra->LCURLYVariable; - return cal_LCURLY; + return cal_LCURLY; } <ESCAPES>"\\" { - //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); yylvalp->str = yyextra->BSLASHVariable; - return cal_BSLASH; + return cal_BSLASH; } <NOESCAPES>"\\" { diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index a781767..2f26b0c 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -61,7 +61,7 @@ char* cmCommandArgumentParserHelper::AddString(const char* str) return stVal; } -char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, +char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, const char* var) { if ( !key ) @@ -163,7 +163,7 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) // try to expand the variable char* ret = this->ExpandVariable(var); // if the return was 0 and we want to replace empty strings - // then return an empty string + // then return an empty string if(!ret && this->RemoveEmpty) { return this->AddString(ret); @@ -175,7 +175,7 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var) } } // at this point we want to put it back because of one of these cases: - // - this->ReplaceAtSyntax is false + // - this->ReplaceAtSyntax is false // - this->ReplaceAtSyntax is true, but this->RemoveEmpty is false, // and the variable was not defined std::string ref = "@"; @@ -274,7 +274,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb) this->InputBuffer = str; this->InputBufferPos = 0; this->CurrentLine = 0; - + this->Result = ""; yyscan_t yyscanner; @@ -292,7 +292,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb) if ( Verbose ) { - std::cerr << "Expanding [" << str << "] produced: [" + std::cerr << "Expanding [" << str << "] produced: [" << this->Result.c_str() << "]" << std::endl; } return 1; diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index cdb832b..f8c672f 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -66,8 +66,8 @@ public: void SetNoEscapeMode(bool b) { this->NoEscapeMode = b; } void SetReplaceAtSyntax(bool b) { this->ReplaceAtSyntax = b; } void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; } - - const char* GetError() { return this->ErrorString.c_str(); } + + const char* GetError() { return this->ErrorString.c_str(); } char EmptyVariable[1]; char DCURLYVariable[3]; char RCURLYVariable[3]; @@ -102,7 +102,7 @@ private: std::string ErrorString; bool NoEscapeMode; bool ReplaceAtSyntax; - bool RemoveEmpty; + bool RemoveEmpty; }; #endif diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx index 1c906a6..1d5fc07 100644 --- a/Source/cmCommandArgumentsHelper.cxx +++ b/Source/cmCommandArgumentsHelper.cxx @@ -12,20 +12,20 @@ #include "cmCommandArgumentsHelper.h" -cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args, - const char* key, +cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group) :Key(key) ,Group(group) ,WasActive(false) ,ArgumentsBeforeEmpty(true) -,CurrentIndex(0) +,CurrentIndex(0) { if (args!=0) { args->AddArgument(this); } - + if (this->Group!=0) { this->Group->ContainedArguments.push_back(this); @@ -50,7 +50,7 @@ void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group) if (group!=0) { this->ArgumentsBeforeEmpty = false; - for(std::vector<cmCommandArgument*>::const_iterator + for(std::vector<cmCommandArgument*>::const_iterator argIt= group->ContainedArguments.begin(); argIt != group->ContainedArguments.end(); ++argIt) @@ -67,7 +67,7 @@ bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const return true; } - std::set<const cmCommandArgument*>::const_iterator argIt + std::set<const cmCommandArgument*>::const_iterator argIt = this->ArgumentsBefore.find(current); if (argIt != this->ArgumentsBefore.end()) { @@ -90,7 +90,7 @@ void cmCommandArgument::ApplyOwnGroup() { if (this->Group!=0) { - for (std::vector<cmCommandArgument*>::const_iterator + for (std::vector<cmCommandArgument*>::const_iterator it = this->Group->ContainedArguments.begin(); it != this->Group->ContainedArguments.end(); ++it) @@ -105,7 +105,7 @@ void cmCommandArgument::ApplyOwnGroup() void cmCommandArgument::Activate() { - this->WasActive = true; + this->WasActive = true; this->CurrentIndex = 0; } @@ -117,8 +117,8 @@ bool cmCommandArgument::Consume(const std::string& arg) } -cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args, - const char* key, +cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) ,Ignore(0) @@ -151,8 +151,8 @@ void cmCAStringVector::DoReset() this->Vector.clear(); } -cmCAString::cmCAString(cmCommandArgumentsHelper* args, - const char* key, +cmCAString::cmCAString(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) { @@ -178,14 +178,14 @@ bool cmCAString::DoConsume(const std::string& arg, unsigned int index) void cmCAString::DoReset() { - this->String = this->DefaultString; + this->String = ""; } -cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args, - const char* key, +cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) -,Enabled(false) +,Enabled(false) {} bool cmCAEnabler::DoConsume(const std::string&, unsigned int index) @@ -202,11 +202,11 @@ void cmCAEnabler::DoReset() this->Enabled = false; } -cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args, - const char* key, +cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group) :cmCommandArgument(args, key, group) -,Enabled(true) +,Enabled(true) {} bool cmCADisabler::DoConsume(const std::string&, unsigned int index) @@ -225,7 +225,7 @@ void cmCADisabler::DoReset() void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg) { - for(std::vector<cmCommandArgument*>::iterator + for(std::vector<cmCommandArgument*>::iterator it = this->ContainedArguments.begin(); it != this->ContainedArguments.end(); ++it) @@ -236,7 +236,7 @@ void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg) void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group) { - for(std::vector<cmCommandArgument*>::iterator + for(std::vector<cmCommandArgument*>::iterator it = this->ContainedArguments.begin(); it != this->ContainedArguments.end(); ++it) @@ -245,7 +245,7 @@ void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group) } } -void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args, +void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args, std::vector<std::string>* unconsumedArgs) { if(args==0) @@ -253,7 +253,7 @@ void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args, return; } - for(std::vector<cmCommandArgument*>::iterator + for(std::vector<cmCommandArgument*>::iterator argIt = this->Arguments.begin(); argIt != this->Arguments.end(); ++argIt) @@ -268,7 +268,7 @@ void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args, it != args->end(); ++it) { - for(std::vector<cmCommandArgument*>::iterator + for(std::vector<cmCommandArgument*>::iterator argIt = this->Arguments.begin(); argIt != this->Arguments.end(); ++argIt) diff --git a/Source/cmCommandArgumentsHelper.h b/Source/cmCommandArgumentsHelper.h index cb33ccd..f732f8f 100644 --- a/Source/cmCommandArgumentsHelper.h +++ b/Source/cmCommandArgumentsHelper.h @@ -18,7 +18,7 @@ class cmCommandArgumentsHelper; class cmCommandArgumentGroup; /* cmCommandArgumentsHelper, cmCommandArgumentGroup and cmCommandArgument (i.e. -its derived classes cmCAXXX can be used to simplify the processing of +its derived classes cmCAXXX can be used to simplify the processing of arguments to cmake commands. Maybe they can also be used to generate documentation. @@ -26,11 +26,11 @@ For every argument supported by a command one cmCommandArgument is created and added to cmCommandArgumentsHelper. cmCommand has a cmCommandArgumentsHelper as member variable so this should be used. -The order of the arguments is defined using the Follows(arg) method. It says +The order of the arguments is defined using the Follows(arg) method. It says that this argument follows immediateley the given argument. It can be used with multiple arguments if the argument can follow after different arguments. -Arguments can be arranged in groups using cmCommandArgumentGroup. Every +Arguments can be arranged in groups using cmCommandArgumentGroup. Every member of a group can follow any other member of the group. These groups can also be used to define the order. @@ -42,8 +42,8 @@ For an example see cmExportCommand.cxx. class cmCommandArgument { public: - cmCommandArgument(cmCommandArgumentsHelper* args, - const char* key, + cmCommandArgument(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group=0); virtual ~cmCommandArgument() {} @@ -56,8 +56,8 @@ class cmCommandArgument /// Returns true if the argument was found in the argument list bool WasFound() const {return this->WasActive;} - // The following methods are only called from - // cmCommandArgumentsHelper::Parse(), but making this a friend would + // The following methods are only called from + // cmCommandArgumentsHelper::Parse(), but making this a friend would // give it access to everything /// Make the current argument the currently active argument @@ -89,19 +89,19 @@ class cmCommandArgument virtual void DoReset() = 0; }; -/** cmCAStringVector is to be used for arguments which can consist of more +/** cmCAStringVector is to be used for arguments which can consist of more than one string, e.g. the FILES argument in INSTALL(FILES f1 f2 f3 ...). */ class cmCAStringVector : public cmCommandArgument { public: - cmCAStringVector(cmCommandArgumentsHelper* args, - const char* key, + cmCAStringVector(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group=0); /// Return the vector of strings const std::vector<std::string>& GetVector() const {return this->Vector;} - /** Is there a keyword which should be skipped in + /** Is there a keyword which should be skipped in the arguments (e.g. ARGS for ADD_CUSTOM_COMMAND) ? */ void SetIgnore(const char* ignore) {this->Ignore=ignore;} private: @@ -118,18 +118,15 @@ e.g. the executable name in ADD_EXECUTABLE(). */ class cmCAString : public cmCommandArgument { public: - cmCAString(cmCommandArgumentsHelper* args, - const char* key, + cmCAString(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group=0); /// Return the string const std::string& GetString() const {return this->String;} const char* GetCString() const {return this->String.c_str();} - void SetDefaultString(const char* text) - {this->DefaultString = (text ? text : "");} private: std::string String; - std::string DefaultString; unsigned int DataStart; virtual bool DoConsume(const std::string& arg, unsigned int index); virtual void DoReset(); @@ -141,8 +138,8 @@ enabled using a special argument, e.g. EXCLUDE_FROM_ALL in ADD_EXECUTABLE(). */ class cmCAEnabler : public cmCommandArgument { public: - cmCAEnabler(cmCommandArgumentsHelper* args, - const char* key, + cmCAEnabler(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group=0); /// Has it been enabled ? @@ -159,8 +156,8 @@ disabled using a special argument.*/ class cmCADisabler : public cmCommandArgument { public: - cmCADisabler(cmCommandArgumentsHelper* args, - const char* key, + cmCADisabler(cmCommandArgumentsHelper* args, + const char* key, cmCommandArgumentGroup* group=0); /// Is it still enabled ? @@ -173,7 +170,7 @@ class cmCADisabler : public cmCommandArgument }; -/** Group of arguments, needed for ordering. E.g. WIN32, EXCLUDE_FROM_ALL and +/** Group of arguments, needed for ordering. E.g. WIN32, EXCLUDE_FROM_ALL and MACSOX_BUNDLE from ADD_EXECUTABLE() are a group. */ class cmCommandArgumentGroup @@ -195,7 +192,7 @@ class cmCommandArgumentsHelper { public: /// Parse the argument list - void Parse(const std::vector<std::string>* args, + void Parse(const std::vector<std::string>* args, std::vector<std::string>* unconsumedArgs); /// Add an argument. void AddArgument(cmCommandArgument* arg); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index df78bf8..cd3ef59 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1214,7 +1214,7 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item, { // if this is a -l option then we might need to warn about // CMP0003 so put it in OldUserFlagItems, if it is not a -l - // or -Wl,-l (-framework -pthread), then allow it without a + // or -Wl,-l (-framework -pthread), then allow it without a // CMP0003 as -L will not affect those other linker flags if(item.find("-l") == 0 || item.find("-Wl,-l") == 0) { diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index ea98326..e52ddef 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -104,7 +104,7 @@ bool cmConfigureFileCommand this->Immediate = true; } } - + // If we were told to copy the file immediately, then do it on the // first pass (now). if(this->Immediate) @@ -115,7 +115,7 @@ bool cmConfigureFileCommand return false; } } - + return true; } diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h index de497a9..347174a 100644 --- a/Source/cmConfigureFileCommand.h +++ b/Source/cmConfigureFileCommand.h @@ -19,7 +19,7 @@ class cmConfigureFileCommand : public cmCommand public: cmTypeMacro(cmConfigureFileCommand, cmCommand); - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmConfigureFileCommand; } @@ -48,7 +48,7 @@ public: { return "Copy a file to another location and modify its contents."; } - + /** * Longer documentation. */ @@ -93,7 +93,7 @@ public: private: int ConfigureFile(); - + cmNewLineStyle NewLineStyle; std::string InputFile; diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index ed485e3..1ae7035 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -281,6 +281,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); cmakeFlags.push_back(flag); } + if(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0) + { + fprintf(fout, "SET(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n"); + } /* Use a random file name to avoid rapid creation and deletion of the same executable name (some filesystems fail on that). */ diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h index 806e5a9..3aa0a79 100644 --- a/Source/cmCreateTestSourceList.h +++ b/Source/cmCreateTestSourceList.h @@ -15,7 +15,7 @@ #include "cmCommand.h" /** \class cmCreateTestSourceList - * \brief + * \brief * */ @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmCreateTestSourceList; } @@ -41,7 +41,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "create_test_sourcelist";} - + /** * Succinct documentation. */ @@ -49,7 +49,7 @@ public: { return "Create a test driver and source list for building test programs."; } - + /** * More documentation. */ @@ -81,7 +81,7 @@ public: "CMAKE_TESTDRIVER_AFTER_TESTMAIN can be set to have code that will be " "placed directly after the call to the test main function."; } - + cmTypeMacro(cmCreateTestSourceList, cmCommand); }; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index a650129..07df7d5 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -21,7 +21,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, const char* config, cmMakefile* mf): CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()), - GE(new cmGeneratorExpression(mf, config, cc.GetBacktrace())) + GE(new cmGeneratorExpression(cc.GetBacktrace())) { } @@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const { return target->GetLocation(this->Config); } - return this->GE->Process(argv0); + return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config); } //---------------------------------------------------------------------------- @@ -58,7 +58,8 @@ cmCustomCommandGenerator cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; for(unsigned int j=1;j < commandLine.size(); ++j) { - std::string arg = this->GE->Process(commandLine[j]); + std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile, + this->Config); cmd += " "; if(this->OldStyle) { diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h index 55ef521..b5175d5 100644 --- a/Source/cmDefinePropertyCommand.h +++ b/Source/cmDefinePropertyCommand.h @@ -17,7 +17,7 @@ class cmDefinePropertyCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmDefinePropertyCommand; } @@ -41,7 +41,7 @@ public: { return "Define and document custom properties."; } - + /** * Longer documentation. */ @@ -80,7 +80,7 @@ public: "Corresponding options to the get_property command will retrieve the " "documentation."; } - + cmTypeMacro(cmDefinePropertyCommand, cmCommand); private: std::string PropertyName; diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 9296d4c..74a0ccb 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -50,6 +50,7 @@ bool cmDepends::Write(std::ostream &makeDepends, std::vector<std::string> pairs; cmSystemTools::ExpandListArgument(srcStr, pairs); + std::map<std::string, std::set<std::string> > dependencies; for(std::vector<std::string>::iterator si = pairs.begin(); si != pairs.end();) { @@ -62,9 +63,14 @@ bool cmDepends::Write(std::ostream &makeDepends, obj = this->LocalGenerator->Convert(obj.c_str(), cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKEFILE); + dependencies[obj].insert(src); + } + for(std::map<std::string, std::set<std::string> >::const_iterator + it = dependencies.begin(); it != dependencies.end(); ++it) + { // Write the dependencies for this pair. - if(!this->WriteDependencies(src.c_str(), obj.c_str(), + if(!this->WriteDependencies(it->second, it->first, makeDepends, internalDepends)) { return false; @@ -98,7 +104,7 @@ bool cmDepends::Check(const char *makeFile, const char *internalFile, // Check whether dependencies must be regenerated. bool okay = true; std::ifstream fin(internalFile); - if(!(fin && this->CheckDependencies(fin, validDeps))) + if(!(fin && this->CheckDependencies(fin, internalFile, validDeps))) { // Clear all dependencies so they will be regenerated. this->Clear(makeFile); @@ -134,8 +140,9 @@ void cmDepends::Clear(const char *file) } //---------------------------------------------------------------------------- -bool cmDepends::WriteDependencies(const char*, const char*, - std::ostream&, std::ostream&) +bool cmDepends::WriteDependencies( + const std::set<std::string>&, const std::string&, + std::ostream&, std::ostream&) { // This should be implemented by the subclass. return false; @@ -143,6 +150,7 @@ bool cmDepends::WriteDependencies(const char*, const char*, //---------------------------------------------------------------------------- bool cmDepends::CheckDependencies(std::istream& internalDepends, + const char* internalDependsFileName, std::map<std::string, DependencyVector>& validDeps) { // Parse dependencies from the stream. If any dependee is missing @@ -154,7 +162,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, while(internalDepends.getline(this->Dependee, this->MaxPath)) { - if ( this->Dependee[0] == 0 || this->Dependee[0] == '#' || + if ( this->Dependee[0] == 0 || this->Dependee[0] == '#' || this->Dependee[0] == '\r' ) { continue; @@ -173,8 +181,10 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, // kdelibs/khtml this reduces the number of calls from 184k down to 92k, // or the time for cmake -E cmake_depends from 0.3 s down to 0.21 s. dependerExists = cmSystemTools::FileExists(this->Depender); - DependencyVector tmp; - validDeps[this->Depender] = tmp; + // If we erase validDeps[this->Depender] by overwriting it with an empty + // vector, we lose dependencies for dependers that have multiple + // entries. No need to initialize the entry, std::map will do so on first + // access. currentDependencies = &validDeps[this->Depender]; continue; } @@ -186,8 +196,11 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, } */ - // Dependencies must be regenerated if the dependee does not exist - // or if the depender exists and is older than the dependee. + // Dependencies must be regenerated + // * if the dependee does not exist + // * if the depender exists and is older than the dependee. + // * if the depender does not exist, but the dependee is newer than the + // depends file bool regenerate = false; const char* dependee = this->Dependee+1; const char* depender = this->Depender; @@ -211,24 +224,49 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, cmSystemTools::Stdout(msg.str().c_str()); } } - else if(dependerExists) + else { - // The dependee and depender both exist. Compare file times. - int result = 0; - if((!this->FileComparison->FileTimeCompare(depender, dependee, - &result) || result < 0)) + if(dependerExists) { - // The depender is older than the dependee. - regenerate = true; + // The dependee and depender both exist. Compare file times. + int result = 0; + if((!this->FileComparison->FileTimeCompare(depender, dependee, + &result) || result < 0)) + { + // The depender is older than the dependee. + regenerate = true; - // Print verbose output. - if(this->Verbose) + // Print verbose output. + if(this->Verbose) + { + cmOStringStream msg; + msg << "Dependee \"" << dependee + << "\" is newer than depender \"" + << depender << "\"." << std::endl; + cmSystemTools::Stdout(msg.str().c_str()); + } + } + } + else + { + // The dependee exists, but the depender doesn't. Regenerate if the + // internalDepends file is older than the dependee. + int result = 0; + if((!this->FileComparison->FileTimeCompare(internalDependsFileName, + dependee, &result) || result < 0)) { - cmOStringStream msg; - msg << "Dependee \"" << dependee - << "\" is newer than depender \"" - << depender << "\"." << std::endl; - cmSystemTools::Stdout(msg.str().c_str()); + // The depends-file is older than the dependee. + regenerate = true; + + // Print verbose output. + if(this->Verbose) + { + cmOStringStream msg; + msg << "Dependee \"" << dependee + << "\" is newer than depends file \"" + << internalDependsFileName << "\"." << std::endl; + cmSystemTools::Stdout(msg.str().c_str()); + } } } } diff --git a/Source/cmDepends.h b/Source/cmDepends.h index 087da64..d787edd 100644 --- a/Source/cmDepends.h +++ b/Source/cmDepends.h @@ -30,7 +30,7 @@ public: /** Instances need to know the build directory name and the relative path from the build directory to the target file. */ cmDepends(cmLocalGenerator* lg=0, const char* targetDir=""); - + /** at what level will the compile be done from */ void SetCompileDirectory(const char *dir) {this->CompileDirectory = dir;}; @@ -48,7 +48,7 @@ public: /** should this be verbose in its output */ void SetVerbose(bool verb) { this->Verbose = verb; } - + /** Virtual destructor to cleanup subclasses properly. */ virtual ~cmDepends(); @@ -69,20 +69,23 @@ public: void Clear(const char *file); /** Set the file comparison object */ - void SetFileComparison(cmFileTimeComparison* fc) { + void SetFileComparison(cmFileTimeComparison* fc) { this->FileComparison = fc; } protected: // Write dependencies for the target file to the given stream. // Return true for success and false for failure. - virtual bool WriteDependencies(const char *src, const char* obj, - std::ostream& makeDepends, std::ostream& internalDepends); + virtual bool WriteDependencies(const std::set<std::string>& sources, + const std::string& obj, + std::ostream& makeDepends, + std::ostream& internalDepends); // Check dependencies for the target file in the given stream. // Return false if dependencies must be regenerated and true // otherwise. virtual bool CheckDependencies(std::istream& internalDepends, + const char* internalDependsFileName, std::map<std::string, DependencyVector>& validDeps); // Finalize the dependency information for the target. diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index 44841a9..43b7b8a 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -98,176 +98,179 @@ cmDependsC::~cmDependsC() } //---------------------------------------------------------------------------- -bool cmDependsC::WriteDependencies(const char *src, const char *obj, - std::ostream& makeDepends, std::ostream& internalDepends) +bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, + const std::string& obj, + std::ostream& makeDepends, + std::ostream& internalDepends) { // Make sure this is a scanning instance. - if(!src || src[0] == '\0') + if(sources.empty() || sources.begin()->empty()) { cmSystemTools::Error("Cannot scan dependencies without a source file."); return false; } - if(!obj || obj[0] == '\0') + if(obj.empty()) { cmSystemTools::Error("Cannot scan dependencies without an object file."); return false; } + std::set<cmStdString> dependencies; + bool haveDeps = false; + if (this->ValidDeps != 0) { std::map<std::string, DependencyVector>::const_iterator tmpIt = this->ValidDeps->find(obj); if (tmpIt!= this->ValidDeps->end()) { - // Write the dependencies to the output stream. Makefile rules - // written by the original local generator for this directory - // convert the dependencies to paths relative to the home output - // directory. We must do the same here. - internalDepends << obj << std::endl; for(DependencyVector::const_iterator i=tmpIt->second.begin(); i != tmpIt->second.end(); ++i) { - makeDepends << obj << ": " << - this->LocalGenerator->Convert(i->c_str(), - cmLocalGenerator::HOME_OUTPUT, - cmLocalGenerator::MAKEFILE) - << std::endl; - internalDepends << " " << i->c_str() << std::endl; + dependencies.insert(*i); } - makeDepends << std::endl; - return true; + haveDeps = true; } } - // Walk the dependency graph starting with the source file. - bool first = true; - UnscannedEntry root; - root.FileName = src; - this->Unscanned.push(root); - this->Encountered.clear(); - this->Encountered.insert(src); - std::set<cmStdString> dependencies; - std::set<cmStdString> scanned; + if (!haveDeps) + { + // Walk the dependency graph starting with the source file. + int srcFiles = (int)sources.size(); + this->Encountered.clear(); + + for(std::set<std::string>::const_iterator srcIt = sources.begin(); + srcIt != sources.end(); ++srcIt) + { + UnscannedEntry root; + root.FileName = *srcIt; + this->Unscanned.push(root); + this->Encountered.insert(*srcIt); + } - // Use reserve to allocate enough memory for tempPathStr - // so that during the loops no memory is allocated or freed - std::string tempPathStr; - tempPathStr.reserve(4*1024); + std::set<cmStdString> scanned; - while(!this->Unscanned.empty()) - { - // Get the next file to scan. - UnscannedEntry current = this->Unscanned.front(); - this->Unscanned.pop(); + // Use reserve to allocate enough memory for tempPathStr + // so that during the loops no memory is allocated or freed + std::string tempPathStr; + tempPathStr.reserve(4*1024); - // If not a full path, find the file in the include path. - std::string fullName; - if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str())) + while(!this->Unscanned.empty()) { - if(cmSystemTools::FileExists(current.FileName.c_str(), true)) + // Get the next file to scan. + UnscannedEntry current = this->Unscanned.front(); + this->Unscanned.pop(); + + // If not a full path, find the file in the include path. + std::string fullName; + if((srcFiles>0) + || cmSystemTools::FileIsFullPath(current.FileName.c_str())) { - fullName = current.FileName; + if(cmSystemTools::FileExists(current.FileName.c_str(), true)) + { + fullName = current.FileName; + } } - } - else if(!current.QuotedLocation.empty() && - cmSystemTools::FileExists(current.QuotedLocation.c_str(), true)) - { - // The include statement producing this entry was a double-quote - // include and the included file is present in the directory of - // the source containing the include statement. - fullName = current.QuotedLocation; - } - else - { - std::map<cmStdString, cmStdString>::iterator - headerLocationIt=this->HeaderLocationCache.find(current.FileName); - if (headerLocationIt!=this->HeaderLocationCache.end()) + else if(!current.QuotedLocation.empty() && + cmSystemTools::FileExists(current.QuotedLocation.c_str(), true)) { - fullName=headerLocationIt->second; + // The include statement producing this entry was a double-quote + // include and the included file is present in the directory of + // the source containing the include statement. + fullName = current.QuotedLocation; } - else for(std::vector<std::string>::const_iterator i = - this->IncludePath.begin(); i != this->IncludePath.end(); ++i) + else { - // Construct the name of the file as if it were in the current - // include directory. Avoid using a leading "./". - - tempPathStr = ""; - if((*i) == ".") + std::map<cmStdString, cmStdString>::iterator + headerLocationIt=this->HeaderLocationCache.find(current.FileName); + if (headerLocationIt!=this->HeaderLocationCache.end()) { - tempPathStr += current.FileName; + fullName=headerLocationIt->second; } - else + else for(std::vector<std::string>::const_iterator i = + this->IncludePath.begin(); i != this->IncludePath.end(); ++i) { - tempPathStr += *i; - tempPathStr+="/"; - tempPathStr+=current.FileName; - } + // Construct the name of the file as if it were in the current + // include directory. Avoid using a leading "./". - // Look for the file in this location. - if(cmSystemTools::FileExists(tempPathStr.c_str(), true)) - { - fullName = tempPathStr; - HeaderLocationCache[current.FileName]=fullName; - break; + tempPathStr = ""; + if((*i) == ".") + { + tempPathStr += current.FileName; + } + else + { + tempPathStr += *i; + tempPathStr+="/"; + tempPathStr+=current.FileName; + } + + // Look for the file in this location. + if(cmSystemTools::FileExists(tempPathStr.c_str(), true)) + { + fullName = tempPathStr; + HeaderLocationCache[current.FileName]=fullName; + break; + } } } - } - - // Complain if the file cannot be found and matches the complain - // regex. - if(fullName.empty() && - this->IncludeRegexComplain.find(current.FileName.c_str())) - { - cmSystemTools::Error("Cannot find file \"", - current.FileName.c_str(), "\"."); - return false; - } - // Scan the file if it was found and has not been scanned already. - if(!fullName.empty() && (scanned.find(fullName) == scanned.end())) - { - // Record scanned files. - scanned.insert(fullName); + // Complain if the file cannot be found and matches the complain + // regex. + if(fullName.empty() && + this->IncludeRegexComplain.find(current.FileName.c_str())) + { + cmSystemTools::Error("Cannot find file \"", + current.FileName.c_str(), "\"."); + return false; + } - // Check whether this file is already in the cache - std::map<cmStdString, cmIncludeLines*>::iterator fileIt= - this->FileCache.find(fullName); - if (fileIt!=this->FileCache.end()) + // Scan the file if it was found and has not been scanned already. + if(!fullName.empty() && (scanned.find(fullName) == scanned.end())) { - fileIt->second->Used=true; - dependencies.insert(fullName); - for (std::vector<UnscannedEntry>::const_iterator incIt= - fileIt->second->UnscannedEntries.begin(); - incIt!=fileIt->second->UnscannedEntries.end(); ++incIt) + // Record scanned files. + scanned.insert(fullName); + + // Check whether this file is already in the cache + std::map<cmStdString, cmIncludeLines*>::iterator fileIt= + this->FileCache.find(fullName); + if (fileIt!=this->FileCache.end()) { - if (this->Encountered.find(incIt->FileName) == - this->Encountered.end()) + fileIt->second->Used=true; + dependencies.insert(fullName); + for (std::vector<UnscannedEntry>::const_iterator incIt= + fileIt->second->UnscannedEntries.begin(); + incIt!=fileIt->second->UnscannedEntries.end(); ++incIt) { - this->Encountered.insert(incIt->FileName); - this->Unscanned.push(*incIt); + if (this->Encountered.find(incIt->FileName) == + this->Encountered.end()) + { + this->Encountered.insert(incIt->FileName); + this->Unscanned.push(*incIt); + } } } - } - else - { - - // Try to scan the file. Just leave it out if we cannot find - // it. - std::ifstream fin(fullName.c_str()); - if(fin) + else { - // Add this file as a dependency. - dependencies.insert(fullName); - // Scan this file for new dependencies. Pass the directory - // containing the file to handle double-quote includes. - std::string dir = cmSystemTools::GetFilenamePath(fullName); - this->Scan(fin, dir.c_str(), fullName); + // Try to scan the file. Just leave it out if we cannot find + // it. + std::ifstream fin(fullName.c_str()); + if(fin) + { + // Add this file as a dependency. + dependencies.insert(fullName); + + // Scan this file for new dependencies. Pass the directory + // containing the file to handle double-quote includes. + std::string dir = cmSystemTools::GetFilenamePath(fullName); + this->Scan(fin, dir.c_str(), fullName); + } } } - } - first = false; + srcFiles--; + } } // Write the dependencies to the output stream. Makefile rules @@ -275,7 +278,7 @@ bool cmDependsC::WriteDependencies(const char *src, const char *obj, // convert the dependencies to paths relative to the home output // directory. We must do the same here. internalDepends << obj << std::endl; - for(std::set<cmStdString>::iterator i=dependencies.begin(); + for(std::set<cmStdString>::const_iterator i=dependencies.begin(); i != dependencies.end(); ++i) { makeDepends << obj << ": " << diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h index bd9a4b7..16dfad7 100644 --- a/Source/cmDependsC.h +++ b/Source/cmDependsC.h @@ -32,11 +32,9 @@ public: virtual ~cmDependsC(); protected: - typedef std::vector<char> t_CharBuffer; - // Implement writing/checking methods required by superclass. - virtual bool WriteDependencies(const char *src, - const char *file, + virtual bool WriteDependencies(const std::set<std::string>& sources, + const std::string& obj, std::ostream& makeDepends, std::ostream& internalDepends); @@ -82,7 +80,6 @@ protected: const std::map<std::string, DependencyVector>* ValidDeps; std::set<cmStdString> Encountered; std::queue<UnscannedEntry> Unscanned; - t_CharBuffer Buffer; std::map<cmStdString, cmIncludeLines *> FileCache; std::map<cmStdString, cmStdString> HeaderLocationCache; diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index c1b6090..e41e5ea 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -170,44 +170,50 @@ cmDependsFortran::~cmDependsFortran() } //---------------------------------------------------------------------------- -bool cmDependsFortran::WriteDependencies(const char *src, const char *obj, - std::ostream&, std::ostream&) +bool cmDependsFortran::WriteDependencies( + const std::set<std::string>& sources, const std::string& obj, + std::ostream&, std::ostream&) { // Make sure this is a scanning instance. - if(!src || src[0] == '\0') + if(sources.empty() || sources.begin()->empty()) { - cmSystemTools::Error("Cannot scan dependencies without an source file."); + cmSystemTools::Error("Cannot scan dependencies without a source file."); return false; } - if(!obj || obj[0] == '\0') + if(obj.empty()) { cmSystemTools::Error("Cannot scan dependencies without an object file."); return false; } - // Get the information object for this source. - cmDependsFortranSourceInfo& info = - this->Internal->CreateObjectInfo(obj, src); + bool okay = true; + for(std::set<std::string>::const_iterator it = sources.begin(); + it != sources.end(); ++it) + { + const std::string& src = *it; + // Get the information object for this source. + cmDependsFortranSourceInfo& info = + this->Internal->CreateObjectInfo(obj.c_str(), src.c_str()); - // Make a copy of the macros defined via ADD_DEFINITIONS - std::set<std::string> ppDefines(this->PPDefinitions.begin(), - this->PPDefinitions.end()); + // Make a copy of the macros defined via ADD_DEFINITIONS + std::set<std::string> ppDefines(this->PPDefinitions.begin(), + this->PPDefinitions.end()); - // Create the parser object. The constructor takes ppMacro and info per - // reference, so we may look into the resulting objects later. - cmDependsFortranParser parser(this, ppDefines, info); + // Create the parser object. The constructor takes ppMacro and info per + // reference, so we may look into the resulting objects later. + cmDependsFortranParser parser(this, ppDefines, info); - // Push on the starting file. - cmDependsFortranParser_FilePush(&parser, src); + // Push on the starting file. + cmDependsFortranParser_FilePush(&parser, src.c_str()); - // Parse the translation unit. - if(cmDependsFortran_yyparse(parser.Scanner) != 0) - { - // Failed to parse the file. Report failure to write dependencies. - return false; + // Parse the translation unit. + if(cmDependsFortran_yyparse(parser.Scanner) != 0) + { + // Failed to parse the file. Report failure to write dependencies. + okay = false; + } } - - return true; + return okay; } //---------------------------------------------------------------------------- @@ -889,7 +895,7 @@ bool cmDependsFortran::FindIncludeFile(const char* dir, } // Search the include path for the file. - for(std::vector<std::string>::const_iterator i = + for(std::vector<std::string>::const_iterator i = this->IncludePath.begin(); i != this->IncludePath.end(); ++i) { fullName = *i; diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h index cdfde6e..cb40796 100644 --- a/Source/cmDependsFortran.h +++ b/Source/cmDependsFortran.h @@ -66,7 +66,7 @@ protected: // Implement writing/checking methods required by superclass. virtual bool WriteDependencies( - const char *src, const char *file, + const std::set<std::string>& sources, const std::string& file, std::ostream& makeDepends, std::ostream& internalDepends); // Actually write the depenencies to the streams. diff --git a/Source/cmDependsJava.cxx b/Source/cmDependsJava.cxx index 1d84914..949d465 100644 --- a/Source/cmDependsJava.cxx +++ b/Source/cmDependsJava.cxx @@ -25,11 +25,11 @@ cmDependsJava::~cmDependsJava() } //---------------------------------------------------------------------------- -bool cmDependsJava::WriteDependencies(const char *src, const char *, - std::ostream&, std::ostream&) +bool cmDependsJava::WriteDependencies(const std::set<std::string>& sources, + const std::string&, std::ostream&, std::ostream&) { // Make sure this is a scanning instance. - if(!src || src[0] == '\0') + if(sources.empty() || sources.begin()->empty()) { cmSystemTools::Error("Cannot scan dependencies without an source file."); return false; @@ -38,7 +38,7 @@ bool cmDependsJava::WriteDependencies(const char *src, const char *, return true; } -bool cmDependsJava::CheckDependencies(std::istream&, +bool cmDependsJava::CheckDependencies(std::istream&, const char*, std::map<std::string, DependencyVector >&) { return true; diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h index fe6fef5..22af53f 100644 --- a/Source/cmDependsJava.h +++ b/Source/cmDependsJava.h @@ -29,10 +29,12 @@ public: protected: // Implement writing/checking methods required by superclass. - virtual bool WriteDependencies(const char *src, const char *file, + virtual bool WriteDependencies( + const std::set<std::string>& sources, const std::string& file, std::ostream& makeDepends, std::ostream& internalDepends); virtual bool CheckDependencies(std::istream& internalDepends, - std::map<std::string, DependencyVector >& validDeps); + const char* internalDependsFileName, + std::map<std::string, DependencyVector>& validDeps); private: cmDependsJava(cmDependsJava const&); // Purposely not implemented. diff --git a/Source/cmDependsJavaLexer.h b/Source/cmDependsJavaLexer.h index 09c19bf..61aa66d 100644 --- a/Source/cmDependsJavaLexer.h +++ b/Source/cmDependsJavaLexer.h @@ -58,7 +58,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ @@ -188,7 +188,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ diff --git a/Source/cmDependsJavaLexer.in.l b/Source/cmDependsJavaLexer.in.l index aae7ec6..9796ad5 100644 --- a/Source/cmDependsJavaLexer.in.l +++ b/Source/cmDependsJavaLexer.in.l @@ -171,18 +171,18 @@ null { PRIMITIVE; return jp_NULLLITERAL; } "\*" { SYMBOL; return jp_TIMES; } "\*=" { SYMBOL; return jp_TIMESEQUALS; } -[a-z_A-Z][a-z_0-9A-Z]* { - yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); - return jp_NAME; +[a-z_A-Z][a-z_0-9A-Z]* { + yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext)); + return jp_NAME; } \/\/.*\n { } [ \f\t\n\r] { } -. { - std::cerr << "Unknown character: " << yytext[0] - << " (" << (int)yytext[0] << ")" << std::endl; - yyextra->Error("Unknown character"); - return jp_ERROR; +. { + std::cerr << "Unknown character: " << yytext[0] + << " (" << (int)yytext[0] << ")" << std::endl; + yyextra->Error("Unknown character"); + return jp_ERROR; } %% diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx index 7b595cc..6136baa 100644 --- a/Source/cmDependsJavaParserHelper.cxx +++ b/Source/cmDependsJavaParserHelper.cxx @@ -35,7 +35,7 @@ cmDependsJavaParserHelper::~cmDependsJavaParserHelper() } void cmDependsJavaParserHelper::CurrentClass -::AddFileNamesForPrinting(std::vector<cmStdString> *files, +::AddFileNamesForPrinting(std::vector<cmStdString> *files, const char* prefix, const char* sep) { cmStdString rname = ""; @@ -103,7 +103,7 @@ void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass) this->PackagesImport.push_back(sclass); } -void cmDependsJavaParserHelper::SafePrintMissing(const char* str, +void cmDependsJavaParserHelper::SafePrintMissing(const char* str, int line, int cnt) { if ( str ) @@ -134,7 +134,7 @@ void cmDependsJavaParserHelper::Print(const char* place, const char* str) } } -void cmDependsJavaParserHelper::CombineUnions(char** out, +void cmDependsJavaParserHelper::CombineUnions(char** out, const char* in1, char** in2, const char* sep) { @@ -193,7 +193,7 @@ void cmDependsJavaParserHelper } void cmDependsJavaParserHelper -::AllocateParserType(cmDependsJavaParserHelper::ParserType* pt, +::AllocateParserType(cmDependsJavaParserHelper::ParserType* pt, const char* str, int len) { pt->str = 0; @@ -270,7 +270,7 @@ std::vector<cmStdString> cmDependsJavaParserHelper::GetFilesProduced() std::vector<cmStdString> files; CurrentClass* toplevel = &(*(this->ClassStack.begin())); std::vector<CurrentClass>::iterator it; - for ( it = toplevel->NestedClasses->begin(); + for ( it = toplevel->NestedClasses->begin(); it != toplevel->NestedClasses->end(); ++ it ) { @@ -289,7 +289,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) this->InputBuffer = str; this->InputBufferPos = 0; this->CurrentLine = 0; - + yyscan_t yyscanner; cmDependsJava_yylex_init(&yyscanner); @@ -306,7 +306,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) { if ( this->CurrentPackage.size() > 0 ) { - std::cout << "Current package is: " << + std::cout << "Current package is: " << this->CurrentPackage.c_str() << std::endl; } std::cout << "Imports packages:"; @@ -337,7 +337,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) this->PrintClasses(); if ( this->UnionsAvailable != 0 ) { - std::cout << "There are still " << + std::cout << "There are still " << this->UnionsAvailable << " unions available" << std::endl; } } @@ -348,13 +348,13 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) void cmDependsJavaParserHelper::CleanupParser() { std::vector<char*>::iterator it; - for ( it = this->Allocates.begin(); + for ( it = this->Allocates.begin(); it != this->Allocates.end(); ++ it ) { delete [] *it; } - this->Allocates.erase(this->Allocates.begin(), + this->Allocates.erase(this->Allocates.begin(), this->Allocates.end()); } @@ -382,11 +382,11 @@ int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen) void cmDependsJavaParserHelper::Error(const char* str) { unsigned long pos = static_cast<unsigned long>(this->InputBufferPos); - fprintf(stderr, "JPError: %s (%lu / Line: %d)\n", + fprintf(stderr, "JPError: %s (%lu / Line: %d)\n", str, pos, this->CurrentLine); int cc; std::cerr << "String: ["; - for ( cc = 0; + for ( cc = 0; cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc); cc ++ ) { @@ -395,7 +395,7 @@ void cmDependsJavaParserHelper::Error(const char* str) std::cerr << "]" << std::endl; } -void cmDependsJavaParserHelper::UpdateCombine(const char* str1, +void cmDependsJavaParserHelper::UpdateCombine(const char* str1, const char* str2) { if ( this->CurrentCombine == "" && str1 != 0) diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h index baecab3..9807a04 100644 --- a/Source/cmDependsJavaParserHelper.h +++ b/Source/cmDependsJavaParserHelper.h @@ -9,7 +9,7 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef cmDependsJavaParserHelper_h +#ifndef cmDependsJavaParserHelper_h #define cmDependsJavaParserHelper_h #include "cmStandardIncludes.h" @@ -39,7 +39,7 @@ public: int ParseFile(const char* file); // For the lexer: - void AllocateParserType(cmDependsJavaParserHelper::ParserType* pt, + void AllocateParserType(cmDependsJavaParserHelper::ParserType* pt, const char* str, int len = 0); int LexInput(char* buf, int maxlen); @@ -69,7 +69,7 @@ private: public: cmStdString Name; std::vector<CurrentClass>* NestedClasses; - CurrentClass() + CurrentClass() { this->NestedClasses = new std::vector<CurrentClass>; } @@ -77,7 +77,7 @@ private: { delete this->NestedClasses; } - CurrentClass& operator=(CurrentClass const& c) + CurrentClass& operator=(CurrentClass const& c) { this->NestedClasses->clear(); this->Name = c.Name; @@ -93,7 +93,7 @@ private: { (*this) = c; } - void AddFileNamesForPrinting(std::vector<cmStdString> *files, + void AddFileNamesForPrinting(std::vector<cmStdString> *files, const char* prefix, const char* sep); }; cmStdString CurrentPackage; @@ -117,7 +117,7 @@ private: void PrintClasses(); void Print(const char* place, const char* str); - void CombineUnions(char** out, const char* in1, char** in2, + void CombineUnions(char** out, const char* in1, char** in2, const char* sep); void SafePrintMissing(const char* str, int line, int cnt); diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 5359013..445fd0e 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -12,11 +12,20 @@ #ifndef cmDocumentGeneratorExpressions_h #define cmDocumentGeneratorExpressions_h -#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \ +#define CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \ "Generator expressions are evaluted during build system generation " \ "to produce information specific to each build configuration. " \ "Valid expressions are:\n" \ + " $<0:...> = empty string (ignores \"...\")\n" \ + " $<1:...> = content of \"...\"\n" \ + " $<CONFIG:cfg> = '1' if config is \"cfg\", else '0'\n" \ " $<CONFIGURATION> = configuration name\n" \ + " $<BOOL:...> = '1' if the '...' is true, else '0'\n" \ + " $<STREQUAL:a,b> = '1' if a is STREQUAL b, else '0'\n" \ + " $<ANGLE-R> = A literal '>'. Used to compare " \ + "strings which contain a '>' for example.\n" \ + " $<COMMA> = A literal ','. Used to compare " \ + "strings which contain a ',' for example.\n" \ " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \ " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \ " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \ @@ -25,6 +34,23 @@ "versions can produce the directory and file name components:\n" \ " $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" \ " $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \ - " $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" + " $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \ + "\n" \ + " $<TARGET_PROPERTY:tgt,prop> = The value of the property prop\n" \ + "on the target tgt. Note that tgt is not added as a dependency of\n" \ + "the target this expression is evaluated on.\n" \ + "Boolean expressions:\n" \ + " $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \ + " $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \ + " $<NOT:?> = '0' if '?' is '1', else '1'\n" \ + "where '?' is always either '0' or '1'.\n" \ + "" + +#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \ + CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \ + "Expressions with an implicit 'this' target:\n" \ + " $<TARGET_PROPERTY:prop> = The value of the property prop on\n" \ + "the target on which the generator expression is evaluated.\n" \ + "" #endif diff --git a/Source/cmDocumentLocationUndefined.h b/Source/cmDocumentLocationUndefined.h index d1be77a..9aecf21 100644 --- a/Source/cmDocumentLocationUndefined.h +++ b/Source/cmDocumentLocationUndefined.h @@ -16,8 +16,8 @@ "\n" \ "Do not set properties that affect the location of a target after " \ action ". These include properties whose names match " \ - "\"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?\" " \ - "or \"(IMPLIB_)?(PREFIX|SUFFIX)\". " \ + "\"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?\", " \ + "\"(IMPLIB_)?(PREFIX|SUFFIX)\", or \"LINKER_LANGUAGE\". " \ "Failure to follow this rule is not diagnosed and leaves the location " \ "of the target undefined." diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 9e33d75..8db0e8f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1,6 +1,8 @@ #include "cmDocumentVariables.h" #include "cmake.h" +#include <cmsys/ios/sstream> + void cmDocumentVariables::DefineVariables(cmake* cm) { // Subsection: variables defined by cmake, that give @@ -218,7 +220,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Full path to ctest command installed with cmake.", "This is the full path to the CTest executable ctest " "which is useful from custom commands that want " - " to use the cmake -E option for portable system " + "to use the cmake -E option for portable system " "commands.",false, "Variables that Provide Information"); @@ -283,6 +285,16 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "see CMAKE_BUILD_TOOL.",false, "Variables that Provide Information"); cm->DefineProperty + ("CMAKE_VS_PLATFORM_TOOLSET", cmProperty::VARIABLE, + "Visual Studio Platform Toolset name.", + "VS 10 and above use MSBuild under the hood and support multiple " + "compiler toolchains. " + "CMake may specify a toolset explicitly, such as \"v110\" for " + "VS 11 or \"Windows7.1SDK\" for 64-bit support in VS 10 Express. " + "CMake provides the name of the chosen toolset in this variable." + ,false, + "Variables that Provide Information"); + cm->DefineProperty ("CMAKE_MINOR_VERSION", cmProperty::VARIABLE, "The Minor version of cmake (i.e. the 4 in X.4.X).", "This specifies the minor version of the CMake" @@ -355,7 +367,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "If this is set to TRUE, then the rpath information " "is not added to compiled executables. The default " "is to add rpath information if the platform supports it. " - "This allows for easy running from the build tree. To omit RPATH" + "This allows for easy running from the build tree. To omit RPATH " "in the install step, but not the build step, use " "CMAKE_SKIP_INSTALL_RPATH instead.",false, "Variables that Provide Information"); @@ -373,12 +385,6 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "into all executables and libraries.",false, "Variables that Provide Information"); cm->DefineProperty - ("CMAKE_USING_VC_FREE_TOOLS", cmProperty::VARIABLE, - "True if free visual studio tools being used.", - "This is set to true if the compiler is Visual " - "Studio free tools.",false, - "Variables that Provide Information"); - cm->DefineProperty ("CMAKE_VERBOSE_MAKEFILE", cmProperty::VARIABLE, "Create verbose makefiles if on.", "This variable defaults to false. You can set " @@ -595,7 +601,21 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "If \"make install\" is invoked or INSTALL is built" ", this directory is pre-pended onto all install " "directories. This variable defaults to /usr/local" - " on UNIX and c:/Program Files on Windows.",false, + " on UNIX and c:/Program Files on Windows.\n" + "On UNIX one can use the DESTDIR mechanism in order" + " to relocate the whole installation. " + "DESTDIR means DESTination DIRectory. It is " + "commonly used by makefile users " + "in order to install software at non-default location. " + "It is usually invoked like this:\n" + " make DESTDIR=/home/john install\n" + "which will install the concerned software using the" + " installation prefix, e.g. \"/usr/local\" pre-pended with " + "the DESTDIR value which finally gives \"/home/john/usr/local\".\n" + "WARNING: DESTDIR may not be used on Windows because installation" + " prefix usually contains a drive letter like in \"C:/Program Files\"" + " which cannot be pre-pended with some other prefix." + ,false, "Variables That Change Behavior"); cm->DefineProperty @@ -681,7 +701,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cm->DefineProperty ("CMAKE_SYSTEM_IGNORE_PATH", cmProperty::VARIABLE, "Path to be ignored by FIND_XXX() commands.", - "Specifies directories to be ignored by searches in FIND_XXX() commands " + "Specifies directories to be ignored by searches in FIND_XXX() " + "commands. " "This is useful in cross-compiled environments where some system " "directories contain incompatible but possibly linkable libraries. For " "example, on cross-compiled cluster environments, this allows a user to " @@ -696,7 +717,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cm->DefineProperty ("CMAKE_IGNORE_PATH", cmProperty::VARIABLE, "Path to be ignored by FIND_XXX() commands.", - "Specifies directories to be ignored by searches in FIND_XXX() commands " + "Specifies directories to be ignored by searches in FIND_XXX() " + "commands. " "This is useful in cross-compiled environments where some system " "directories contain incompatible but possibly linkable libraries. For " "example, on cross-compiled cluster environments, this allows a user to " @@ -827,13 +849,13 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Tell cmake to use MFC for an executable or dll.", "This can be set in a CMakeLists.txt file and will " "enable MFC in the application. It should be set " - "to 1 for static the static MFC library, and 2 for " - "the shared MFC library. This is used in visual " - "studio 6 and 7 project files. The CMakeSetup " + "to 1 for the static MFC library, and 2 for " + "the shared MFC library. This is used in Visual " + "Studio 6 and 7 project files. The CMakeSetup " "dialog used MFC and the CMakeLists.txt looks like this:\n" - "add_definitions(-D_AFXDLL)\n" - "set(CMAKE_MFC_FLAG 2)\n" - "add_executable(CMakeSetup WIN32 ${SRCS})\n",false, + " add_definitions(-D_AFXDLL)\n" + " set(CMAKE_MFC_FLAG 2)\n" + " add_executable(CMakeSetup WIN32 ${SRCS})\n",false, "Variables That Change Behavior"); cm->DefineProperty @@ -974,12 +996,33 @@ void cmDocumentVariables::DefineVariables(cmake* cm) false, "Variables That Describe the System"); - cm->DefineProperty - ("MSVC80", cmProperty::VARIABLE, - "True when using Microsoft Visual C 8.0", - "Set to true when the compiler is version 8.0 of Microsoft Visual C.", - false, - "Variables That Describe the System"); + int msvc_versions[] = { 60, 70, 71, 80, 90, 100, 110, 0 }; + for (int i = 0; msvc_versions[i] != 0; i ++) + { + const char minor = (char)('0' + (msvc_versions[i] % 10)); + cmStdString varName = "MSVC"; + cmsys_ios::ostringstream majorStr; + + majorStr << (msvc_versions[i] / 10); + varName += majorStr.str(); + if (msvc_versions[i] < 100) + { + varName += minor; + } + + cmStdString verString = majorStr.str() + "." + minor; + + cmStdString shortStr = "True when using Microsoft Visual C " + verString; + cmStdString fullStr = "Set to true when the compiler is version " + + verString + + " of Microsoft Visual C."; + cm->DefineProperty + (varName.c_str(), cmProperty::VARIABLE, + shortStr.c_str(), + fullStr.c_str(), + false, + "Variables That Describe the System"); + } cm->DefineProperty ("MSVC_IDE", cmProperty::VARIABLE, @@ -999,6 +1042,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) " 1400 = VS 8.0\n" " 1500 = VS 9.0\n" " 1600 = VS 10.0\n" + " 1700 = VS 11.0\n" "", false, "Variables That Describe the System"); @@ -1169,6 +1213,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE, + "Where to put all the MS debug symbol files.", + "This variable is used to initialize the " + "PDB_OUTPUT_DIRECTORY property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_AUTOMOC", cmProperty::VARIABLE, "Whether to handle moc automatically for Qt targets.", "This variable is used to initialize the " @@ -1350,6 +1403,14 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "See that target property for additional information.", false, "Variables that Control the Build"); + cm->DefineProperty + ("CMAKE_POSITION_INDEPENDENT_CODE", cmProperty::VARIABLE, + "Default value for POSITION_INDEPENDENT_CODE of targets.", + "This variable is used to initialize the " + "POSITION_INDEPENDENT_CODE property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); // Variables defined when the a language is enabled These variables will // also be defined whenever CMake has loaded its support for compiling (LANG) @@ -1373,8 +1434,30 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cm->DefineProperty ("CMAKE_<LANG>_COMPILER_ID", cmProperty::VARIABLE, - "An internal variable subject to change.", - "This is used in determining the compiler and is subject to change.", + "Compiler identification string.", + "A short string unique to the compiler vendor. " + "Possible values include:\n" + " Absoft = Absoft Fortran (absoft.com)\n" + " ADSP = Analog VisualDSP++ (analog.com)\n" + " Clang = LLVM Clang (clang.llvm.org)\n" + " Cray = Cray Compiler (cray.com)\n" + " Embarcadero, Borland = Embarcadero (embarcadero.com)\n" + " G95 = G95 Fortran (g95.org)\n" + " GNU = GNU Compiler Collection (gcc.gnu.org)\n" + " HP = Hewlett-Packard Compiler (hp.com)\n" + " Intel = Intel Compiler (intel.com)\n" + " MIPSpro = SGI MIPSpro (sgi.com)\n" + " MSVC = Microsoft Visual Studio (microsoft.com)\n" + " PGI = The Portland Group (pgroup.com)\n" + " PathScale = PathScale (pathscale.com)\n" + " SDCC = Small Device C Compiler (sdcc.sourceforge.net)\n" + " SunPro = Oracle Solaris Studio (oracle.com)\n" + " TI_DSP = Texas Instruments (ti.com)\n" + " TinyCC = Tiny C Compiler (tinycc.org)\n" + " Watcom = Open Watcom (openwatcom.org)\n" + " XL, VisualAge, zOS = IBM XL (ibm.com)\n" + "This variable is not guaranteed to be defined for all " + "compilers or languages.", false, "Variables for Languages"); @@ -1394,10 +1477,10 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cm->DefineProperty ("CMAKE_<LANG>_COMPILER_VERSION", cmProperty::VARIABLE, - "An internal variable subject to change.", + "Compiler version string.", "Compiler version in major[.minor[.patch[.tweak]]] format. " - "This variable is reserved for internal use by CMake and is not " - "guaranteed to be set.", + "This variable is not guaranteed to be defined for all " + "compilers or languages.", false, "Variables for Languages"); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 904a157..debde3b 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -148,13 +148,6 @@ static const char *cmDocumentationStandardSeeAlso[][3] = "The list is member-post-only but one may sign up on the CMake web page. " "Please first read the full documentation at " "http://www.cmake.org before posting questions to the list."}, - {0, - "Summary of helpful links:\n" - " Home: http://www.cmake.org\n" - " Docs: http://www.cmake.org/HTML/Documentation.html\n" - " Mail: http://www.cmake.org/HTML/MailingLists.html\n" - " FAQ: http://www.cmake.org/Wiki/CMake_FAQ\n" - , 0}, {0,0,0} }; @@ -162,7 +155,7 @@ static const char *cmDocumentationStandardSeeAlso[][3] = static const char *cmDocumentationCopyright[][3] = { {0, - "Copyright 2000-2009 Kitware, Inc., Insight Software Consortium. " + "Copyright 2000-2012 Kitware, Inc., Insight Software Consortium. " "All rights reserved.", 0}, {0, "Redistribution and use in source and binary forms, with or without " @@ -221,7 +214,7 @@ DOCUMENT_INTRO(CompatCommands, "cmakecompat", cmDocumentation::cmDocumentation() :CurrentFormatter(0) { - this->SetForm(TextForm); + this->SetForm(TextForm, 0); this->addCommonStandardDocSections(); this->ShowGenerators = true; } @@ -594,7 +587,7 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) i != this->RequestedHelpItems.end(); ++i) { - this->SetForm(i->HelpForm); + this->SetForm(i->HelpForm, i->ManSection); this->CurrentArgument = i->Argument; // If a file name was given, use it. Otherwise, default to the // given stream. @@ -642,7 +635,8 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) cmDocumentation::Form cmDocumentation::GetFormFromFilename( - const std::string& filename) + const std::string& filename, + int* manSection) { std::string ext = cmSystemTools::GetFilenameLastExtension(filename); ext = cmSystemTools::UpperCase(ext); @@ -659,6 +653,10 @@ cmDocumentation::Form cmDocumentation::GetFormFromFilename( // ".1" to ".9" should be manpages if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9')) { + if (manSection) + { + *manSection = ext[1] - '0'; + } return cmDocumentation::ManForm; } @@ -1128,49 +1126,57 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, { help.HelpType = cmDocumentation::Properties; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-policies") == 0) { help.HelpType = cmDocumentation::Policies; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-variables") == 0) { help.HelpType = cmDocumentation::Variables; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-modules") == 0) { help.HelpType = cmDocumentation::Modules; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-custom-modules") == 0) { help.HelpType = cmDocumentation::CustomModules; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-commands") == 0) { help.HelpType = cmDocumentation::Commands; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-compatcommands") == 0) { help.HelpType = cmDocumentation::CompatCommands; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-full") == 0) { help.HelpType = cmDocumentation::Full; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-html") == 0) { @@ -1183,6 +1189,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, help.HelpType = cmDocumentation::Full; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::ManForm; + help.ManSection = 1; } else if(strcmp(argv[i], "--help-command") == 0) { @@ -1190,35 +1197,40 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.Argument = cmSystemTools::LowerCase(help.Argument); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-module") == 0) { help.HelpType = cmDocumentation::SingleModule; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-property") == 0) { help.HelpType = cmDocumentation::SingleProperty; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-policy") == 0) { help.HelpType = cmDocumentation::SinglePolicy; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-variable") == 0) { help.HelpType = cmDocumentation::SingleVariable; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-command-list") == 0) { @@ -1269,9 +1281,9 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } //---------------------------------------------------------------------------- -void cmDocumentation::Print(Form f, std::ostream& os) +void cmDocumentation::Print(Form f, int manSection, std::ostream& os) { - this->SetForm(f); + this->SetForm(f, manSection); this->Print(os); } @@ -1879,7 +1891,7 @@ void cmDocumentation::CreateFullDocumentation() } //---------------------------------------------------------------------------- -void cmDocumentation::SetForm(Form f) +void cmDocumentation::SetForm(Form f, int manSection) { switch(f) { @@ -1890,6 +1902,7 @@ void cmDocumentation::SetForm(Form f) this->CurrentFormatter = &this->DocbookFormatter; break; case ManForm: + this->ManFormatter.SetManSection(manSection); this->CurrentFormatter = &this->ManFormatter; break; case TextForm: diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 11bef16..e180f60 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -33,7 +33,7 @@ class cmDocumentation: public cmDocumentationEnums { public: cmDocumentation(); - + ~cmDocumentation(); /** @@ -51,18 +51,18 @@ public: typedef std::list<documentedModuleSectionPair_t> documentedModulesList_t; // High-level interface for standard documents: - + /** * Check command line arguments for documentation options. Returns * true if documentation options are found, and false otherwise. * When true is returned, PrintRequestedDocumentation should be - * called. exitOpt can be used for things like cmake -E, so that + * called. exitOpt can be used for things like cmake -E, so that * all arguments after the -E are ignored and not searched for * help arguments. */ - bool CheckOptions(int argc, const char* const* argv, + bool CheckOptions(int argc, const char* const* argv, const char* exitOpt =0); - + /** * Print help requested on the command line. Call after * CheckOptions returns true. Returns true on success, and false @@ -70,12 +70,12 @@ public: * command line cannot be written. */ bool PrintRequestedDocumentation(std::ostream& os); - + /** Print help of the given type. */ bool PrintDocumentation(Type ht, std::ostream& os, const char* docname=0); void SetShowGenerators(bool showGen) { this->ShowGenerators = showGen; } - + /** Set the program name for standard document generation. */ void SetName(const char* name); @@ -108,8 +108,8 @@ public: * Print documentation in the given form. All previously added * sections will be generated. */ - void Print(Form f, std::ostream& os); - + void Print(Form f, int manSection, std::ostream& os); + /** * Print documentation in the current form. All previously added * sections will be generated. @@ -125,15 +125,16 @@ public: void SetSeeAlsoList(const char *data[][3]); /** Clear all previously added sections of help. */ - void ClearSections(); - + void ClearSections(); + /** Set cmake root so we can find installed files */ void SetCMakeRoot(const char* root) { this->CMakeRoot = root;} /** Set CMAKE_MODULE_PATH so we can find additional cmake modules */ void SetCMakeModulePath(const char* path) { this->CMakeModulePath = path;} - - static Form GetFormFromFilename(const std::string& filename); + + static Form GetFormFromFilename(const std::string& filename, + int* ManSection); /** Add common (to all tools) documentation section(s) */ void addCommonStandardDocSections(); @@ -190,13 +191,13 @@ public: std::vector<cmDocumentationEntry>& commands, cmake* cm); private: - void SetForm(Form f); + void SetForm(Form f, int manSection); void SetDocName(const char* docname); - bool CreateSingleModule(const char* fname, + bool CreateSingleModule(const char* fname, const char* moduleName, cmDocumentationSection &sec); - void CreateModuleDocsForDir(cmsys::Directory& dir, + void CreateModuleDocsForDir(cmsys::Directory& dir, cmDocumentationSection &moduleSection); bool CreateModulesSection(); bool CreateCustomModulesSection(); @@ -236,7 +237,7 @@ private: std::string NameString; std::string DocName; std::map<std::string,cmDocumentationSection*> AllSections; - + std::string SeeAlsoString; std::string CMakeRoot; std::string CMakeModulePath; @@ -247,11 +248,12 @@ private: struct RequestedHelpItem { - RequestedHelpItem():HelpForm(TextForm), HelpType(None) {} + RequestedHelpItem():HelpForm(TextForm), HelpType(None), ManSection(1) {} cmDocumentationEnums::Form HelpForm; cmDocumentationEnums::Type HelpType; std::string Filename; std::string Argument; + int ManSection; }; std::vector<RequestedHelpItem> RequestedHelpItems; diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index 6762d66..9f01949 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx @@ -19,7 +19,7 @@ cmDocumentationFormatter::~cmDocumentationFormatter() { } -void cmDocumentationFormatter::PrintFormatted(std::ostream& os, +void cmDocumentationFormatter::PrintFormatted(std::ostream& os, const char* text) { if(!text) diff --git a/Source/cmDocumentationFormatterDocbook.cxx b/Source/cmDocumentationFormatterDocbook.cxx index 3087330..706ce0a 100644 --- a/Source/cmDocumentationFormatterDocbook.cxx +++ b/Source/cmDocumentationFormatterDocbook.cxx @@ -11,6 +11,14 @@ ============================================================================*/ #include "cmDocumentationFormatterDocbook.h" #include "cmDocumentationSection.h" +#include <algorithm> +#include <ctype.h> // for isalnum + +static int cmIsAlnum(int c) +{ + return isalnum(c); +} + //---------------------------------------------------------------------------- // this function is a copy of the one in the HTML formatter @@ -34,7 +42,7 @@ static void cmDocumentationPrintDocbookChar(std::ostream& os, char c) case '<': os << "<"; break; - case '>': + case '>': os << ">"; break; case '&': @@ -94,151 +102,116 @@ void cmDocumentationPrintDocbookEscapes(std::ostream& os, const char* text) } } - +//---------------------------------------------------------------------------- cmDocumentationFormatterDocbook::cmDocumentationFormatterDocbook() :cmDocumentationFormatter() { } +//---------------------------------------------------------------------------- void cmDocumentationFormatterDocbook ::PrintSection(std::ostream& os, const cmDocumentationSection §ion, const char* name) { - if(name) - { - std::string id = "section_"; - id += name; - if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end()) - { - this->EmittedLinkIds.insert(id); - os << "<sect1 id=\"section_" << name << "\">\n" - "<title>\n" << name << "</title>\n"; - } - else - { - static unsigned int i=0; - i++; - os << "<sect1 id=\"section_" << name << i << "\">\n" - "<title>\n" << name << "</title>\n"; - } - } + os << "<sect1 id=\""; + this->PrintId(os, 0, name); + os << "\">\n<title>" << name << "</title>\n"; std::string prefix = this->ComputeSectionLinkPrefix(name); + const std::vector<cmDocumentationEntry> &entries = section.GetEntries(); - const std::vector<cmDocumentationEntry> &entries = - section.GetEntries(); - - if (!entries.empty()) + bool hasSubSections = false; + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + op != entries.end(); ++op) { - os << "<itemizedlist>\n"; - for(std::vector<cmDocumentationEntry>::const_iterator op - = entries.begin(); op != entries.end(); ++ op ) + if(op->Name.size()) { - if(op->Name.size()) - { - os << " <listitem><link linkend=\"" << prefix << "_"; - cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); - os << "\"><emphasis><literal>"; - cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); - os << "</literal></emphasis></link></listitem>\n"; - } + hasSubSections = true; + break; } - os << "</itemizedlist>\n" ; } - for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); - op != entries.end();) + bool inAbstract = false; + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + op != entries.end(); ++op) { if(op->Name.size()) { - for(;op != entries.end() && op->Name.size(); ++op) + if(inAbstract) { - if(op->Name.size()) - { - os << " <para id=\"" << prefix << "_"; - cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); - - // make sure that each id exists only once. Since it seems - // not easily possible to determine which link refers to which id, - // we have at least to make sure that the duplicated id's get a - // different name (by appending an increasing number), Alex - std::string id = prefix; - id += "_"; - id += op->Name; - if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end()) - { - this->EmittedLinkIds.insert(id); - } - else - { - static unsigned int i=0; - i++; - os << i; - } - // continue as normal... - - os << "\"><sect2><title>"; - cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); - os << "</title></sect2> "; - } + os << "</abstract>\n"; + inAbstract = false; + } + os << "<sect2 id=\""; + this->PrintId(os, prefix.c_str(), op->Name); + os << "\">\n<title>"; + cmDocumentationPrintDocbookEscapes(os, op->Name.c_str()); + os << "</title>\n"; + if(op->Full.size()) + { + os << "<abstract>\n<para>"; cmDocumentationPrintDocbookEscapes(os, op->Brief.c_str()); - if(op->Name.size()) - { - os << "</para>\n"; - } - - if(op->Full.size()) - { - // a line break seems to be simply a line break with docbook - os << "\n "; - this->PrintFormatted(os, op->Full.c_str()); - } - os << "\n"; + os << "</para>\n</abstract>\n"; + this->PrintFormatted(os, op->Full.c_str()); } + else + { + this->PrintFormatted(os, op->Brief.c_str()); + } + os << "</sect2>\n"; } else { + if(hasSubSections && op == entries.begin()) + { + os << "<abstract>\n"; + inAbstract = true; + } this->PrintFormatted(os, op->Brief.c_str()); - os << "\n"; - ++op; } } - if(name) + + // empty sections are not allowed in docbook. + if(entries.empty()) { - os << "</sect1>\n"; + os << "<para/>\n"; } + + os << "</sect1>\n"; } -void cmDocumentationFormatterDocbook::PrintPreformatted(std::ostream& os, - const char* text) +//---------------------------------------------------------------------------- +void cmDocumentationFormatterDocbook +::PrintPreformatted(std::ostream& os, const char* text) { - os << "<literallayout>"; + os << "<para>\n<programlisting>"; cmDocumentationPrintDocbookEscapes(os, text); - os << "</literallayout>\n "; + os << "</programlisting>\n</para>\n"; } -void cmDocumentationFormatterDocbook::PrintParagraph(std::ostream& os, - const char* text) +void cmDocumentationFormatterDocbook +::PrintParagraph(std::ostream& os, const char* text) { os << "<para>"; cmDocumentationPrintDocbookEscapes(os, text); - os << "</para>"; + os << "</para>\n"; } //---------------------------------------------------------------------------- -void cmDocumentationFormatterDocbook::PrintHeader(const char* docname, - const char* appname, - std::ostream& os) +void cmDocumentationFormatterDocbook +::PrintHeader(const char* docname, const char* appname, std::ostream& os) { + this->Docname = docname; + // this one is used to ensure that we don't create multiple link targets - // with the same name. We can clear it here since we are at the + // with the same name. We can clear it here since we are at the // start of a document here. this->EmittedLinkIds.clear(); os << "<?xml version=\"1.0\" ?>\n" - "<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\" " - "\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\" [\n" + "<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook V4.5//EN\" " + "\"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd\" [\n" "<!ENTITY % addindex \"IGNORE\">\n" "<!ENTITY % English \"INCLUDE\"> ]>\n" "<article>\n" @@ -253,3 +226,29 @@ void cmDocumentationFormatterDocbook::PrintFooter(std::ostream& os) os << "</article>\n"; } +//---------------------------------------------------------------------------- +void cmDocumentationFormatterDocbook +::PrintId(std::ostream& os, const char* prefix, std::string id) +{ + std::replace_if(id.begin(), id.end(), + std::not1(std::ptr_fun(cmIsAlnum)), '_'); + if(prefix) + { + id = std::string(prefix) + "." + id; + } + os << this->Docname << '.' << id; + + // make sure that each id exists only once. Since it seems + // not easily possible to determine which link refers to which id, + // we have at least to make sure that the duplicated id's get a + // different name (by appending an increasing number), Alex + if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end()) + { + this->EmittedLinkIds.insert(id); + } + else + { + static unsigned int i=0; + os << i++; + } +} diff --git a/Source/cmDocumentationFormatterDocbook.h b/Source/cmDocumentationFormatterDocbook.h index 213948d..0352d34 100644 --- a/Source/cmDocumentationFormatterDocbook.h +++ b/Source/cmDocumentationFormatterDocbook.h @@ -35,7 +35,9 @@ public: virtual void PrintPreformatted(std::ostream& os, const char* text); virtual void PrintParagraph(std::ostream& os, const char* text); private: + void PrintId(std::ostream& os, const char* prefix, std::string id); std::set<std::string> EmittedLinkIds; + std::string Docname; }; #endif diff --git a/Source/cmDocumentationFormatterHTML.cxx b/Source/cmDocumentationFormatterHTML.cxx index cd0077e..7213b43 100644 --- a/Source/cmDocumentationFormatterHTML.cxx +++ b/Source/cmDocumentationFormatterHTML.cxx @@ -29,7 +29,7 @@ static void cmDocumentationPrintHTMLChar(std::ostream& os, char c) // Use an escape sequence if necessary. switch (c) { - case '<': + case '<': os << "<"; break; case '>': @@ -114,7 +114,7 @@ void cmDocumentationFormatterHTML { std::string prefix = this->ComputeSectionLinkPrefix(name); - const std::vector<cmDocumentationEntry> &entries = + const std::vector<cmDocumentationEntry> &entries = section.GetEntries(); // skip the index if the help for only a single item (--help-command, @@ -131,7 +131,7 @@ void cmDocumentationFormatterHTML } // Is a list needed? - for(std::vector<cmDocumentationEntry>::const_iterator op + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); op != entries.end(); ++ op ) { if (op->Name.size()) @@ -154,7 +154,7 @@ void cmDocumentationFormatterHTML } } - for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); op != entries.end();) { if(op->Name.size()) @@ -191,7 +191,7 @@ void cmDocumentationFormatterHTML } } -void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os, +void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os, const char* text) { os << "<pre>"; @@ -199,7 +199,7 @@ void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os, os << "</pre>\n "; } -void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os, +void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os, const char* text) { os << "<p>"; @@ -229,7 +229,7 @@ void cmDocumentationFormatterHTML::PrintFooter(std::ostream& os) } //---------------------------------------------------------------------------- -void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os, +void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os, const char* text) { // Hyperlink prefixes. @@ -262,7 +262,7 @@ void cmDocumentationFormatterHTML std::vector<const cmDocumentationSection *>& sections) { // skip the index if only the help for a single item is printed - if ((sections.size() == 1) + if ((sections.size() == 1) && (sections[0]->GetName(this->GetForm()) != 0 ) && (std::string(sections[0]->GetName(this->GetForm())) == "SingleItem")) { diff --git a/Source/cmDocumentationFormatterHTML.h b/Source/cmDocumentationFormatterHTML.h index 427e04b..44bf240 100644 --- a/Source/cmDocumentationFormatterHTML.h +++ b/Source/cmDocumentationFormatterHTML.h @@ -32,7 +32,7 @@ public: const cmDocumentationSection& section, const char* name); virtual void PrintPreformatted(std::ostream& os, const char* text); - virtual void PrintParagraph(std::ostream& os, const char* text); + virtual void PrintParagraph(std::ostream& os, const char* text); virtual void PrintIndex(std::ostream& , std::vector<const cmDocumentationSection *>&); private: diff --git a/Source/cmDocumentationFormatterMan.cxx b/Source/cmDocumentationFormatterMan.cxx index 79a3b25..4123c85 100644 --- a/Source/cmDocumentationFormatterMan.cxx +++ b/Source/cmDocumentationFormatterMan.cxx @@ -19,9 +19,15 @@ cmDocumentationFormatterMan::cmDocumentationFormatterMan() :cmDocumentationFormatter() +,ManSection(1) { } +void cmDocumentationFormatterMan::SetManSection(int manSection) +{ + this->ManSection = manSection; +} + void cmDocumentationFormatterMan ::PrintSection(std::ostream& os, const cmDocumentationSection §ion, @@ -32,9 +38,9 @@ void cmDocumentationFormatterMan os << ".SH " << name << "\n"; } - const std::vector<cmDocumentationEntry> &entries = + const std::vector<cmDocumentationEntry> &entries = section.GetEntries(); - for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); op != entries.end(); ++op) { if(op->Name.size()) @@ -58,7 +64,7 @@ void cmDocumentationFormatterMan::EscapeText(std::string& man_text) cmSystemTools::ReplaceString(man_text, "-", "\\-"); } -void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, +void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, const char* text) { std::string man_text = text; @@ -69,7 +75,7 @@ void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, os << ".fi\n\n"; } -void cmDocumentationFormatterMan::PrintParagraph(std::ostream& os, +void cmDocumentationFormatterMan::PrintParagraph(std::ostream& os, const char* text) { std::string man_text = text; @@ -87,7 +93,7 @@ void cmDocumentationFormatterMan::PrintHeader(const char* docname, this->EscapeText(s_docname); this->EscapeText(s_appname); - os << ".TH " << s_docname << " 1 \"" + os << ".TH " << s_docname << " " << this->ManSection << " \"" << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str() << "\" \"" << s_appname << " " << cmVersion::GetCMakeVersion() diff --git a/Source/cmDocumentationFormatterMan.h b/Source/cmDocumentationFormatterMan.h index 11b5acb..b3d069c 100644 --- a/Source/cmDocumentationFormatterMan.h +++ b/Source/cmDocumentationFormatterMan.h @@ -22,6 +22,8 @@ class cmDocumentationFormatterMan : public cmDocumentationFormatter public: cmDocumentationFormatterMan(); + void SetManSection(int manSection); + virtual cmDocumentationEnums::Form GetForm() const { return cmDocumentationEnums::ManForm;} @@ -35,6 +37,7 @@ public: private: void EscapeText(std::string& man_text); + int ManSection; }; #endif diff --git a/Source/cmDocumentationFormatterText.cxx b/Source/cmDocumentationFormatterText.cxx index 0b04b73..5def194 100644 --- a/Source/cmDocumentationFormatterText.cxx +++ b/Source/cmDocumentationFormatterText.cxx @@ -33,9 +33,9 @@ void cmDocumentationFormatterText os << name << "\n\n"; } - const std::vector<cmDocumentationEntry> &entries = + const std::vector<cmDocumentationEntry> &entries = section.GetEntries(); - for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); op != entries.end(); ++op) { if(op->Name.size()) @@ -58,7 +58,7 @@ void cmDocumentationFormatterText } } -void cmDocumentationFormatterText::PrintPreformatted(std::ostream& os, +void cmDocumentationFormatterText::PrintPreformatted(std::ostream& os, const char* text) { bool newline = true; @@ -78,7 +78,7 @@ void cmDocumentationFormatterText::PrintPreformatted(std::ostream& os, os << "\n"; } -void cmDocumentationFormatterText::PrintParagraph(std::ostream& os, +void cmDocumentationFormatterText::PrintParagraph(std::ostream& os, const char* text) { os << this->TextIndent; @@ -91,7 +91,7 @@ void cmDocumentationFormatterText::SetIndent(const char* indent) this->TextIndent = indent; } -void cmDocumentationFormatterText::PrintColumn(std::ostream& os, +void cmDocumentationFormatterText::PrintColumn(std::ostream& os, const char* text) { // Print text arranged in an indented column of fixed witdh. @@ -100,14 +100,14 @@ void cmDocumentationFormatterText::PrintColumn(std::ostream& os, bool newSentence = false; bool firstLine = true; int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent)); - + // Loop until the end of the text. while(*l) { // Parse the next word. const char* r = l; while(*r && (*r != '\n') && (*r != ' ')) { ++r; } - + // Does it fit on this line? if(r-l < (width-column-(newSentence?1:0))) { @@ -135,12 +135,12 @@ void cmDocumentationFormatterText::PrintColumn(std::ostream& os, // first line. os << (firstLine?"":this->TextIndent); } - + // Print the word. os.write(l, static_cast<long>(r-l)); newSentence = (*(r-1) == '.'); } - + if(*r == '\n') { // Text provided a newline. Start a new line. @@ -175,6 +175,6 @@ void cmDocumentationFormatterText::PrintColumn(std::ostream& os, // Move to beginning of next word. Skip over whitespace. l = r; - while(*l && (*l == ' ')) { ++l; } + while(*l && (*l == ' ')) { ++l; } } } diff --git a/Source/cmDocumentationFormatterUsage.cxx b/Source/cmDocumentationFormatterUsage.cxx index 8a415cb..a068e56 100644 --- a/Source/cmDocumentationFormatterUsage.cxx +++ b/Source/cmDocumentationFormatterUsage.cxx @@ -28,9 +28,9 @@ void cmDocumentationFormatterUsage os << name << "\n"; } - const std::vector<cmDocumentationEntry> &entries = + const std::vector<cmDocumentationEntry> &entries = section.GetEntries(); - for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); op != entries.end(); ++op) { if(op->Name.size()) diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h index 0fab38f..4f8c10d 100644 --- a/Source/cmDocumentationSection.h +++ b/Source/cmDocumentationSection.h @@ -26,28 +26,28 @@ public: /** Create a cmSection, with a special name for man-output mode. */ cmDocumentationSection(const char* name, const char* manName) :Name(name), ManName(manName) {} - + /** Has any content been added to this section or is it empty ? */ bool IsEmpty() const { return this->Entries.empty(); } - + /** Clear contents. */ void Clear() { this->Entries.clear(); } - + /** Return the name of this section for the given output form. */ const char* GetName(cmDocumentationEnums::Form form) const { return (form==cmDocumentationEnums::ManForm ? this->ManName.c_str() : this->Name.c_str()); } - + /** Return a pointer to the first entry of this section. */ const std::vector<cmDocumentationEntry> &GetEntries() const { return this->Entries; } - + /** Append an entry to this section. */ void Append(const cmDocumentationEntry& entry) { this->Entries.push_back(entry); } void Append(const std::vector<cmDocumentationEntry> &entries) { this->Entries.insert(this->Entries.end(),entries.begin(),entries.end()); } - + /** Append an entry to this section using NULL terminated chars */ void Append(const char *[][3]); void Append(const char *n, const char *b, const char *f); @@ -58,7 +58,7 @@ public: { this->Entries.insert(this->Entries.begin(), entries.begin(),entries.end()); } - + private: std::string Name; std::string ManName; diff --git a/Source/cmElseCommand.h b/Source/cmElseCommand.h index 5e8b790..f259919 100644 --- a/Source/cmElseCommand.h +++ b/Source/cmElseCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmElseCommand; } @@ -54,7 +54,7 @@ public: { return "Starts the else portion of an if block."; } - + /** * More documentation. */ @@ -64,7 +64,7 @@ public: " else(expression)\n" "See the if command."; } - + cmTypeMacro(cmElseCommand, cmCommand); }; diff --git a/Source/cmElseIfCommand.h b/Source/cmElseIfCommand.h index 20cd81a..46e2bd9 100644 --- a/Source/cmElseIfCommand.h +++ b/Source/cmElseIfCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmElseIfCommand; } @@ -54,7 +54,7 @@ public: { return "Starts the elseif portion of an if block."; } - + /** * More documentation. */ @@ -64,7 +64,7 @@ public: " elseif(expression)\n" "See the if command."; } - + cmTypeMacro(cmElseIfCommand, cmCommand); }; diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx index f8f36eb..dcabf6a 100644 --- a/Source/cmEnableLanguageCommand.cxx +++ b/Source/cmEnableLanguageCommand.cxx @@ -22,7 +22,7 @@ bool cmEnableLanguageCommand this->SetError ("called with incorrect number of arguments"); return false; - } + } for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h index 5958e44..e4bb251 100644 --- a/Source/cmEnableLanguageCommand.h +++ b/Source/cmEnableLanguageCommand.h @@ -28,7 +28,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEnableLanguageCommand; } @@ -39,7 +39,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -52,7 +52,7 @@ public: { return "Enable a language (CXX/C/Fortran/etc)"; } - + /** * More documentation. */ @@ -67,7 +67,7 @@ public: "If OPTIONAL is used, use the CMAKE_<languageName>_COMPILER_WORKS " "variable to check whether the language has been enabled successfully."; } - + cmTypeMacro(cmEnableLanguageCommand, cmCommand); }; diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx index 5abb873..aa41ef7 100644 --- a/Source/cmEnableTestingCommand.cxx +++ b/Source/cmEnableTestingCommand.cxx @@ -12,7 +12,7 @@ #include "cmEnableTestingCommand.h" #include "cmLocalGenerator.h" -// we do this in the final pass so that we now the subdirs have all +// we do this in the final pass so that we now the subdirs have all // been defined bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&, cmExecutionStatus &) diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h index b607818..9b9e985 100644 --- a/Source/cmEnableTestingCommand.h +++ b/Source/cmEnableTestingCommand.h @@ -24,7 +24,7 @@ * within the valid control structures are replicated in Testfile * (i.e. SUBDIRS() and ADD_TEST() commands within IF() commands that are * not entered by CMake are not replicated in Testfile). - * Note that CTest expects to find this file in the build directory root; + * Note that CTest expects to find this file in the build directory root; * therefore, this command should be in the source directory root too. */ class cmEnableTestingCommand : public cmCommand @@ -33,7 +33,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEnableTestingCommand; } @@ -57,7 +57,7 @@ public: { return "Enable testing for current directory and below."; } - + /** * More documentation. */ @@ -70,9 +70,9 @@ public: "a test file in the build directory root. Therefore, this command " "should be in the source directory root."; } - + cmTypeMacro(cmEnableTestingCommand, cmCommand); - + }; diff --git a/Source/cmEndForEachCommand.cxx b/Source/cmEndForEachCommand.cxx index 2eca4e2..7f11ae5 100644 --- a/Source/cmEndForEachCommand.cxx +++ b/Source/cmEndForEachCommand.cxx @@ -12,7 +12,7 @@ #include "cmEndForEachCommand.h" bool cmEndForEachCommand -::InvokeInitialPass(std::vector<cmListFileArgument> const&, +::InvokeInitialPass(std::vector<cmListFileArgument> const&, cmExecutionStatus &) { this->SetError("An ENDFOREACH command was found outside of a proper " diff --git a/Source/cmEndForEachCommand.h b/Source/cmEndForEachCommand.h index 37b2d2a..d5ee8a6 100644 --- a/Source/cmEndForEachCommand.h +++ b/Source/cmEndForEachCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEndForEachCommand; } @@ -36,7 +36,7 @@ public: */ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&, cmExecutionStatus &); - + /** * This is called when the command is first encountered in * the CMakeLists.txt file. @@ -61,7 +61,7 @@ public: { return "Ends a list of commands in a FOREACH block."; } - + /** * More documentation. */ @@ -71,7 +71,7 @@ public: " endforeach(expression)\n" "See the FOREACH command."; } - + cmTypeMacro(cmEndForEachCommand, cmCommand); }; diff --git a/Source/cmEndFunctionCommand.h b/Source/cmEndFunctionCommand.h index 54ac068..d7b74e9 100644 --- a/Source/cmEndFunctionCommand.h +++ b/Source/cmEndFunctionCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEndFunctionCommand; } @@ -36,7 +36,7 @@ public: */ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&, cmExecutionStatus &); - + /** * This is called when the command is first encountered in * the CMakeLists.txt file. @@ -61,7 +61,7 @@ public: { return "Ends a list of commands in a function block."; } - + /** * More documentation. */ @@ -71,7 +71,7 @@ public: " endfunction(expression)\n" "See the function command."; } - + cmTypeMacro(cmEndFunctionCommand, cmCommand); }; diff --git a/Source/cmEndIfCommand.cxx b/Source/cmEndIfCommand.cxx index e98d4d4..0ac09de 100644 --- a/Source/cmEndIfCommand.cxx +++ b/Source/cmEndIfCommand.cxx @@ -20,7 +20,7 @@ bool cmEndIfCommand::InitialPass(std::vector<std::string> const&, { return true; } - + this->SetError("An ENDIF command was found outside of a proper " "IF ENDIF structure. Or its arguments did not match " "the opening IF command."); diff --git a/Source/cmEndIfCommand.h b/Source/cmEndIfCommand.h index 81d1b5f..5c4b9e3 100644 --- a/Source/cmEndIfCommand.h +++ b/Source/cmEndIfCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEndIfCommand; } @@ -54,7 +54,7 @@ public: { return "Ends a list of commands in an if block."; } - + /** * More documentation. */ @@ -64,7 +64,7 @@ public: " endif(expression)\n" "See the if command."; } - + cmTypeMacro(cmEndIfCommand, cmCommand); }; diff --git a/Source/cmEndMacroCommand.h b/Source/cmEndMacroCommand.h index 25e86b7..9d0e70f 100644 --- a/Source/cmEndMacroCommand.h +++ b/Source/cmEndMacroCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEndMacroCommand; } @@ -36,7 +36,7 @@ public: */ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&, cmExecutionStatus &); - + /** * This is called when the command is first encountered in * the CMakeLists.txt file. @@ -61,7 +61,7 @@ public: { return "Ends a list of commands in a macro block."; } - + /** * More documentation. */ @@ -71,7 +71,7 @@ public: " endmacro(expression)\n" "See the macro command."; } - + cmTypeMacro(cmEndMacroCommand, cmCommand); }; diff --git a/Source/cmEndWhileCommand.h b/Source/cmEndWhileCommand.h index 635ad5a..18ba5ea 100644 --- a/Source/cmEndWhileCommand.h +++ b/Source/cmEndWhileCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmEndWhileCommand; } @@ -36,7 +36,7 @@ public: */ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const& args, cmExecutionStatus &status); - + /** * This is called when the command is first encountered in * the CMakeLists.txt file. @@ -61,7 +61,7 @@ public: { return "Ends a list of commands in a while block."; } - + /** * More documentation. */ @@ -71,7 +71,7 @@ public: " endwhile(expression)\n" "See the while command."; } - + cmTypeMacro(cmEndWhileCommand, cmCommand); }; diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 61b27ea..9fdb1e8 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -36,7 +36,7 @@ bool cmExecProgramCommand doingargs = false; havereturn_variable = false; haveoutput_variable = true; - } + } else if ( haveoutput_variable ) { if ( output_variable.size() > 0 ) @@ -54,7 +54,7 @@ bool cmExecProgramCommand doingargs = false; haveoutput_variable = false; havereturn_variable = true; - } + } else if ( havereturn_variable ) { if ( return_variable.size() > 0 ) @@ -108,16 +108,16 @@ bool cmExecProgramCommand } else { - result = cmSystemTools::RunCommand(command.c_str(), output, + result = cmSystemTools::RunCommand(command.c_str(), output, retVal, 0, verbose); } if(!result) { retVal = -1; - } + } if ( output_variable.size() > 0 ) - { + { std::string::size_type first = output.find_first_not_of(" \n\t\r"); std::string::size_type last = output.find_last_not_of(" \n\t\r"); if(first == std::string::npos) @@ -128,7 +128,7 @@ bool cmExecProgramCommand { last = output.size()-1; } - + std::string coutput = std::string(output, first, last-first+1); this->Makefile->AddDefinition(output_variable.c_str(), coutput.c_str()); } @@ -139,7 +139,7 @@ bool cmExecProgramCommand sprintf(buffer, "%d", retVal); this->Makefile->AddDefinition(return_variable.c_str(), buffer); } - + return true; } diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h index 7233860..f752501 100644 --- a/Source/cmExecProgramCommand.h +++ b/Source/cmExecProgramCommand.h @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmExecProgramCommand; } @@ -38,13 +38,13 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "exec_program";} - + /** * This determines if the command is invoked when in script mode. */ @@ -55,10 +55,10 @@ public: */ virtual const char* GetTerseDocumentation() const { - return + return "Deprecated. Use the execute_process() command instead."; } - + /** * More documentation. */ @@ -82,7 +82,7 @@ public: "stdout/stderr of the console running cmake.\n" ; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index a0d9c9c..994c170 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -266,12 +266,12 @@ bool cmExecuteProcessCommand } if(!output_file.empty()) { - cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDOUT, + cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDOUT, output_file.c_str()); } if(!error_file.empty()) { - cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR, + cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR, error_file.c_str()); } @@ -326,12 +326,12 @@ bool cmExecuteProcessCommand // Store the output obtained. if(!output_variable.empty() && tempOutput.size()) { - this->Makefile->AddDefinition(output_variable.c_str(), + this->Makefile->AddDefinition(output_variable.c_str(), &*tempOutput.begin()); } if(!merge_output && !error_variable.empty() && tempError.size()) { - this->Makefile->AddDefinition(error_variable.c_str(), + this->Makefile->AddDefinition(error_variable.c_str(), &*tempError.begin()); } diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h index 9fbecac..1488924 100644 --- a/Source/cmExecutionStatus.h +++ b/Source/cmExecutionStatus.h @@ -23,19 +23,19 @@ class cmExecutionStatus : public cmObject { public: cmTypeMacro(cmExecutionStatus, cmObject); - + cmExecutionStatus() { this->Clear();}; - - virtual void SetReturnInvoked(bool val) + + virtual void SetReturnInvoked(bool val) { this->ReturnInvoked = val; } virtual bool GetReturnInvoked() { return this->ReturnInvoked; } - - virtual void SetBreakInvoked(bool val) + + virtual void SetBreakInvoked(bool val) { this->BreakInvoked = val; } virtual bool GetBreakInvoked() { return this->BreakInvoked; } - + virtual void Clear() { this->ReturnInvoked = false; @@ -45,7 +45,7 @@ public: virtual void SetNestedError(bool val) { this->NestedError = val; } virtual bool GetNestedError() { return this->NestedError; } - + protected: bool ReturnInvoked; bool BreakInvoked; diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 32595ee..fb3f39f 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -72,8 +72,9 @@ cmExportBuildFileGenerator if(!properties.empty()) { // Get the rest of the target details. + std::vector<std::string> missingTargets; this->SetImportDetailProperties(config, suffix, - target, properties); + target, properties, missingTargets); // TOOD: PUBLIC_HEADER_LOCATION // This should wait until the build feature propagation stuff @@ -82,6 +83,7 @@ cmExportBuildFileGenerator // properties); // Generate code in the export file. + this->GenerateMissingTargetsCheckCode(os, missingTargets); this->GenerateImportPropertyCode(os, config, target, properties); } } @@ -133,6 +135,25 @@ cmExportBuildFileGenerator //---------------------------------------------------------------------------- void +cmExportBuildFileGenerator::HandleMissingTarget( + std::string& link_libs, std::vector<std::string>&, + cmMakefile*, cmTarget* depender, cmTarget* dependee) +{ + // The target is not in the export. + if(!this->AppendMode) + { + // We are not appending, so all exported targets should be + // known here. This is probably user-error. + this->ComplainAboutMissingTarget(depender, dependee); + } + // Assume the target will be exported by another command. + // Append it with the export namespace. + link_libs += this->Namespace; + link_libs += dependee->GetName(); +} + +//---------------------------------------------------------------------------- +void cmExportBuildFileGenerator ::ComplainAboutMissingTarget(cmTarget* depender, cmTarget* dependee) diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 0f37626..726537b 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -45,8 +45,14 @@ protected: virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, std::string const& suffix); - virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee); + virtual void HandleMissingTarget(std::string& link_libs, + std::vector<std::string>& missingTargets, + cmMakefile* mf, + cmTarget* depender, + cmTarget* dependee); + + void ComplainAboutMissingTarget(cmTarget* depender, + cmTarget* dependee); /** Fill in properties indicating built file locations. */ void SetImportLocationProperty(const char* config, diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index eb19df5e..8dffae4 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -11,10 +11,15 @@ ============================================================================*/ #include "cmExportFileGenerator.h" +#include "cmExportSet.h" #include "cmGeneratedFileStream.h" +#include "cmGlobalGenerator.h" +#include "cmInstallExportGenerator.h" +#include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetExport.h" #include "cmVersion.h" #include <cmsys/auto_ptr.hxx> @@ -123,7 +128,9 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, void cmExportFileGenerator ::SetImportDetailProperties(const char* config, std::string const& suffix, - cmTarget* target, ImportPropertyMap& properties) + cmTarget* target, ImportPropertyMap& properties, + std::vector<std::string>& missingTargets + ) { // Get the makefile in which to lookup target information. cmMakefile* mf = target->GetMakefile(); @@ -159,13 +166,13 @@ cmExportFileGenerator { this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", - iface->Languages, properties); + iface->Languages, properties, missingTargets); this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", - iface->Libraries, properties); + iface->Libraries, properties, missingTargets); this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_DEPENDENT_LIBRARIES", - iface->SharedDeps, properties); + iface->SharedDeps, properties, missingTargets); if(iface->Multiplicity > 0) { std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; @@ -184,7 +191,9 @@ cmExportFileGenerator cmTarget* target, const char* propName, std::vector<std::string> const& libs, - ImportPropertyMap& properties) + ImportPropertyMap& properties, + std::vector<std::string>& missingTargets + ) { // Skip the property if there are no libraries. if(libs.empty()) @@ -224,17 +233,7 @@ cmExportFileGenerator } else { - // The target is not in the export. - if(!this->AppendMode) - { - // We are not appending, so all exported targets should be - // known here. This is probably user-error. - this->ComplainAboutMissingTarget(target, tgt); - } - // Assume the target will be exported by another command. - // Append it with the export namespace. - link_libs += this->Namespace; - link_libs += *li; + this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt); } } else @@ -250,6 +249,7 @@ cmExportFileGenerator properties[prop] = link_libs; } + //---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os, const char* config) @@ -381,6 +381,30 @@ cmExportFileGenerator //---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, + const std::vector<std::string>& missingTargets) +{ + os << "# Make sure the targets which have been exported in some other \n" + "# export set exist.\n"; + for(unsigned int i=0; i<missingTargets.size(); ++i) + { + os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n" + << " IF(CMAKE_FIND_PACKAGE_NAME)\n" + << " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" + << " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " + << "\"Required imported target \\\"" << missingTargets[i] + << "\\\" not found ! \")\n" + << " ELSE()\n" + << " MESSAGE(FATAL_ERROR \"Required imported target \\\"" + << missingTargets[i] << "\\\" not found ! \")\n" + << " ENDIF()\n" + << "ENDIF()\n"; + } + os << "\n"; +} + + +//---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) { diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index f271e55..70bc65d 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -60,17 +60,21 @@ protected: ImportPropertyMap const& properties, const std::set<std::string>& importedLocations); void GenerateImportedFileCheckLoop(std::ostream& os); + void GenerateMissingTargetsCheckCode(std::ostream& os, + const std::vector<std::string>& missingTargets); // Collect properties with detailed information about targets beyond // their location on disk. void SetImportDetailProperties(const char* config, std::string const& suffix, cmTarget* target, - ImportPropertyMap& properties); + ImportPropertyMap& properties, + std::vector<std::string>& missingTargets); void SetImportLinkProperty(std::string const& suffix, cmTarget* target, const char* propName, std::vector<std::string> const& libs, - ImportPropertyMap& properties); + ImportPropertyMap& properties, + std::vector<std::string>& missingTargets); /** Each subclass knows how to generate its kind of export file. */ virtual bool GenerateMainFile(std::ostream& os) = 0; @@ -80,10 +84,13 @@ protected: const char* config, std::string const& suffix) = 0; - /** Each subclass knows how to complain about a target that is - missing from an export set. */ - virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee) = 0; + /** Each subclass knows how to deal with a target that is missing from an + * export set. */ + virtual void HandleMissingTarget(std::string& link_libs, + std::vector<std::string>& missingTargets, + cmMakefile* mf, + cmTarget* depender, + cmTarget* dependee) = 0; // The namespace in which the exports are placed in the generated file. std::string Namespace; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index da14dd7..7841731 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -11,14 +11,19 @@ ============================================================================*/ #include "cmExportInstallFileGenerator.h" +#include "cmExportSet.h" +#include "cmExportSetMap.h" #include "cmGeneratedFileStream.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" #include "cmInstallExportGenerator.h" #include "cmInstallTargetGenerator.h" +#include "cmTargetExport.h" //---------------------------------------------------------------------------- cmExportInstallFileGenerator ::cmExportInstallFileGenerator(cmInstallExportGenerator* iegen): - InstallExportGenerator(iegen) + IEGen(iegen) { } @@ -36,10 +41,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { // Create all the imported targets. for(std::vector<cmTargetExport*>::const_iterator - tei = this->ExportSet->begin(); - tei != this->ExportSet->end(); ++tei) + tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); + tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) { - cmTargetExport* te = *tei; + cmTargetExport const* te = *tei; if(this->ExportedTargets.insert(te->Target).second) { this->GenerateImportTargetCode(os, te->Target); @@ -47,8 +52,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) else { cmOStringStream e; - e << "INSTALL(EXPORT \"" << this->Name << "\" ...) " - << "includes target \"" << te->Target->GetName() + e << "INSTALL(EXPORT \"" + << this->IEGen->GetExportSet()->GetName() + << "\" ...) " << "includes target \"" << te->Target->GetName() << "\" more than once in the export set."; cmSystemTools::Error(e.str().c_str()); return false; @@ -84,7 +90,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config) { // Skip configurations not enabled for this export. - if(!this->InstallExportGenerator->InstallsForConfig(config)) + if(!this->IEGen->InstallsForConfig(config)) { return true; } @@ -140,7 +146,7 @@ cmExportInstallFileGenerator { // Add code to compute the installation prefix relative to the // import file location. - const char* installDest = this->InstallExportGenerator->GetDestination(); + const char* installDest = this->IEGen->GetDestination(); if(!cmSystemTools::FileIsFullPath(installDest)) { std::string dest = installDest; @@ -161,11 +167,11 @@ cmExportInstallFileGenerator // Add each target in the set to the export. for(std::vector<cmTargetExport*>::const_iterator - tei = this->ExportSet->begin(); - tei != this->ExportSet->end(); ++tei) + tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); + tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) { // Collect import properties for this target. - cmTargetExport* te = *tei; + cmTargetExport const* te = *tei; ImportPropertyMap properties; std::set<std::string> importedLocations; this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator, @@ -185,8 +191,9 @@ cmExportInstallFileGenerator if(!properties.empty()) { // Get the rest of the target details. + std::vector<std::string> missingTargets; this->SetImportDetailProperties(config, suffix, - te->Target, properties); + te->Target, properties, missingTargets); // TOOD: PUBLIC_HEADER_LOCATION // This should wait until the build feature propagation stuff @@ -195,6 +202,7 @@ cmExportInstallFileGenerator // properties); // Generate code in the export file. + this->GenerateMissingTargetsCheckCode(os, missingTargets); this->GenerateImportPropertyCode(os, config, te->Target, properties); this->GenerateImportedFileChecksCode(os, te->Target, properties, importedLocations); @@ -306,12 +314,80 @@ cmExportInstallFileGenerator //---------------------------------------------------------------------------- void +cmExportInstallFileGenerator::HandleMissingTarget( + std::string& link_libs, std::vector<std::string>& missingTargets, + cmMakefile* mf, cmTarget* depender, cmTarget* dependee) +{ + std::string name = dependee->GetName(); + std::vector<std::string> namespaces = this->FindNamespaces(mf, name); + int targetOccurrences = (int)namespaces.size(); + if (targetOccurrences == 1) + { + std::string missingTarget = namespaces[0]; + missingTarget += name; + link_libs += missingTarget; + missingTargets.push_back(missingTarget); + } + else + { + // We are not appending, so all exported targets should be + // known here. This is probably user-error. + this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); + } +} + +//---------------------------------------------------------------------------- +std::vector<std::string> +cmExportInstallFileGenerator +::FindNamespaces(cmMakefile* mf, const std::string& name) +{ + std::vector<std::string> namespaces; + cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator(); + const cmExportSetMap& exportSets = gg->GetExportSets(); + + for(cmExportSetMap::const_iterator expIt = exportSets.begin(); + expIt != exportSets.end(); + ++expIt) + { + const cmExportSet* exportSet = expIt->second; + std::vector<cmTargetExport*> const* targets = + exportSet->GetTargetExports(); + + bool containsTarget = false; + for(unsigned int i=0; i<targets->size(); i++) + { + if (name == (*targets)[i]->Target->GetName()) + { + containsTarget = true; + break; + } + } + + if (containsTarget) + { + std::vector<cmInstallExportGenerator const*> const* installs = + exportSet->GetInstallations(); + for(unsigned int i=0; i<installs->size(); i++) + { + namespaces.push_back((*installs)[i]->GetNamespace()); + } + } + } + + return namespaces; +} + + +//---------------------------------------------------------------------------- +void cmExportInstallFileGenerator ::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen) { - const char* installDest = this->InstallExportGenerator->GetDestination(); + const char* installDest = this->IEGen->GetDestination(); cmOStringStream e; - e << "INSTALL(EXPORT \"" << this->Name << "\") given absolute " + e << "INSTALL(EXPORT \"" + << this->IEGen->GetExportSet()->GetName() + << "\") given absolute " << "DESTINATION \"" << installDest << "\" but the export " << "references an installation of target \"" << itgen->GetTarget()->GetName() << "\" which has relative " @@ -322,12 +398,24 @@ cmExportInstallFileGenerator //---------------------------------------------------------------------------- void cmExportInstallFileGenerator -::ComplainAboutMissingTarget(cmTarget* depender, cmTarget* dependee) +::ComplainAboutMissingTarget(cmTarget* depender, + cmTarget* dependee, + int occurrences) { cmOStringStream e; - e << "INSTALL(EXPORT \"" << this->Name << "\" ...) " + e << "INSTALL(EXPORT \"" + << this->IEGen->GetExportSet()->GetName() + << "\" ...) " << "includes target \"" << depender->GetName() - << "\" which requires target \"" << dependee->GetName() - << "\" that is not in the export set."; + << "\" which requires target \"" << dependee->GetName() << "\" "; + if (occurrences == 0) + { + e << "that is not in the export set."; + } + else + { + e << "that is not in this export set, but " << occurrences + << " times in others."; + } cmSystemTools::Error(e.str().c_str()); } diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index fb678e8..e719ecc 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -18,6 +18,7 @@ class cmInstallExportGenerator; class cmInstallFilesGenerator; class cmInstallTargetGenerator; class cmTargetExport; +class cmExportSet; /** \class cmExportInstallFileGenerator * \brief Generate a file exporting targets from an install tree. @@ -40,15 +41,6 @@ public: files. */ cmExportInstallFileGenerator(cmInstallExportGenerator* iegen); - /** Set the name of the export associated with the files. This is - the name given to the install(EXPORT) command mode. */ - void SetName(const char* name) { this->Name = name; } - - /** Set the set of targets to be exported. These are the targets - associated with the export name. */ - void SetExportSet(std::vector<cmTargetExport*> const* eSet) - { this->ExportSet = eSet; } - /** Get the per-config file generated for each configuraiton. This maps from the configuration name to the file temporary location for installation. */ @@ -65,8 +57,19 @@ protected: virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, std::string const& suffix); - virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee); + virtual void HandleMissingTarget(std::string& link_libs, + std::vector<std::string>& missingTargets, + cmMakefile* mf, + cmTarget* depender, + cmTarget* dependee); + + void ComplainAboutMissingTarget(cmTarget* depender, + cmTarget* dependee, + int occurrences); + + std::vector<std::string> FindNamespaces(cmMakefile* mf, + const std::string& name); + /** Generate a per-configuration file for the targets. */ bool GenerateImportFileConfig(const char* config); @@ -81,9 +84,7 @@ protected: void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen); - cmInstallExportGenerator* InstallExportGenerator; - std::string Name; - std::vector<cmTargetExport*> const* ExportSet; + cmInstallExportGenerator* IEGen; std::string ImportPrefix; @@ -91,34 +92,4 @@ protected: std::map<cmStdString, cmStdString> ConfigImportFiles; }; -/* - cmTargetExport is used in cmGlobalGenerator to collect the install - generators for targets associated with an export. -*/ -class cmTargetExport -{ -public: - cmTargetExport(cmTarget* tgt, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runtime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* headers - ) : Target(tgt), ArchiveGenerator(archive), - RuntimeGenerator(runtime), LibraryGenerator(library), - FrameworkGenerator(framework), BundleGenerator(bundle), - HeaderGenerator(headers) {} - - cmTarget* Target; - cmInstallTargetGenerator* ArchiveGenerator; - cmInstallTargetGenerator* RuntimeGenerator; - cmInstallTargetGenerator* LibraryGenerator; - cmInstallTargetGenerator* FrameworkGenerator; - cmInstallTargetGenerator* BundleGenerator; - cmInstallFilesGenerator* HeaderGenerator; -private: - cmTargetExport(); -}; - #endif diff --git a/Source/cmExportLibraryDependencies.cxx b/Source/cmExportLibraryDependencies.cxx index 8fdb069..f07b783 100644 --- a/Source/cmExportLibraryDependencies.cxx +++ b/Source/cmExportLibraryDependencies.cxx @@ -26,7 +26,7 @@ bool cmExportLibraryDependenciesCommand this->SetError("called with incorrect number of arguments"); return false; } - + // store the arguments for the final pass this->Filename = args[0]; this->Append = false; diff --git a/Source/cmExportLibraryDependencies.h b/Source/cmExportLibraryDependencies.h index 2a2ff21..d8b65cc 100644 --- a/Source/cmExportLibraryDependencies.h +++ b/Source/cmExportLibraryDependencies.h @@ -18,7 +18,7 @@ * \brief Add a test to the lists of tests to run. * * cmExportLibraryDependenciesCommand adds a test to the list of tests to run - * + * */ class cmExportLibraryDependenciesCommand : public cmCommand { @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmExportLibraryDependenciesCommand; } @@ -40,7 +40,7 @@ public: /** * This is called at the end after all the information - * specified by the command is accumulated. + * specified by the command is accumulated. */ virtual void FinalPass(); virtual bool HasFinalPass() const { return true; } @@ -57,7 +57,7 @@ public: { return "Deprecated. Use INSTALL(EXPORT) or EXPORT command."; } - + /** * More documentation. */ @@ -87,7 +87,7 @@ public: { return true; } - + cmTypeMacro(cmExportLibraryDependenciesCommand, cmCommand); private: diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx new file mode 100644 index 0000000..33b0630 --- /dev/null +++ b/Source/cmExportSet.cxx @@ -0,0 +1,32 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmExportSet.h" +#include "cmTargetExport.h" + +cmExportSet::~cmExportSet() +{ + for(unsigned int i = 0; i < this->TargetExports.size(); ++ i) + { + delete this->TargetExports[i]; + } +} + +void cmExportSet::AddTargetExport(cmTargetExport* te) +{ + this->TargetExports.push_back(te); +} + +void cmExportSet::AddInstallation(cmInstallExportGenerator const* installation) +{ + this->Installations.push_back(installation); +} diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h new file mode 100644 index 0000000..a57aa12 --- /dev/null +++ b/Source/cmExportSet.h @@ -0,0 +1,46 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmExportSet_h +#define cmExportSet_h + +#include "cmSystemTools.h" +class cmTargetExport; +class cmInstallExportGenerator; + +/// A set of targets that were installed with the same EXPORT parameter. +class cmExportSet +{ +public: + /// Construct an empty export set named \a name + cmExportSet(const std::string &name) : Name(name) {} + /// Destructor + ~cmExportSet(); + + void AddTargetExport(cmTargetExport* tgt); + + void AddInstallation(cmInstallExportGenerator const* installation); + + std::string const& GetName() const { return this->Name; } + + std::vector<cmTargetExport*> const* GetTargetExports() const + { return &this->TargetExports; } + + std::vector<cmInstallExportGenerator const*> const* GetInstallations() const + { return &this->Installations; } + +private: + std::vector<cmTargetExport*> TargetExports; + std::string Name; + std::vector<cmInstallExportGenerator const*> Installations; +}; + +#endif diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx new file mode 100644 index 0000000..96fdb3e --- /dev/null +++ b/Source/cmExportSetMap.cxx @@ -0,0 +1,34 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmExportSetMap.h" +#include "cmExportSet.h" + +cmExportSet* cmExportSetMap::operator[](const std::string &name) +{ + std::map<std::string, cmExportSet*>::iterator it = this->find(name); + if (it == this->end()) // Export set not found + { + it = this->insert(std::make_pair(name, new cmExportSet(name))).first; + } + return it->second; +} + +cmExportSetMap::~cmExportSetMap() +{ + for(std::map<std::string, cmExportSet*>::iterator it = this->begin(); + it != this->end(); + ++ it) + { + delete it->second; + } +} diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h new file mode 100644 index 0000000..4663c55 --- /dev/null +++ b/Source/cmExportSetMap.h @@ -0,0 +1,33 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmExportSetMap_h +#define cmExportSetMap_h + +#include "cmSystemTools.h" +class cmExportSet; + +/// A name -> cmExportSet map with overloaded operator[]. +class cmExportSetMap : public std::map<std::string, cmExportSet*> +{ +public: + /** \brief Overloaded operator[]. + * + * The operator is overloaded because cmExportSet has no default constructor: + * we do not want unnamed export sets. + */ + cmExportSet* operator[](const std::string &name); + + /// Overloaded destructor deletes all member export sets. + ~cmExportSetMap(); +}; + +#endif diff --git a/Source/cmExprLexer.h b/Source/cmExprLexer.h index 4c10496..03b36ce 100644 --- a/Source/cmExprLexer.h +++ b/Source/cmExprLexer.h @@ -58,7 +58,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ @@ -188,7 +188,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ diff --git a/Source/cmExprLexer.in.l b/Source/cmExprLexer.in.l index db9018f..f344b40 100644 --- a/Source/cmExprLexer.in.l +++ b/Source/cmExprLexer.in.l @@ -54,19 +54,19 @@ Modify cmExprLexer.h: %% -[0-9][0-9]* { yylvalp->Number = atoi(yytext); return exp_NUMBER; } +[0-9][0-9]* { yylvalp->Number = atoi(yytext); return exp_NUMBER; } "+" { return exp_PLUS; } -"-" { return exp_MINUS; } -"*" { return exp_TIMES; } -"/" { return exp_DIVIDE; } -"%" { return exp_MOD; } -"\|" { return exp_OR; } -"&" { return exp_AND; } -"^" { return exp_XOR; } -"~" { return exp_NOT; } -"<<" { return exp_SHIFTLEFT; } -">>" { return exp_SHIFTRIGHT; } +"-" { return exp_MINUS; } +"*" { return exp_TIMES; } +"/" { return exp_DIVIDE; } +"%" { return exp_MOD; } +"\|" { return exp_OR; } +"&" { return exp_AND; } +"^" { return exp_XOR; } +"~" { return exp_NOT; } +"<<" { return exp_SHIFTLEFT; } +">>" { return exp_SHIFTRIGHT; } "(" { return exp_OPENPARENT; } ")" { return exp_CLOSEPARENT; } diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx index 7728d74..9c1795e 100644 --- a/Source/cmExprParserHelper.cxx +++ b/Source/cmExprParserHelper.cxx @@ -42,7 +42,7 @@ int cmExprParserHelper::ParseString(const char* str, int verb) this->InputBuffer = str; this->InputBufferPos = 0; this->CurrentLine = 0; - + this->Result = 0; yyscan_t yyscanner; @@ -61,7 +61,7 @@ int cmExprParserHelper::ParseString(const char* str, int verb) if ( Verbose ) { - std::cerr << "Expanding [" << str << "] produced: [" + std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]" << std::endl; } return 1; diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h index 690426d..4b76b33 100644 --- a/Source/cmExprParserHelper.h +++ b/Source/cmExprParserHelper.h @@ -9,7 +9,7 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef cmExprParserHelper_h +#ifndef cmExprParserHelper_h #define cmExprParserHelper_h #include "cmStandardIncludes.h" diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx index 6ed84bd..9c965cc 100644 --- a/Source/cmExternalMakefileProjectGenerator.cxx +++ b/Source/cmExternalMakefileProjectGenerator.cxx @@ -49,7 +49,7 @@ const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName( } // otherwise search for the matching global generator - for (std::vector<std::string>::const_iterator + for (std::vector<std::string>::const_iterator it = this->SupportedGlobalGenerators.begin(); it != this->SupportedGlobalGenerators.end(); ++it) diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h index 46f1d31..182c1a8 100644 --- a/Source/cmExternalMakefileProjectGenerator.h +++ b/Source/cmExternalMakefileProjectGenerator.h @@ -22,12 +22,12 @@ class cmGlobalGenerator; * \brief Base class for generators for "External Makefile based IDE projects". * * cmExternalMakefileProjectGenerator is a base class for generators - * for "external makefile based projects", i.e. IDE projects which work + * for "external makefile based projects", i.e. IDE projects which work * an already existing makefiles. * See cmGlobalKdevelopGenerator as an example. - * After the makefiles have been generated by one of the Makefile + * After the makefiles have been generated by one of the Makefile * generators, the Generate() method is called and this generator - * can iterate over the local generators and/or projects to produce the + * can iterate over the local generators and/or projects to produce the * project files for the IDE. */ class cmExternalMakefileProjectGenerator @@ -39,7 +39,7 @@ public: ///! Get the name for this generator. virtual const char* GetName() const = 0; /** Get the documentation entry for this generator. */ - virtual void GetDocumentation(cmDocumentationEntry& entry, + virtual void GetDocumentation(cmDocumentationEntry& entry, const char* fullName) const = 0; ///! set the global generator which will generate the makefiles @@ -47,7 +47,7 @@ public: {this->GlobalGenerator = generator;} ///! Return the list of global generators supported by this extra generator - const std::vector<std::string>& GetSupportedGlobalGenerators() const + const std::vector<std::string>& GetSupportedGlobalGenerators() const {return this->SupportedGlobalGenerators;} ///! Get the name of the global generator for the given full name @@ -55,7 +55,7 @@ public: /** Create a full name from the given global generator name and the * extra generator name */ - static std::string CreateFullGeneratorName(const char* globalGenerator, + static std::string CreateFullGeneratorName(const char* globalGenerator, const char* extraGenerator); ///! Generate the project files, the Makefiles have already been generated diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 5df8627..25b13e5 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -60,9 +60,7 @@ cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator() // disable until somebody actually tests it: // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); #endif -#ifdef CMAKE_USE_NINJA this->SupportedGlobalGenerators.push_back("Ninja"); -#endif this->SupportedGlobalGenerators.push_back("Unix Makefiles"); } @@ -619,14 +617,17 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, " <Option compiler=\"" << compiler << "\" />\n" " <Compiler>\n"; + cmGeneratorTarget *gtgt = this->GlobalGenerator + ->GetGeneratorTarget(target); + // the compilerdefines for this target - const char* cdefs = target->GetMakefile()->GetProperty( - "COMPILE_DEFINITIONS"); - if(cdefs) + std::string cdefs = gtgt->GetCompileDefinitions(); + + if(!cdefs.empty()) { // Expand the list. std::vector<std::string> defs; - cmSystemTools::ExpandListArgument(cdefs, defs); + cmSystemTools::ExpandListArgument(cdefs.c_str(), defs); for(std::vector<std::string>::const_iterator di = defs.begin(); di != defs.end(); ++di) { @@ -635,57 +636,59 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, } } - // the include directories for this target - std::set<std::string> uniqIncludeDirs; + // the include directories for this target + std::set<std::string> uniqIncludeDirs; + + std::vector<std::string> includes; + const char *config = target->GetMakefile() + ->GetDefinition("CMAKE_BUILD_TYPE"); + target->GetMakefile()->GetLocalGenerator()-> + GetIncludeDirectories(includes, gtgt, "C", config); + for(std::vector<std::string>::const_iterator dirIt=includes.begin(); + dirIt != includes.end(); + ++dirIt) + { + uniqIncludeDirs.insert(*dirIt); + } - std::vector<std::string> includes; - target->GetMakefile()->GetLocalGenerator()-> - GetIncludeDirectories(includes, target); - for(std::vector<std::string>::const_iterator dirIt=includes.begin(); - dirIt != includes.end(); + std::string systemIncludeDirs = makefile->GetSafeDefinition( + "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); + if (!systemIncludeDirs.empty()) + { + std::vector<std::string> dirs; + cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs); + for(std::vector<std::string>::const_iterator dirIt=dirs.begin(); + dirIt != dirs.end(); ++dirIt) { uniqIncludeDirs.insert(*dirIt); } + } - std::string systemIncludeDirs = makefile->GetSafeDefinition( - "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); - if (!systemIncludeDirs.empty()) - { - std::vector<std::string> dirs; - cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs); - for(std::vector<std::string>::const_iterator dirIt=dirs.begin(); - dirIt != dirs.end(); - ++dirIt) - { - uniqIncludeDirs.insert(*dirIt); - } - } - - systemIncludeDirs = makefile->GetSafeDefinition( - "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); - if (!systemIncludeDirs.empty()) - { - std::vector<std::string> dirs; - cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs); - for(std::vector<std::string>::const_iterator dirIt=dirs.begin(); - dirIt != dirs.end(); - ++dirIt) - { - uniqIncludeDirs.insert(*dirIt); - } - } - - for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin(); - dirIt != uniqIncludeDirs.end(); + systemIncludeDirs = makefile->GetSafeDefinition( + "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); + if (!systemIncludeDirs.empty()) + { + std::vector<std::string> dirs; + cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs); + for(std::vector<std::string>::const_iterator dirIt=dirs.begin(); + dirIt != dirs.end(); ++dirIt) { - fout <<" <Add directory=\"" << dirIt->c_str() << "\" />\n"; + uniqIncludeDirs.insert(*dirIt); } + } - fout<<" </Compiler>\n"; + for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin(); + dirIt != uniqIncludeDirs.end(); + ++dirIt) + { + fout <<" <Add directory=\"" << dirIt->c_str() << "\" />\n"; } - else // e.g. all and the GLOBAL and UTILITY targets + + fout<<" </Compiler>\n"; + } + else // e.g. all and the GLOBAL and UTILITY targets { fout<<" <Option working_dir=\"" << makefile->GetStartOutputDirectory() << "\" />\n" diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 65077b3..97ab086 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -34,9 +34,11 @@ cmExtraEclipseCDT4Generator this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); #endif + this->SupportedGlobalGenerators.push_back("Ninja"); this->SupportedGlobalGenerators.push_back("Unix Makefiles"); this->SupportsVirtualFolders = true; + this->GenerateLinkedResources = true; } //---------------------------------------------------------------------------- @@ -82,6 +84,9 @@ void cmExtraEclipseCDT4Generator::Generate() this->HomeDirectory = mf->GetHomeDirectory(); this->HomeOutputDirectory = mf->GetHomeOutputDirectory(); + this->GenerateLinkedResources = mf->IsOn( + "CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES"); + this->IsOutOfSourceBuild = (this->HomeDirectory!=this->HomeOutputDirectory); this->GenerateSourceProject = (this->IsOutOfSourceBuild && @@ -286,6 +291,9 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() // set the make command std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); + const std::string makeArgs = mf->GetSafeDefinition( + "CMAKE_ECLIPSE_MAKE_ARGUMENTS"); + fout << "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>\n" @@ -293,7 +301,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() "\t\t\t\t</dictionary>\n" "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.command</key>\n" - "\t\t\t\t\t<value>" + this->GetEclipsePath(make) + "</value>\n" + "\t\t\t\t\t<value>" << this->GetEclipsePath(make) << "</value>\n" "\t\t\t\t</dictionary>\n" "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.contents</key>\n" @@ -305,7 +313,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() "\t\t\t\t</dictionary>\n" "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.arguments</key>\n" - "\t\t\t\t\t<value></value>\n" + "\t\t\t\t\t<value>" << makeArgs << "</value>\n" "\t\t\t\t</dictionary>\n" "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.buildLocation</key>\n" @@ -458,18 +466,6 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() this->CreateLinksForTargets(fout); } - // I'm not sure this makes too much sense. There can be different - // output directories in different subdirs, so we would need more of them. - - // for EXECUTABLE_OUTPUT_PATH when not in binary dir - this->AppendOutLinkedResource(fout, - mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"), - mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH")); - // for LIBRARY_OUTPUT_PATH when not in binary dir - this->AppendOutLinkedResource(fout, - mf->GetSafeDefinition("CMAKE_LIBRARY_OUTPUT_DIRECTORY"), - mf->GetSafeDefinition("LIBRARY_OUTPUT_PATH")); - fout << "\t</linkedResources>\n"; fout << "</projectDescription>\n"; @@ -509,6 +505,10 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets( linkName2 += ti->first; this->AppendLinkedResource(fout, linkName2, "virtual:/virtual", VirtualFolder); + if (!this->GenerateLinkedResources) + { + break; // skip generating the linked resources to the source files + } std::vector<cmSourceGroup> sourceGroups=makefile->GetSourceGroups(); // get the files from the source lists then add them to the groups cmTarget* tgt = const_cast<cmTarget*>(&ti->second); @@ -563,6 +563,11 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets( void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects( cmGeneratedFileStream& fout, const std::string& baseDir) { + if (!this->GenerateLinkedResources) + { + return; + } + // for each sub project create a linked resource to the source dir // - only if it is an out-of-source build this->AppendLinkedResource(fout, "[Subprojects]", @@ -587,7 +592,8 @@ void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects( this->GetEclipsePath(linkSourceDirectory), LinkToFolder ); - this->SrcLinkedResources.push_back(it->first); + // Don't add it to the srcLinkedResources, because listing multiple + // directories confuses the Eclipse indexer (#13596). } } } @@ -606,6 +612,16 @@ void cmExtraEclipseCDT4Generator::AppendIncludeDirectories( if (!inc->empty()) { std::string dir = cmSystemTools::CollapseFullPath(inc->c_str()); + + // handle framework include dirs on OSX, the remainder after the + // Frameworks/ part has to be stripped + // /System/Library/Frameworks/GLUT.framework/Headers + cmsys::RegularExpression frameworkRx("(.+/Frameworks)/.+\\.framework/"); + if(frameworkRx.find(dir.c_str())) + { + dir = frameworkRx.match(1); + } + if(emittedDirs.find(dir) == emittedDirs.end()) { emittedDirs.insert(dir); @@ -728,15 +744,16 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const /* I don't know what the pathentry kind="src" are good for, e.g. autocompletion * works also without them. Done wrong, the indexer complains, see #12417 * and #12213. + * According to #13596, this entry at least limits the directories the + * indexer is searching for files. So now the "src" entry contains only + * the linked resource to CMAKE_SOURCE_DIR. * The CDT documentation is very terse on that: * "CDT_SOURCE: Entry kind constant describing a path entry identifying a * folder containing source code to be compiled." * Also on the cdt-dev list didn't bring any information: * http://web.archiveorange.com/archive/v/B4NlJDNIpYoOS1SbxFNy - * So I'm disabling them for now, hoping that somebody will report if something - * is not workging anymore. * Alex */ -#ifdef DO_CREATE_SRC_PATH_ENTRIES + for (std::vector<std::string>::const_iterator it = this->SrcLinkedResources.begin(); it != this->SrcLinkedResources.end(); @@ -753,22 +770,10 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const excludeFromOut += this->EscapeForXML(*it) + "/|"; } } -#endif + excludeFromOut += "**/CMakeFiles/"; fout << "<pathentry excluding=\"" << excludeFromOut << "\" kind=\"out\" path=\"\"/>\n"; - // add output entry for EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH - // - if it is a subdir of homeOutputDirectory, there is no need to add it - // - if it is not then create a linked resource and add the linked name - // but check it doesn't conflict with other linked resources names - for (std::vector<std::string>::const_iterator - it = this->OutLinkedResources.begin(); - it != this->OutLinkedResources.end(); - ++it) - { - fout << "<pathentry kind=\"out\" path=\"" << this->EscapeForXML(*it) - << "\"/>\n"; - } // add pre-processor definitions to allow eclipse to gray out sections emmited.clear(); @@ -894,11 +899,18 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const it != this->GlobalGenerator->GetLocalGenerators().end(); ++it) { - cmTargets & targets = (*it)->GetMakefile()->GetTargets(); - for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) + cmGeneratorTargetsType targets = (*it)->GetMakefile() + ->GetGeneratorTargets(); + for (cmGeneratorTargetsType::iterator l = targets.begin(); + l != targets.end(); ++l) { + if (l->first->IsImported()) + { + continue; + } std::vector<std::string> includeDirs; - (*it)->GetIncludeDirectories(includeDirs, &l->second); + const char *config = mf->GetDefinition("CMAKE_BUILD_TYPE"); + (*it)->GetIncludeDirectories(includeDirs, l->second, "C", config); this->AppendIncludeDirectories(fout, includeDirs, emmited); } } @@ -1067,9 +1079,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } //insert rules for compiling, preprocessing and assembling individual files - cmLocalUnixMakefileGenerator3* lumg=(cmLocalUnixMakefileGenerator3*)*it; std::vector<std::string> objectFileTargets; - lumg->GetIndividualFileTargets(objectFileTargets); + (*it)->GetIndividualFileTargets(objectFileTargets); for(std::vector<std::string>::const_iterator fit=objectFileTargets.begin(); fit != objectFileTargets.end(); ++fit) @@ -1314,51 +1325,3 @@ void cmExtraEclipseCDT4Generator "\t\t</link>\n" ; } - -bool cmExtraEclipseCDT4Generator -::AppendOutLinkedResource(cmGeneratedFileStream& fout, - const std::string& defname, - const std::string& altdefname) -{ - if (defname.empty() && altdefname.empty()) - { - return false; - } - - std::string outputPath = (defname.empty() ? altdefname : defname); - - if (!cmSystemTools::FileIsFullPath(outputPath.c_str())) - { - outputPath = this->HomeOutputDirectory + "/" + outputPath; - } - if (cmSystemTools::IsSubDirectory(outputPath.c_str(), - this->HomeOutputDirectory.c_str())) - { - return false; - } - - std::string name = this->GetPathBasename(outputPath); - - // make sure linked resource name is unique - while (this->GlobalGenerator->GetProjectMap().find(name) - != this->GlobalGenerator->GetProjectMap().end()) - { - name += "_"; - } - - if (std::find(this->OutLinkedResources.begin(), - this->OutLinkedResources.end(), - name) - != this->OutLinkedResources.end()) - { - return false; - } - else - { - this->AppendLinkedResource(fout, name, - this->GetEclipsePath(outputPath), LinkToFolder); - this->OutLinkedResources.push_back(name); - return true; - } -} - diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index ebd8c08..31ad68d 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h @@ -93,10 +93,6 @@ private: const std::string& path, LinkType linkType); - bool AppendOutLinkedResource(cmGeneratedFileStream& fout, - const std::string& defname, - const std::string& altdefname); - static void AppendIncludeDirectories(cmGeneratedFileStream& fout, const std::vector<std::string>& includeDirs, std::set<std::string>& emittedDirs); @@ -109,11 +105,11 @@ private: void CreateLinksForTargets(cmGeneratedFileStream& fout); std::vector<std::string> SrcLinkedResources; - std::vector<std::string> OutLinkedResources; std::string HomeDirectory; std::string HomeOutputDirectory; bool IsOutOfSourceBuild; bool GenerateSourceProject; + bool GenerateLinkedResources; bool SupportsVirtualFolders; }; diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index 93533e5..a4aa75a 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -33,19 +33,19 @@ bool cmFLTKWrapUICommand std::vector<std::string> newArgs; this->Makefile->ExpandSourceListArguments(args,newArgs, 1); - - // get the list of GUI files from which .cxx and .h will be generated + + // get the list of GUI files from which .cxx and .h will be generated std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory(); - // Some of the generated files are *.h so the directory "GUI" + // Some of the generated files are *.h so the directory "GUI" // where they are created have to be added to the include path this->Makefile->AddIncludeDirectory( outputDirectory.c_str() ); - for(std::vector<std::string>::iterator i = (newArgs.begin() + 1); + for(std::vector<std::string>::iterator i = (newArgs.begin() + 1); i != newArgs.end(); i++) { cmSourceFile *curr = this->Makefile->GetSource(i->c_str()); - // if we should use the source GUI + // if we should use the source GUI // to generate .cxx and .h files if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) { @@ -107,11 +107,11 @@ bool cmFLTKWrapUICommand std::string varName = this->Target; varName += "_FLTK_UI_SRCS"; this->Makefile->AddDefinition(varName.c_str(), sourceListValue.c_str()); - + return true; } -void cmFLTKWrapUICommand::FinalPass() +void cmFLTKWrapUICommand::FinalPass() { // people should add the srcs to the target themselves, but the old command // didn't support that, so check and see if they added the files in and if @@ -119,7 +119,7 @@ void cmFLTKWrapUICommand::FinalPass() cmTarget* target = this->Makefile->FindTarget(this->Target.c_str()); if(!target) { - std::string msg = + std::string msg = "FLTK_WRAP_UI was called with a target that was never created: "; msg += this->Target; msg +=". The problem was found while processing the source directory: "; @@ -128,12 +128,12 @@ void cmFLTKWrapUICommand::FinalPass() cmSystemTools::Message(msg.c_str(),"Warning"); return; } - std::vector<cmSourceFile*> const& srcs = + std::vector<cmSourceFile*> const& srcs = target->GetSourceFiles(); bool found = false; for (unsigned int i = 0; i < srcs.size(); ++i) { - if (srcs[i]->GetFullPath() == + if (srcs[i]->GetFullPath() == this->GeneratedSourcesClasses[0]->GetFullPath()) { found = true; @@ -142,7 +142,7 @@ void cmFLTKWrapUICommand::FinalPass() } if (!found) { - std::string msg = + std::string msg = "In CMake 2.2 the FLTK_WRAP_UI command sets a variable to the list of " "source files that should be added to your executable or library. It " "appears that you have not added these source files to your target. " @@ -153,13 +153,13 @@ void cmFLTKWrapUICommand::FinalPass() "of sources to add to your target when you call ADD_LIBRARY or " "ADD_EXECUTABLE. For now CMake will add the sources to your target " "for you as was done in CMake 2.0 and earlier. In the future this may " - "become an error."; + "become an error."; msg +="The problem was found while processing the source directory: "; msg += this->Makefile->GetStartDirectory(); cmSystemTools::Message(msg.c_str(),"Warning"); // first we add the rules for all the .fl to .h and .cxx files size_t lastHeadersClass = this->GeneratedSourcesClasses.size(); - + // Generate code for all the .fl files for(size_t classNum = 0; classNum < lastHeadersClass; classNum++) { diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h index cb0f9d5..530de2c 100644 --- a/Source/cmFLTKWrapUICommand.h +++ b/Source/cmFLTKWrapUICommand.h @@ -28,7 +28,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmFLTKWrapUICommand; } @@ -39,7 +39,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * This is called at the end after all the information * specified by the command is accumulated. Most commands do @@ -61,7 +61,7 @@ public: { return "Create FLTK user interfaces Wrappers."; } - + /** * More documentation. */ @@ -75,7 +75,7 @@ public: "resultingLibraryName_FLTK_UI_SRCS which should be added to your " "library."; } - + private: /** * List of produced files. @@ -83,7 +83,7 @@ private: std::vector<cmSourceFile *> GeneratedSourcesClasses; /** - * List of Fluid files that provide the source + * List of Fluid files that provide the source * generating .cxx and .h files */ std::string Target; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index d69431e..b877f3c 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -10,6 +10,7 @@ See the License for more information. ============================================================================*/ #include "cmFileCommand.h" +#include "cmCryptoHash.h" #include "cmake.h" #include "cmHexFileConverter.h" #include "cmInstallType.h" @@ -21,6 +22,7 @@ #endif #undef GetCurrentDirectory +#include <assert.h> #include <sys/types.h> #include <sys/stat.h> @@ -271,7 +273,7 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args) // Open the specified file. #if defined(_WIN32) || defined(__CYGWIN__) - std::ifstream file(fileName.c_str(), std::ios::in | + std::ifstream file(fileName.c_str(), std::ios::in | (hexOutputArg.IsEnabled() ? std::ios::binary : std::ios::in)); #else std::ifstream file(fileName.c_str(), std::ios::in); @@ -704,11 +706,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, bool recurse) { - if ( args.size() < 2 ) - { - this->SetError("GLOB requires at least a variable name"); - return false; - } + // File commands has at least one argument + assert(args.size() > 1); std::vector<std::string>::const_iterator i = args.begin(); @@ -842,11 +841,8 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, bool cmFileCommand::HandleMakeDirectoryCommand( std::vector<std::string> const& args) { - if(args.size() < 2 ) - { - this->SetError("called with incorrect number of arguments"); - return false; - } + // File command has at least one argument + assert(args.size() > 1); std::vector<std::string>::const_iterator i = args.begin(); @@ -1003,7 +999,9 @@ protected: // Match rules are case-insensitive on some platforms. #if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__) std::string lower = cmSystemTools::LowerCase(file); - file = lower.c_str(); + const char* file_to_match = lower.c_str(); +#else + const char* file_to_match = file; #endif // Collect properties from all matching rules. @@ -1012,7 +1010,7 @@ protected: for(std::vector<MatchRule>::iterator mr = this->MatchRules.begin(); mr != this->MatchRules.end(); ++mr) { - if(mr->Regex.find(file)) + if(mr->Regex.find(file_to_match)) { matched = true; result.Exclude |= mr->Properties.Exclude; @@ -2619,17 +2617,17 @@ namespace { ::curl_easy_cleanup(this->Easy); } } - - inline void release(void) + + inline void release(void) { this->Easy = 0; return; } - + private: ::CURL * Easy; }; - + } #endif @@ -2664,7 +2662,11 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) long inactivity_timeout = 0; std::string verboseLog; std::string statusVar; - std::string expectedMD5sum; + bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY"); + const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO"); + std::string expectedHash; + std::string hashMatchMSG; + cmsys::auto_ptr<cmCryptoHash> hash; bool showProgress = false; while(i != args.end()) @@ -2715,6 +2717,32 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) } statusVar = *i; } + else if(*i == "TLS_VERIFY") + { + ++i; + if(i != args.end()) + { + tls_verify = cmSystemTools::IsOn(i->c_str()); + } + else + { + this->SetError("TLS_VERIFY missing bool value."); + return false; + } + } + else if(*i == "TLS_CAINFO") + { + ++i; + if(i != args.end()) + { + cainfo = i->c_str(); + } + else + { + this->SetError("TLS_CAFILE missing file value."); + return false; + } + } else if(*i == "EXPECTED_MD5") { ++i; @@ -2723,48 +2751,68 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5."); return false; } - expectedMD5sum = cmSystemTools::LowerCase(*i); + hash = cmsys::auto_ptr<cmCryptoHash>(cmCryptoHash::New("MD5")); + hashMatchMSG = "MD5 sum"; + expectedHash = cmSystemTools::LowerCase(*i); } else if(*i == "SHOW_PROGRESS") { showProgress = true; } + else if(*i == "EXPECTED_HASH") + { + ++i; + if(i == args.end()) + { + this->SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH."); + return false; + } + std::string::size_type pos = i->find("="); + if(pos == std::string::npos) + { + std::string err = + "DOWNLOAD EXPECTED_HASH expects ALGO=value but got: "; + err += *i; + this->SetError(err.c_str()); + return false; + } + std::string algo = i->substr(0, pos); + expectedHash = cmSystemTools::LowerCase(i->substr(pos+1)); + hash = cmsys::auto_ptr<cmCryptoHash>(cmCryptoHash::New(algo.c_str())); + if(!hash.get()) + { + std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: "; + err += algo; + this->SetError(err.c_str()); + return false; + } + hashMatchMSG = algo + " hash"; + } ++i; } - - // If file exists already, and caller specified an expected md5 sum, - // and the existing file already has the expected md5 sum, then simply + // If file exists already, and caller specified an expected md5 or sha, + // and the existing file already has the expected hash, then simply // return. // - if(cmSystemTools::FileExists(file.c_str()) && - !expectedMD5sum.empty()) + if(cmSystemTools::FileExists(file.c_str()) && hash.get()) { - char computedMD5[32]; - - if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5)) - { - this->SetError("DOWNLOAD cannot compute MD5 sum on pre-existing file"); - return false; - } - - std::string actualMD5sum = cmSystemTools::LowerCase( - std::string(computedMD5, 32)); - - if (expectedMD5sum == actualMD5sum) + std::string msg; + std::string actualHash = hash->HashFile(file.c_str()); + if(actualHash == expectedHash) { + msg = "returning early; file already exists with expected "; + msg += hashMatchMSG; + msg += "\""; if(statusVar.size()) { cmOStringStream result; - result << (int)0 << ";\"" - "returning early: file already exists with expected MD5 sum\""; + result << (int)0 << ";\"" << msg; this->Makefile->AddDefinition(statusVar.c_str(), result.str().c_str()); } - return true; } } - // Make sure parent directory exists so we can write to the file // as we receive downloaded bits from curl... // @@ -2796,7 +2844,6 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) } cURLEasyGuard g_curl(curl); - ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); check_curl_result(res, "DOWNLOAD cannot set url: "); @@ -2804,6 +2851,9 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); check_curl_result(res, "DOWNLOAD cannot set http failure option: "); + res = ::curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/" LIBCURL_VERSION); + check_curl_result(res, "DOWNLOAD cannot set user agent option: "); + res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cmWriteToFileCallback); check_curl_result(res, "DOWNLOAD cannot set write function: "); @@ -2812,6 +2862,25 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) cmFileCommandCurlDebugCallback); check_curl_result(res, "DOWNLOAD cannot set debug function: "); + // check to see if TLS verification is requested + if(tls_verify) + { + res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); + check_curl_result(res, "Unable to set TLS/SSL Verify on: "); + } + else + { + res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + check_curl_result(res, "Unable to set TLS/SSL Verify off: "); + } + // check to see if a CAINFO file has been specified + // command arg comes first + if(cainfo && *cainfo) + { + res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo); + check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: "); + } + cmFileCommandVectorOfChar chunkDebug; res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fout); @@ -2886,26 +2955,22 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) // Verify MD5 sum if requested: // - if (!expectedMD5sum.empty()) + if (hash.get()) { - char computedMD5[32]; - - if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5)) + std::string actualHash = hash->HashFile(file.c_str()); + if (actualHash.size() == 0) { - this->SetError("DOWNLOAD cannot compute MD5 sum on downloaded file"); + this->SetError("DOWNLOAD cannot compute hash on downloaded file"); return false; } - std::string actualMD5sum = cmSystemTools::LowerCase( - std::string(computedMD5, 32)); - - if (expectedMD5sum != actualMD5sum) + if (expectedHash != actualHash) { cmOStringStream oss; - oss << "DOWNLOAD MD5 mismatch" << std::endl + oss << "DOWNLOAD HASH mismatch" << std::endl << " for file: [" << file << "]" << std::endl - << " expected MD5 sum: [" << expectedMD5sum << "]" << std::endl - << " actual MD5 sum: [" << actualMD5sum << "]" << std::endl + << " expected hash: [" << expectedHash << "]" << std::endl + << " actual hash: [" << actualHash << "]" << std::endl ; this->SetError(oss.str().c_str()); return false; diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index ced26c4..b4aa903 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -83,7 +83,8 @@ public: " file(TO_NATIVE_PATH path result)\n" " file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n" - " [EXPECTED_MD5 sum])\n" + " [EXPECTED_HASH ALGO=value] [EXPECTED_MD5 sum]\n" + " [TLS_VERIFY on|off] [TLS_CAINFO file])\n" " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" "WRITE will write a message into a file called 'filename'. It " @@ -168,11 +169,21 @@ public: "timeout after time seconds, time should be specified as an integer. " "The INACTIVITY_TIMEOUT specifies an integer number of seconds of " "inactivity after which the operation should terminate. " - "If EXPECTED_MD5 sum is specified, the operation will verify that the " - "downloaded file's actual md5 sum matches the expected value. If it " - "does not match, the operation fails with an error. " + "If EXPECTED_HASH ALGO=value is specified, the operation will verify " + "that the downloaded file's actual hash matches the expected value, " + "where ALGO is one of MD5, SHA1, SHA224, SHA256, SHA384, or SHA512. " + "If it does not match, the operation fails with an error. " + "(\"EXPECTED_MD5 sum\" is short-hand for \"EXPECTED_HASH MD5=sum\".) " "If SHOW_PROGRESS is specified, progress information will be printed " - "as status messages until the operation is complete." + "as status messages until the operation is complete. " + "For https URLs CMake must be built with OpenSSL. " + "TLS/SSL certificates are not checked by default. " + "Set TLS_VERIFY to ON to check certificates and/or use " + "EXPECTED_HASH to verify downloaded content. " + "Set TLS_CAINFO to specify a custom Certificate Authority file. " + "If either TLS option is not given CMake will check variables " + "CMAKE_TLS_VERIFY and CMAKE_TLS_CAINFO, " + "respectively." "\n" "UPLOAD will upload the given file to the given URL. " "If LOG var is specified a log of the upload will be put in var. " diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx index b1050d3..3167be4 100644 --- a/Source/cmFileTimeComparison.cxx +++ b/Source/cmFileTimeComparison.cxx @@ -116,7 +116,7 @@ cmFileTimeComparison::~cmFileTimeComparison() } //---------------------------------------------------------------------------- -bool cmFileTimeComparison::FileTimeCompare(const char* f1, +bool cmFileTimeComparison::FileTimeCompare(const char* f1, const char* f2, int* result) { return this->Internals->FileTimeCompare(f1, f2, result); @@ -129,7 +129,7 @@ bool cmFileTimeComparison::FileTimesDiffer(const char* f1, const char* f2) } //---------------------------------------------------------------------------- -int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1, +int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1, cmFileTimeComparison_Type* s2) { #if !defined(_WIN32) || defined(__CYGWIN__) diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h index f5de2f6..cc1ef63 100644 --- a/Source/cmFileTimeComparison.h +++ b/Source/cmFileTimeComparison.h @@ -31,7 +31,7 @@ public: * Compare file modification times. * Return true for successful comparison and false for error. * When true is returned, result has -1, 0, +1 for - * f1 older, same, or newer than f2. + * f1 older, same, or newer than f2. */ bool FileTimeCompare(const char* f1, const char* f2, int* result); @@ -42,7 +42,7 @@ public: bool FileTimesDiffer(const char* f1, const char* f2); protected: - + cmFileTimeComparisonInternal* Internals; }; diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index fb8bcf7..1de3982 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -10,11 +10,13 @@ See the License for more information. ============================================================================*/ #include "cmFindBase.h" - + cmFindBase::cmFindBase() { this->AlreadyInCache = false; this->AlreadyInCacheWithoutMetaInfo = false; + this->NamesPerDir = false; + this->NamesPerDirAllowed = false; } //---------------------------------------------------------------------------- @@ -132,7 +134,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) bool compatibility = this->Makefile->NeedBackwardsCompatibility(2,3); // copy argsIn into args so it can be modified, - // in the process extract the DOC "documentation" + // in the process extract the DOC "documentation" size_t size = argsIn.size(); std::vector<std::string> args; bool foundDoc = false; @@ -178,7 +180,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) this->AlreadyInCache = true; return true; } - this->AlreadyInCache = false; + this->AlreadyInCache = false; // Find the current root path mode. this->SelectDefaultRootPathMode(); @@ -213,6 +215,19 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) compatibility = false; newStyle = true; } + else if (args[j] == "NAMES_PER_DIR") + { + doing = DoingNone; + if(this->NamesPerDirAllowed) + { + this->NamesPerDir = true; + } + else + { + this->SetError("does not support NAMES_PER_DIR"); + return false; + } + } else if (args[j] == "NO_SYSTEM_PATH") { doing = DoingNone; @@ -264,17 +279,17 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } else if(this->Names.size() == 1) { - this->VariableDocumentation += "the " + this->VariableDocumentation += "the " + this->Names[0] + " library be found"; } else - { + { this->VariableDocumentation += "one of the " + this->Names[0]; for (unsigned int j = 1; j < this->Names.size() - 1; ++j) { this->VariableDocumentation += ", " + this->Names[j]; } - this->VariableDocumentation += " or " + this->VariableDocumentation += " or " + this->Names[this->Names.size() - 1] + " libraries be found"; } } @@ -504,7 +519,7 @@ void cmFindBase::AddPathSuffixes() cmSystemTools::ConvertToUnixSlashes(*i); // copy each finalPath combined with SearchPathSuffixes // to the SearchPaths ivar - for(std::vector<std::string>::iterator j = + for(std::vector<std::string>::iterator j = this->SearchPathSuffixes.begin(); j != this->SearchPathSuffixes.end(); ++j) { @@ -517,7 +532,7 @@ void cmFindBase::AddPathSuffixes() p += std::string("/"); } p += *j; - // add to all paths because the search path may be modified + // add to all paths because the search path may be modified // later with lib being replaced for lib64 which may exist paths.push_back(p); } @@ -535,13 +550,13 @@ void cmFindBase::PrintFindStuff() std::cerr << "SearchAppBundleOnly: " << this->SearchAppBundleOnly << "\n"; std::cerr << "SearchAppBundleFirst: " << this->SearchAppBundleFirst << "\n"; std::cerr << "VariableName " << this->VariableName << "\n"; - std::cerr << "VariableDocumentation " + std::cerr << "VariableDocumentation " << this->VariableDocumentation << "\n"; std::cerr << "NoDefaultPath " << this->NoDefaultPath << "\n"; - std::cerr << "NoCMakeEnvironmentPath " + std::cerr << "NoCMakeEnvironmentPath " << this->NoCMakeEnvironmentPath << "\n"; std::cerr << "NoCMakePath " << this->NoCMakePath << "\n"; - std::cerr << "NoSystemEnvironmentPath " + std::cerr << "NoSystemEnvironmentPath " << this->NoSystemEnvironmentPath << "\n"; std::cerr << "NoCMakeSystemPath " << this->NoCMakeSystemPath << "\n"; std::cerr << "EnvironmentPath " << this->EnvironmentPath << "\n"; diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index 37ab2ec..84b0330 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -30,7 +30,7 @@ public: */ virtual bool ParseArguments(std::vector<std::string> const& args); cmTypeMacro(cmFindBase, cmFindCommon); - + virtual const char* GetFullDocumentation() const; protected: @@ -43,12 +43,14 @@ protected: // also copy the documentation from the cache to VariableDocumentation // if it has documentation in the cache bool CheckForVariableInCache(); - + cmStdString GenericDocumentation; // use by command during find cmStdString VariableDocumentation; cmStdString VariableName; std::vector<std::string> Names; + bool NamesPerDir; + bool NamesPerDirAllowed; // CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM cmStdString EnvironmentPath; // LIB,INCLUDE diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h index 7d349d3..1bfdcbd 100644 --- a/Source/cmFindFileCommand.h +++ b/Source/cmFindFileCommand.h @@ -18,7 +18,7 @@ * \brief Define a command to search for an executable program. * * cmFindFileCommand is used to define a CMake variable - * that specifies an executable program. The command searches + * that specifies an executable program. The command searches * in the current path (e.g., PATH environment variable) for * an executable that matches one of the supplied names. */ @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmFindFileCommand; } @@ -42,7 +42,7 @@ public: { return "Find the full path to a file."; } - + cmTypeMacro(cmFindFileCommand, cmFindPathCommand); protected: virtual void GenerateDocumentation(); diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 6cdbbf2..4af7e11 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -15,8 +15,9 @@ #include <cmsys/stl/algorithm> cmFindLibraryCommand::cmFindLibraryCommand() -{ +{ this->EnvironmentPath = "LIB"; + this->NamesPerDirAllowed = true; } //---------------------------------------------------------------------------- @@ -44,6 +45,9 @@ void cmFindLibraryCommand::GenerateDocumentation() "SEARCH_XXX", "library"); cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SUBDIR", "lib"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "NAMES name1 [name2 ...]", + "NAMES name1 [name2 ...] [NAMES_PER_DIR]"); cmSystemTools::ReplaceString( this->GenericDocumentation, "XXX_EXTRA_PREFIX_ENTRY", @@ -53,6 +57,12 @@ void cmFindLibraryCommand::GenerateDocumentation() "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY"); this->GenericDocumentation += "\n" + "When more than one value is given to the NAMES option this command " + "by default will consider one name at a time and search every directory " + "for it. " + "The NAMES_PER_DIR option tells this command to consider one directory " + "at a time and search for all names in it." + "\n" "If the library found is a framework, then VAR will be set to " "the full path to the framework <fullPath>/A.framework. " "When a full path to a framework is used as a library, " @@ -105,7 +115,10 @@ bool cmFindLibraryCommand ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS")) { // add special 64 bit paths if this is a 64 bit compile. - this->AddLib64Paths(); + if(this->Makefile->PlatformIs64Bit()) + { + this->AddArchitecturePaths("64"); + } } std::string library = this->FindLibrary(); @@ -129,90 +142,55 @@ bool cmFindLibraryCommand //---------------------------------------------------------------------------- void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix) { - std::vector<std::string> newPaths; - bool found = false; - std::string subpath = "lib"; - subpath += suffix; - subpath += "/"; - for(std::vector<std::string>::iterator i = this->SearchPaths.begin(); - i != this->SearchPaths.end(); ++i) + std::vector<std::string> original; + original.swap(this->SearchPaths); + for(std::vector<std::string>::iterator i = original.begin(); + i != original.end(); ++i) { - // Try replacing lib/ with lib<suffix>/ - std::string s = *i; - cmSystemTools::ReplaceString(s, "lib/", subpath.c_str()); - if((s != *i) && cmSystemTools::FileIsDirectory(s.c_str())) - { - found = true; - newPaths.push_back(s); - } + this->AddArchitecturePath(*i, 0, suffix); + } +} - // Now look for lib<suffix> - s = *i; - s += suffix; - if(cmSystemTools::FileIsDirectory(s.c_str())) +//---------------------------------------------------------------------------- +void cmFindLibraryCommand::AddArchitecturePath( + std::string const& dir, std::string::size_type start_pos, + const char* suffix, bool fresh) +{ + std::string::size_type pos = dir.find("lib/", start_pos); + if(pos != std::string::npos) + { + std::string cur_dir = dir.substr(0,pos+3); + + // Follow "lib<suffix>". + std::string next_dir = cur_dir + suffix; + if(cmSystemTools::FileIsDirectory(next_dir.c_str())) { - found = true; - newPaths.push_back(s); + next_dir += dir.substr(pos+3); + std::string::size_type next_pos = pos+3+strlen(suffix)+1; + this->AddArchitecturePath(next_dir, next_pos, suffix); } - // now add the original unchanged path - if(cmSystemTools::FileIsDirectory(i->c_str())) + + // Follow "lib". + if(cmSystemTools::FileIsDirectory(cur_dir.c_str())) { - newPaths.push_back(*i); + this->AddArchitecturePath(dir, pos+3+1, suffix, false); } } - - // If any new paths were found replace the original set. - if(found) + if(fresh) { - this->SearchPaths = newPaths; - } -} - -void cmFindLibraryCommand::AddLib64Paths() -{ - std::string voidsize = - this->Makefile->GetSafeDefinition("CMAKE_SIZEOF_VOID_P"); - int size = atoi(voidsize.c_str()); - if(size != 8) - { - return; - } - std::vector<std::string> path64; - bool found64 = false; - for(std::vector<std::string>::iterator i = this->SearchPaths.begin(); - i != this->SearchPaths.end(); ++i) - { - std::string s = *i; - std::string s2 = *i; - cmSystemTools::ReplaceString(s, "lib/", "lib64/"); - // try to replace lib with lib64 and see if it is there, - // then prepend it to the path - // Note that all paths have trailing slashes. - if((s != *i) && cmSystemTools::FileIsDirectory(s.c_str())) + // Check for <dir><suffix>/. + std::string cur_dir = dir + suffix + "/"; + if(cmSystemTools::FileIsDirectory(cur_dir.c_str())) { - path64.push_back(s); - found64 = true; - } - // now just add a 64 to the path name and if it is there, - // add it to the path - s2 += "64/"; - if(cmSystemTools::FileIsDirectory(s2.c_str())) - { - found64 = true; - path64.push_back(s2); - } - // now add the original unchanged path - if(cmSystemTools::FileIsDirectory(i->c_str())) + this->SearchPaths.push_back(cur_dir); + } + + // Now add the original unchanged path + if(cmSystemTools::FileIsDirectory(dir.c_str())) { - path64.push_back(*i); + this->SearchPaths.push_back(dir); } } - // now replace the SearchPaths with the 64 bit converted path - // if any 64 bit paths were discovered - if(found64) - { - this->SearchPaths = path64; - } } //---------------------------------------------------------------------------- @@ -252,18 +230,19 @@ struct cmFindLibraryHelper // Keep track of the best library file found so far. typedef std::vector<std::string>::size_type size_type; std::string BestPath; - size_type BestPrefix; - size_type BestSuffix; // Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor> bool OpenBSD; - unsigned int BestMajor; - unsigned int BestMinor; - // Current name under consideration. - cmsys::RegularExpression NameRegex; - bool TryRawName; - std::string RawName; + // Current names under consideration. + struct Name + { + bool TryRaw; + std::string Raw; + cmsys::RegularExpression Regex; + Name(): TryRaw(false) {} + }; + std::vector<Name> Names; // Current full path under consideration. std::string TestPath; @@ -281,8 +260,9 @@ struct cmFindLibraryHelper suffix) - this->Suffixes.begin(); } bool HasValidSuffix(std::string const& name); - void SetName(std::string const& name); + void AddName(std::string const& name); bool CheckDirectory(std::string const& path); + bool CheckDirectoryForName(std::string const& path, Name& name); }; //---------------------------------------------------------------------------- @@ -305,14 +285,6 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf): this->OpenBSD = this->Makefile->GetCMakeInstance() ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING"); - - this->TryRawName = false; - - // No library file has yet been found. - this->BestPrefix = this->Prefixes.size(); - this->BestSuffix = this->Suffixes.size(); - this->BestMajor = 0; - this->BestMinor = 0; } //---------------------------------------------------------------------------- @@ -385,11 +357,13 @@ bool cmFindLibraryHelper::HasValidSuffix(std::string const& name) } //---------------------------------------------------------------------------- -void cmFindLibraryHelper::SetName(std::string const& name) +void cmFindLibraryHelper::AddName(std::string const& name) { + Name entry; + // Consider checking the raw name too. - this->TryRawName = this->HasValidSuffix(name); - this->RawName = name; + entry.TryRaw = this->HasValidSuffix(name); + entry.Raw = name; // Build a regular expression to match library names. std::string regex = "^"; @@ -401,21 +375,37 @@ void cmFindLibraryHelper::SetName(std::string const& name) regex += "(\\.[0-9]+\\.[0-9]+)?"; } regex += "$"; - this->NameRegex.compile(regex.c_str()); + entry.Regex.compile(regex.c_str()); + this->Names.push_back(entry); } //---------------------------------------------------------------------------- bool cmFindLibraryHelper::CheckDirectory(std::string const& path) { + for(std::vector<Name>::iterator i = this->Names.begin(); + i != this->Names.end(); ++i) + { + if(this->CheckDirectoryForName(path, *i)) + { + return true; + } + } + return false; +} + +//---------------------------------------------------------------------------- +bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path, + Name& name) +{ // If the original library name provided by the user matches one of // the suffixes, try it first. This allows users to search // specifically for a static library on some platforms (on MS tools // one cannot tell just from the library name whether it is a static // library or an import library). - if(this->TryRawName) + if(name.TryRaw) { this->TestPath = path; - this->TestPath += this->RawName; + this->TestPath += name.Raw; if(cmSystemTools::FileExists(this->TestPath.c_str(), true)) { this->BestPath = @@ -425,6 +415,12 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path) } } + // No library file has yet been found. + size_type bestPrefix = this->Prefixes.size(); + size_type bestSuffix = this->Suffixes.size(); + unsigned int bestMajor = 0; + unsigned int bestMinor = 0; + // Search for a file matching the library name regex. std::string dir = path; cmSystemTools::ConvertToUnixSlashes(dir); @@ -438,7 +434,7 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path) #else std::string const& testName = origName; #endif - if(this->NameRegex.find(testName)) + if(name.Regex.find(testName)) { this->TestPath = path; this->TestPath += origName; @@ -448,25 +444,25 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path) // best name found so far. Earlier prefixes are preferred, // followed by earlier suffixes. For OpenBSD, shared library // version extensions are compared. - size_type prefix = this->GetPrefixIndex(this->NameRegex.match(1)); - size_type suffix = this->GetSuffixIndex(this->NameRegex.match(2)); + size_type prefix = this->GetPrefixIndex(name.Regex.match(1)); + size_type suffix = this->GetSuffixIndex(name.Regex.match(2)); unsigned int major = 0; unsigned int minor = 0; if(this->OpenBSD) { - sscanf(this->NameRegex.match(3).c_str(), ".%u.%u", &major, &minor); + sscanf(name.Regex.match(3).c_str(), ".%u.%u", &major, &minor); } - if(this->BestPath.empty() || prefix < this->BestPrefix || - (prefix == this->BestPrefix && suffix < this->BestSuffix) || - (prefix == this->BestPrefix && suffix == this->BestSuffix && - (major > this->BestMajor || - (major == this->BestMajor && minor > this->BestMinor)))) + if(this->BestPath.empty() || prefix < bestPrefix || + (prefix == bestPrefix && suffix < bestSuffix) || + (prefix == bestPrefix && suffix == bestSuffix && + (major > bestMajor || + (major == bestMajor && minor > bestMinor)))) { this->BestPath = this->TestPath; - this->BestPrefix = prefix; - this->BestSuffix = suffix; - this->BestMajor = major; - this->BestMinor = minor; + bestPrefix = prefix; + bestSuffix = suffix; + bestMajor = major; + bestMinor = minor; } } } @@ -479,6 +475,42 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path) //---------------------------------------------------------------------------- std::string cmFindLibraryCommand::FindNormalLibrary() { + if(this->NamesPerDir) + { + return this->FindNormalLibraryNamesPerDir(); + } + else + { + return this->FindNormalLibraryDirsPerName(); + } +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir() +{ + // Search for all names in each directory. + cmFindLibraryHelper helper(this->Makefile); + for(std::vector<std::string>::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + helper.AddName(*ni); + } + // Search every directory. + for(std::vector<std::string>::const_iterator + p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p) + { + if(helper.CheckDirectory(*p)) + { + return helper.BestPath; + } + } + // Couldn't find the library. + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName() +{ // Search the entire path for each name. cmFindLibraryHelper helper(this->Makefile); for(std::vector<std::string>::const_iterator ni = this->Names.begin(); @@ -486,7 +518,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary() { // Switch to searching for this name. std::string const& name = *ni; - helper.SetName(name); + helper.AddName(name); // Search every directory. for(std::vector<std::string>::const_iterator @@ -506,19 +538,60 @@ std::string cmFindLibraryCommand::FindNormalLibrary() //---------------------------------------------------------------------------- std::string cmFindLibraryCommand::FindFrameworkLibrary() { - // Search for a framework of each name in the entire search path. + if(this->NamesPerDir) + { + return this->FindFrameworkLibraryNamesPerDir(); + } + else + { + return this->FindFrameworkLibraryDirsPerName(); + } +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir() +{ + std::string fwPath; + // Search for all names in each search path. + for(std::vector<std::string>::const_iterator di = this->SearchPaths.begin(); + di != this->SearchPaths.end(); ++di) + { + for(std::vector<std::string>::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + fwPath = *di; + fwPath += *ni; + fwPath += ".framework"; + if(cmSystemTools::FileIsDirectory(fwPath.c_str())) + { + return cmSystemTools::CollapseFullPath(fwPath.c_str()); + } + } + } + + // No framework found. + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName() +{ + std::string fwPath; + // Search for each name in all search paths. for(std::vector<std::string>::const_iterator ni = this->Names.begin(); ni != this->Names.end() ; ++ni) { - // Search the paths for a framework with this name. - std::string fwName = *ni; - fwName += ".framework"; - std::string fwPath = cmSystemTools::FindDirectory(fwName.c_str(), - this->SearchPaths, - true); - if(!fwPath.empty()) + for(std::vector<std::string>::const_iterator + di = this->SearchPaths.begin(); + di != this->SearchPaths.end(); ++di) { - return fwPath; + fwPath = *di; + fwPath += *ni; + fwPath += ".framework"; + if(cmSystemTools::FileIsDirectory(fwPath.c_str())) + { + return cmSystemTools::CollapseFullPath(fwPath.c_str()); + } } } diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index b880be2..cd0fce8 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmFindLibraryCommand; } @@ -59,15 +59,22 @@ public: return "Find a library."; } cmTypeMacro(cmFindLibraryCommand, cmFindBase); - + protected: void AddArchitecturePaths(const char* suffix); - void AddLib64Paths(); + void AddArchitecturePath(std::string const& dir, + std::string::size_type start_pos, + const char* suffix, + bool fresh = true); std::string FindLibrary(); virtual void GenerateDocumentation(); private: std::string FindNormalLibrary(); + std::string FindNormalLibraryNamesPerDir(); + std::string FindNormalLibraryDirsPerName(); std::string FindFrameworkLibrary(); + std::string FindFrameworkLibraryNamesPerDir(); + std::string FindFrameworkLibraryDirsPerName(); }; diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index be47f95..470ceca 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -840,6 +840,8 @@ bool cmFindPackageCommand //---------------------------------------------------------------------------- void cmFindPackageCommand::SetModuleVariables(const std::string& components) { + this->AddFindDefinition("CMAKE_FIND_PACKAGE_NAME", this->Name.c_str()); + // Store the list of components. std::string components_var = this->Name + "_FIND_COMPONENTS"; this->AddFindDefinition(components_var.c_str(), components.c_str()); @@ -1016,6 +1018,9 @@ bool cmFindPackageCommand::HandlePackageMode() std::string foundVar = this->Name; foundVar += "_FOUND"; + std::string notFoundMessageVar = this->Name; + notFoundMessageVar += "_NOT_FOUND_MESSAGE"; + std::string notFoundMessage; // If the directory for the config file was found, try to read the file. bool result = true; @@ -1033,6 +1038,7 @@ bool cmFindPackageCommand::HandlePackageMode() // has set Foo_FOUND to FALSE itself: this->Makefile->RemoveDefinition(foundVar.c_str()); } + this->Makefile->RemoveDefinition(notFoundMessageVar.c_str()); // Set the version variables before loading the config file. // It may override them. @@ -1051,6 +1057,8 @@ bool cmFindPackageCommand::HandlePackageMode() // we get here if the Config file has set Foo_FOUND actively to FALSE found = false; configFileSetFOUNDFalse = true; + notFoundMessage = this->Makefile->GetSafeDefinition( + notFoundMessageVar.c_str()); } } else @@ -1071,6 +1079,10 @@ bool cmFindPackageCommand::HandlePackageMode() " " << this->FileFound << "\n" "but it set " << foundVar << " to FALSE so package \"" << this->Name << "\" is considered to be NOT FOUND."; + if (!notFoundMessage.empty()) + { + e << " Reason given by package: \n" << notFoundMessage << "\n"; + } } // If there are files in ConsideredConfigs, it means that FooConfig.cmake // have been found, but they didn't have appropriate versions. diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 846d187..9524924 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -104,7 +104,7 @@ bool cmFindPathCommand (this->VariableName.c_str(), (this->VariableName + "-NOTFOUND").c_str(), this->VariableDocumentation.c_str(), - (this->IncludeFileInPath) ? + (this->IncludeFileInPath) ? cmCacheManager::FILEPATH :cmCacheManager::PATH); return true; } @@ -143,14 +143,14 @@ cmFindPathCommand::FindHeaderInFramework(std::string const& file, // remove the name from the slash; fileName = fileName.substr(pos+1); frameWorkName = file; - frameWorkName = + frameWorkName = frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1); // if the framework has a path in it then just use the filename if(frameWorkName.find("/") != frameWorkName.npos) { fileName = file; frameWorkName = ""; - } + } if(frameWorkName.size()) { std::string fpath = dir; @@ -160,7 +160,7 @@ cmFindPathCommand::FindHeaderInFramework(std::string const& file, intPath += "/Headers/"; intPath += fileName; if(cmSystemTools::FileExists(intPath.c_str())) - { + { if(this->IncludeFileInPath) { return intPath; diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h index a612990..759567d 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmFindPathCommand; } diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 00f5419..909b333 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -81,7 +81,7 @@ bool cmFindProgramCommand result.c_str(), this->VariableDocumentation.c_str(), cmCacheManager::FILEPATH); - + return true; } this->Makefile->AddCacheDefinition(this->VariableName.c_str(), @@ -117,21 +117,21 @@ std::string cmFindProgramCommand for(std::vector<std::string>::const_iterator name = names.begin(); name != names.end() ; ++name) { - + std::string appName = *name + std::string(".app"); - std::string appPath = cmSystemTools::FindDirectory(appName.c_str(), - this->SearchPaths, + std::string appPath = cmSystemTools::FindDirectory(appName.c_str(), + this->SearchPaths, true); if ( !appPath.empty() ) { std::string executable = GetBundleExecutable(appPath); - if (!executable.empty()) + if (!executable.empty()) { return cmSystemTools::CollapseFullPath(executable.c_str()); } - } - } + } + } // Couldn't find app bundle return ""; @@ -142,44 +142,44 @@ std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath) std::string executable = ""; (void)bundlePath; #if defined(__APPLE__) - // Started with an example on developer.apple.com about finding bundles + // Started with an example on developer.apple.com about finding bundles // and modified from that. - + // Get a CFString of the app bundle path // XXX - Is it safe to assume everything is in UTF8? - CFStringRef bundlePathCFS = - CFStringCreateWithCString(kCFAllocatorDefault , + CFStringRef bundlePathCFS = + CFStringCreateWithCString(kCFAllocatorDefault , bundlePath.c_str(), kCFStringEncodingUTF8 ); - + // Make a CFURLRef from the CFString representation of the // bundle’s path. - CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundlePathCFS, kCFURLPOSIXPathStyle, true ); - + // Make a bundle instance using the URLRef. CFBundleRef appBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL ); - + // returned executableURL is relative to <appbundle>/Contents/MacOS/ CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle); - + if (executableURL != NULL) { const int MAX_OSX_PATH_SIZE = 1024; char buffer[MAX_OSX_PATH_SIZE]; - + // Convert the CFString to a C string - CFStringGetCString( CFURLGetString(executableURL), buffer, + CFStringGetCString( CFURLGetString(executableURL), buffer, MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); - + // And finally to a c++ string executable = bundlePath + "/Contents/MacOS/" + std::string(buffer); // Only release CFURLRef if it's not null CFRelease( executableURL ); } - // Any CF objects returned from functions with "create" or + // Any CF objects returned from functions with "create" or // "copy" in their names must be released by us! CFRelease( bundlePathCFS ); CFRelease( bundleURL ); diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h index c1b14f9..8350c9b 100644 --- a/Source/cmFindProgramCommand.h +++ b/Source/cmFindProgramCommand.h @@ -18,7 +18,7 @@ * \brief Define a command to search for an executable program. * * cmFindProgramCommand is used to define a CMake variable - * that specifies an executable program. The command searches + * that specifies an executable program. The command searches * in the current path (e.g., PATH environment variable) for * an executable that matches one of the supplied names. */ @@ -28,7 +28,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmFindProgramCommand; } @@ -57,7 +57,7 @@ public: { return "Find an executable program."; } - + cmTypeMacro(cmFindProgramCommand, cmFindBase); protected: diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 74966c9..d697067 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -25,7 +25,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach")) { // if this is the endofreach for this statement - if (!this->Depth) + if (!this->Depth) { // Remove the function blocker for this scope or bail. cmsys::auto_ptr<cmFunctionBlocker> @@ -45,7 +45,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, std::string tmps; cmListFileArgument arg; for( ; j != this->Args.end(); ++j) - { + { // set the variable to the loop value mf.AddDefinition(this->Args[0].c_str(),j->c_str()); // Invoke all the functions that were collected in the block. @@ -83,10 +83,10 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, this->Depth--; } } - + // record the command this->Functions.push_back(lff); - + // always return true return true; } @@ -121,7 +121,7 @@ bool cmForEachCommand { return this->HandleInMode(args); } - + // create a function blocker cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker(); if ( args.size() > 1 ) @@ -157,7 +157,7 @@ bool cmForEachCommand step = 1; } } - if ( + if ( (start > stop && step > 0) || (start < stop && step < 0) || step == 0 @@ -198,7 +198,7 @@ bool cmForEachCommand f->Args = args; } this->Makefile->AddFunctionBlocker(f); - + return true; } diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index ae50005..dc47613 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -25,7 +25,7 @@ public: cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - + std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; private: @@ -39,7 +39,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmForEachCommand; } @@ -68,7 +68,7 @@ public: { return "Evaluate a group of commands for each value in a list."; } - + /** * More documentation. */ @@ -106,7 +106,7 @@ public: "following it in the iteration." ; } - + cmTypeMacro(cmForEachCommand, cmCommand); private: bool HandleInMode(std::vector<std::string> const& args); diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index 9ee0b5c..68bf762 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -29,7 +29,7 @@ public: /** * should this function blocker be removed, useful when one function adds a - * blocker and another must remove it + * blocker and another must remove it */ virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile&) {return false;} diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index ce36145..10b47b9 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -65,7 +65,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const { return this->Args[0].c_str(); } - + /** * Succinct documentation. */ @@ -131,15 +131,15 @@ bool cmFunctionHelperCommand::InvokeInitialPass { cmOStringStream tmpStream; tmpStream << "ARGV" << t; - this->Makefile->AddDefinition(tmpStream.str().c_str(), + this->Makefile->AddDefinition(tmpStream.str().c_str(), expandedArgs[t].c_str()); this->Makefile->MarkVariableAsUsed(tmpStream.str().c_str()); } - + // define the formal arguments for (unsigned int j = 1; j < this->Args.size(); ++j) { - this->Makefile->AddDefinition(this->Args[j].c_str(), + this->Makefile->AddDefinition(this->Args[j].c_str(), expandedArgs[j-1].c_str()); } @@ -208,7 +208,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, else if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction")) { // if this is the endfunction for this function then execute - if (!this->Depth) + if (!this->Depth) { std::string name = this->Args[0]; std::vector<std::string>::size_type cc; @@ -224,20 +224,20 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, f->Args = this->Args; f->Functions = this->Functions; mf.RecordPolicies(f->Policies); - + // Set the FilePath on the arguments to match the function since it is // not stored and the original values may be freed for (unsigned int i = 0; i < f->Functions.size(); ++i) { for (unsigned int j = 0; j < f->Functions[i].Arguments.size(); ++j) { - f->Functions[i].Arguments[j].FilePath = + f->Functions[i].Arguments[j].FilePath = f->Functions[i].FilePath.c_str(); } } std::string newName = "_" + this->Args[0]; - mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(), + mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(), newName.c_str()); mf.AddCommand(f); @@ -265,7 +265,7 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction")) { std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); + mf.ExpandArguments(lff.Arguments, expandedArguments); // if the endfunction has arguments then make sure // they match the ones in the openeing function command if ((expandedArguments.empty() || @@ -291,7 +291,7 @@ bool cmFunctionCommand cmFunctionFunctionBlocker *f = new cmFunctionFunctionBlocker(); for(std::vector<std::string>::const_iterator j = args.begin(); j != args.end(); ++j) - { + { f->Args.push_back(*j); } this->Makefile->AddFunctionBlocker(f); diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h index 43c8e29..730a7a7 100644 --- a/Source/cmFunctionCommand.h +++ b/Source/cmFunctionCommand.h @@ -20,11 +20,11 @@ class cmFunctionFunctionBlocker : public cmFunctionBlocker public: cmFunctionFunctionBlocker() {this->Depth=0;} virtual ~cmFunctionFunctionBlocker() {} - virtual bool IsFunctionBlocked(const cmListFileFunction&, + virtual bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf); - + std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; int Depth; diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 1a391ed..0af0753 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -31,7 +31,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet): // Check if the file opened. if(!*this && !quiet) { - cmSystemTools::Error("Cannot open file for write: ", + cmSystemTools::Error("Cannot open file for write: ", this->TempName.c_str()); cmSystemTools::ReportLastSystemError(""); } @@ -58,7 +58,7 @@ cmGeneratedFileStream::Open(const char* name, bool quiet, bool binaryFlag) // Open the temporary output file. if ( binaryFlag ) { - this->Stream::open(this->TempName.c_str(), + this->Stream::open(this->TempName.c_str(), std::ios::out | std::ios::binary); } else @@ -69,7 +69,7 @@ cmGeneratedFileStream::Open(const char* name, bool quiet, bool binaryFlag) // Check if the file opened. if(!*this && !quiet) { - cmSystemTools::Error("Cannot open file for write: ", + cmSystemTools::Error("Cannot open file for write: ", this->TempName.c_str()); cmSystemTools::ReportLastSystemError(""); } diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index f88ab0b..7d8df37 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -13,181 +13,168 @@ #include "cmMakefile.h" #include "cmTarget.h" +#include "assert.h" + +#include <cmsys/String.h> + +#include "cmGeneratorExpressionEvaluator.h" +#include "cmGeneratorExpressionLexer.h" +#include "cmGeneratorExpressionParser.h" +#include "cmGeneratorExpressionDAGChecker.h" //---------------------------------------------------------------------------- cmGeneratorExpression::cmGeneratorExpression( - cmMakefile* mf, const char* config, - cmListFileBacktrace const& backtrace, bool quiet): - Makefile(mf), Config(config), Backtrace(backtrace), Quiet(quiet) + cmListFileBacktrace const& backtrace): + Backtrace(backtrace), CompiledExpression(0) { - this->TargetInfo.compile("^\\$<TARGET" - "(|_SONAME|_LINKER)" // File with what purpose? - "_FILE(|_NAME|_DIR):" // Filename component. - "([A-Za-z0-9_.-]+)" // Target name. - ">$"); } //---------------------------------------------------------------------------- -const char* cmGeneratorExpression::Process(std::string const& input) +const cmCompiledGeneratorExpression & +cmGeneratorExpression::Parse(std::string const& input) { - return this->Process(input.c_str()); + return this->Parse(input.c_str()); } //---------------------------------------------------------------------------- -const char* cmGeneratorExpression::Process(const char* input) +const cmCompiledGeneratorExpression & +cmGeneratorExpression::Parse(const char* input) { - this->Data.clear(); + cmGeneratorExpressionLexer l; + std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(input); + bool needsParsing = l.GetSawGeneratorExpression(); + std::vector<cmGeneratorExpressionEvaluator*> evaluators; - // We construct and evaluate expressions directly in the output - // buffer. Each expression is replaced by its own output value - // after evaluation. A stack of barriers records the starting - // indices of open (pending) expressions. - for(const char* c = input; *c; ++c) + if (needsParsing) { - if(c[0] == '$' && c[1] == '<') - { - this->Barriers.push(this->Data.size()); - this->Data.push_back('$'); - this->Data.push_back('<'); - c += 1; - } - else if(c[0] == '>' && !this->Barriers.empty()) - { - this->Data.push_back('>'); - if(!this->Evaluate()) { break; } - this->Barriers.pop(); - } - else - { - this->Data.push_back(c[0]); - } + cmGeneratorExpressionParser p(tokens); + p.Parse(evaluators); } - // Return a null-terminated output value. - this->Data.push_back('\0'); - return &*this->Data.begin(); + delete this->CompiledExpression; + this->CompiledExpression = new cmCompiledGeneratorExpression( + this->Backtrace, + evaluators, + input, + needsParsing); + return *this->CompiledExpression; } -//---------------------------------------------------------------------------- -bool cmGeneratorExpression::Evaluate() +cmGeneratorExpression::~cmGeneratorExpression() { - // The top-most barrier points at the beginning of the expression. - size_t barrier = this->Barriers.top(); - - // Construct a null-terminated representation of the expression. - this->Data.push_back('\0'); - const char* expr = &*(this->Data.begin()+barrier); - - // Evaluate the expression. - std::string result; - if(this->Evaluate(expr, result)) - { - // Success. Replace the expression with its evaluation result. - this->Data.erase(this->Data.begin()+barrier, this->Data.end()); - this->Data.insert(this->Data.end(), result.begin(), result.end()); - return true; - } - else if(!this->Quiet) - { - // Failure. Report the error message. - cmOStringStream e; - e << "Error evaluating generator expression:\n" - << " " << expr << "\n" - << result; - this->Makefile->GetCMakeInstance() - ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), - this->Backtrace); - return false; - } - return true; + delete this->CompiledExpression; } //---------------------------------------------------------------------------- -bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result) +const char *cmCompiledGeneratorExpression::Evaluate( + cmMakefile* mf, const char* config, bool quiet, + cmGeneratorTarget *target, + cmGeneratorExpressionDAGChecker *dagChecker) const { - if(this->TargetInfo.find(expr)) - { - if(!this->EvaluateTargetInfo(result)) - { - return false; - } - } - else if(strcmp(expr, "$<CONFIGURATION>") == 0) + if (!this->NeedsParsing) { - result = this->Config? this->Config : ""; + return this->Input; } - else + + this->Output = ""; + + std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it + = this->Evaluators.begin(); + const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end + = this->Evaluators.end(); + + cmGeneratorExpressionContext context; + context.Makefile = mf; + context.Config = config; + context.Quiet = quiet; + context.HadError = false; + context.Target = target; + context.Backtrace = this->Backtrace; + + for ( ; it != end; ++it) { - result = "Expression syntax not recognized."; - return false; + this->Output += (*it)->Evaluate(&context, dagChecker); + if (context.HadError) + { + this->Output = ""; + break; + } } - return true; + + this->Targets = context.Targets; + // TODO: Return a std::string from here instead? + return this->Output.c_str(); } +cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( + cmListFileBacktrace const& backtrace, + const std::vector<cmGeneratorExpressionEvaluator*> &evaluators, + const char *input, bool needsParsing) + : Backtrace(backtrace), Evaluators(evaluators), Input(input), + NeedsParsing(needsParsing) +{ + +} + + //---------------------------------------------------------------------------- -bool cmGeneratorExpression::EvaluateTargetInfo(std::string& result) +cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() { - // Lookup the referenced target. - std::string name = this->TargetInfo.match(3); - cmTarget* target = this->Makefile->FindTargetToUse(name.c_str()); - if(!target) - { - result = "No target \"" + name + "\""; - return false; - } - if(target->GetType() >= cmTarget::UTILITY && - target->GetType() != cmTarget::UNKNOWN_LIBRARY) - { - result = "Target \"" + name + "\" is not an executable or library."; - return false; - } - this->Targets.insert(target); + std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it + = this->Evaluators.begin(); + const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end + = this->Evaluators.end(); - // Lookup the target file with the given purpose. - std::string purpose = this->TargetInfo.match(1); - if(purpose == "") + for ( ; it != end; ++it) { - // The target implementation file (.so.1.2, .dll, .exe, .a). - result = target->GetFullPath(this->Config, false, true); + delete *it; } - else if(purpose == "_LINKER") - { - // The file used to link to the target (.so, .lib, .a). - if(!target->IsLinkable()) - { - result = ("TARGET_LINKER_FILE is allowed only for libraries and " - "executables with ENABLE_EXPORTS."); - return false; - } - result = target->GetFullPath(this->Config, target->HasImportLibrary()); - } - else if(purpose == "_SONAME") +} + +std::string cmGeneratorExpression::Preprocess(const std::string &input, + PreprocessContext context) +{ + if (context != StripAllGeneratorExpressions) + { + assert(!"cmGeneratorExpression::Preprocess called with invalid args"); + return std::string(); + } + + std::string result; + std::string::size_type pos = 0; + std::string::size_type lastPos = pos; + while((pos = input.find("$<", lastPos)) != input.npos) { - // The target soname file (.so.1). - if(target->IsDLLPlatform()) + result += input.substr(lastPos, pos - lastPos); + pos += 2; + int nestingLevel = 1; + const char *c = input.c_str() + pos; + const char * const cStart = c; + for ( ; *c; ++c) { - result = "TARGET_SONAME_FILE is not allowed for DLL target platforms."; - return false; + if(c[0] == '$' && c[1] == '<') + { + ++nestingLevel; + ++c; + continue; + } + if(c[0] == '>') + { + --nestingLevel; + if (nestingLevel == 0) + { + break; + } + } } - if(target->GetType() != cmTarget::SHARED_LIBRARY) + const std::string::size_type traversed = (c - cStart) + 1; + if (!*c) { - result = "TARGET_SONAME_FILE is allowed only for SHARED libraries."; - return false; + result += "$<" + input.substr(pos, traversed); } - result = target->GetDirectory(this->Config); - result += "/"; - result += target->GetSOName(this->Config); - } - - // Extract the requested portion of the full path. - std::string part = this->TargetInfo.match(2); - if(part == "_NAME") - { - result = cmSystemTools::GetFilenameName(result); - } - else if(part == "_DIR") - { - result = cmSystemTools::GetFilenamePath(result); + pos += traversed; + lastPos = pos; } - return true; + result += input.substr(lastPos); + return result; } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 1a9d4c6..29d3f44 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -9,6 +9,10 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ + +#ifndef cmGeneratorExpression_h +#define cmGeneratorExpression_h + #include "cmStandardIncludes.h" #include <stack> @@ -16,9 +20,15 @@ #include <cmsys/RegularExpression.hxx> class cmTarget; +class cmGeneratorTarget; class cmMakefile; class cmListFileBacktrace; +struct cmGeneratorExpressionEvaluator; +struct cmGeneratorExpressionDAGChecker; + +class cmCompiledGeneratorExpression; + /** \class cmGeneratorExpression * \brief Evaluate generate-time query expression syntax. * @@ -31,28 +41,59 @@ class cmListFileBacktrace; class cmGeneratorExpression { public: - /** Construct with an evaluation context and configuration. */ - cmGeneratorExpression(cmMakefile* mf, const char* config, - cmListFileBacktrace const& backtrace, - bool quiet = false); + /** Construct. */ + cmGeneratorExpression(cmListFileBacktrace const& backtrace); + ~cmGeneratorExpression(); + + const cmCompiledGeneratorExpression& Parse(std::string const& input); + const cmCompiledGeneratorExpression& Parse(const char* input); + + enum PreprocessContext { + StripAllGeneratorExpressions + }; - /** Evaluate generator expressions in a string. */ - const char* Process(std::string const& input); - const char* Process(const char* input); + static std::string Preprocess(const std::string &input, + PreprocessContext context); + +private: + cmGeneratorExpression(const cmGeneratorExpression &); + void operator=(const cmGeneratorExpression &); + + cmListFileBacktrace const& Backtrace; + cmCompiledGeneratorExpression *CompiledExpression; +}; + +class cmCompiledGeneratorExpression +{ +public: + const char* Evaluate(cmMakefile* mf, const char* config, + bool quiet = false, + cmGeneratorTarget *target = 0, + cmGeneratorExpressionDAGChecker *dagChecker = 0) const; /** Get set of targets found during evaluations. */ std::set<cmTarget*> const& GetTargets() const { return this->Targets; } + + ~cmCompiledGeneratorExpression(); + private: - cmMakefile* Makefile; - const char* Config; + cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, + const std::vector<cmGeneratorExpressionEvaluator*> &evaluators, + const char *input, bool needsParsing); + + friend class cmGeneratorExpression; + + cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &); + void operator=(const cmCompiledGeneratorExpression &); + cmListFileBacktrace const& Backtrace; - bool Quiet; - std::vector<char> Data; - std::stack<size_t> Barriers; - cmsys::RegularExpression TargetInfo; - std::set<cmTarget*> Targets; - bool Evaluate(); - bool Evaluate(const char* expr, std::string& result); - bool EvaluateTargetInfo(std::string& result); + const std::vector<cmGeneratorExpressionEvaluator*> Evaluators; + const char* const Input; + const bool NeedsParsing; + + mutable std::set<cmTarget*> Targets; + mutable std::string Output; }; + +#endif diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx new file mode 100644 index 0000000..bfb0ddf --- /dev/null +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -0,0 +1,106 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionDAGChecker.h" + +#include "cmMakefile.h" + +//---------------------------------------------------------------------------- +cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( + const cmListFileBacktrace &backtrace, + const std::string &target, + const std::string &property, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *parent) + : Parent(parent), Target(target), Property(property), + Content(content), Backtrace(backtrace) +{ + this->IsDAG = this->isDAG(); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorExpressionDAGChecker::check() const +{ + return this->IsDAG; +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionDAGChecker::reportError( + cmGeneratorExpressionContext *context, + const std::string &expr) +{ + if (this->IsDAG) + { + return; + } + + context->HadError = true; + if (context->Quiet) + { + return; + } + + const cmGeneratorExpressionDAGChecker *parent = this->Parent; + + if (parent && !parent->Parent) + { + cmOStringStream e; + e << "Error evaluating generator expression:\n" + << " " << expr << "\n" + << "Self reference on target \"" + << context->Target->GetName() << "\".\n"; + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), + parent->Backtrace); + return; + } + + { + cmOStringStream e; + e << "Error evaluating generator expression:\n" + << " " << expr << "\n" + << "Dependency loop found."; + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), + context->Backtrace); + } + + int loopStep = 1; + while (parent) + { + cmOStringStream e; + e << "Loop step " << loopStep << "\n" + << " " + << (parent->Content ? parent->Content->GetOriginalExpression() : expr) + << "\n"; + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), + parent->Backtrace); + parent = parent->Parent; + ++loopStep; + } +} + +//---------------------------------------------------------------------------- +bool cmGeneratorExpressionDAGChecker::isDAG() const +{ + const cmGeneratorExpressionDAGChecker *parent = this->Parent; + while (parent) + { + if (this->Target == parent->Target && this->Property == parent->Property) + { + return false; + } + parent = parent->Parent; + } + return true; +} diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h new file mode 100644 index 0000000..ffc84f8 --- /dev/null +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -0,0 +1,44 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionDAGChecker_h +#define cmGeneratorExpressionDAGChecker_h + +#include "cmStandardIncludes.h" + +#include "cmGeneratorExpressionEvaluator.h" + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionDAGChecker +{ + cmGeneratorExpressionDAGChecker(const cmListFileBacktrace &backtrace, + const std::string &target, + const std::string &property, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *parent); + + bool check() const; + + void reportError(cmGeneratorExpressionContext *context, + const std::string &expr); +private: + bool isDAG() const; + +private: + const cmGeneratorExpressionDAGChecker * const Parent; + const std::string Target; + const std::string Property; + const GeneratorExpressionContent * const Content; + const cmListFileBacktrace Backtrace; + bool IsDAG; +}; + +#endif diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx new file mode 100644 index 0000000..2e123a4 --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -0,0 +1,769 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmMakefile.h" + +#include "cmGeneratorExpressionEvaluator.h" +#include "cmGeneratorExpressionParser.h" +#include "cmGeneratorExpressionDAGChecker.h" +#include "cmGeneratorExpression.h" + +#include <cmsys/String.h> + +//---------------------------------------------------------------------------- +#if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510 +static +#endif +void reportError(cmGeneratorExpressionContext *context, + const std::string &expr, const std::string &result) +{ + context->HadError = true; + if (context->Quiet) + { + return; + } + + cmOStringStream e; + e << "Error evaluating generator expression:\n" + << " " << expr << "\n" + << result; + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), + context->Backtrace); +} + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionNode +{ + virtual ~cmGeneratorExpressionNode() {} + + virtual bool GeneratesContent() const { return true; } + + virtual bool AcceptsSingleArbitraryContentParameter() const + { return false; } + + virtual int NumExpectedParameters() const { return 1; } + + virtual std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker + ) const = 0; +}; + +//---------------------------------------------------------------------------- +static const struct ZeroNode : public cmGeneratorExpressionNode +{ + ZeroNode() {} + + virtual bool GeneratesContent() const { return false; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + // Unreachable + return std::string(); + } +} zeroNode; + +//---------------------------------------------------------------------------- +static const struct OneNode : public cmGeneratorExpressionNode +{ + OneNode() {} + + virtual bool AcceptsSingleArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + // Unreachable + return std::string(); + } +} oneNode; + +//---------------------------------------------------------------------------- +#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \ +static const struct OP ## Node : public cmGeneratorExpressionNode \ +{ \ + OP ## Node () {} \ +/* We let -1 carry the meaning 'at least one' */ \ + virtual int NumExpectedParameters() const { return -1; } \ + \ + std::string Evaluate(const std::vector<std::string> ¶meters, \ + cmGeneratorExpressionContext *context, \ + const GeneratorExpressionContent *content, \ + cmGeneratorExpressionDAGChecker *) const \ + { \ + std::vector<std::string>::const_iterator it = parameters.begin(); \ + const std::vector<std::string>::const_iterator end = parameters.end(); \ + for ( ; it != end; ++it) \ + { \ + if (*it == #FAILURE_VALUE) \ + { \ + return #FAILURE_VALUE; \ + } \ + else if (*it != #SUCCESS_VALUE) \ + { \ + reportError(context, content->GetOriginalExpression(), \ + "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \ + return std::string(); \ + } \ + } \ + return #SUCCESS_VALUE; \ + } \ +} OPNAME; + +BOOLEAN_OP_NODE(andNode, AND, 1, 0) +BOOLEAN_OP_NODE(orNode, OR, 0, 1) + +#undef BOOLEAN_OP_NODE + +//---------------------------------------------------------------------------- +static const struct NotNode : public cmGeneratorExpressionNode +{ + NotNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + if (*parameters.begin() != "0" && *parameters.begin() != "1") + { + reportError(context, content->GetOriginalExpression(), + "$<NOT> parameter must resolve to exactly one '0' or '1' value."); + return std::string(); + } + return *parameters.begin() == "0" ? "1" : "0"; + } +} notNode; + +//---------------------------------------------------------------------------- +static const struct BoolNode : public cmGeneratorExpressionNode +{ + BoolNode() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0"; + } +} boolNode; + +//---------------------------------------------------------------------------- +static const struct StrEqualNode : public cmGeneratorExpressionNode +{ + StrEqualNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return *parameters.begin() == parameters[1] ? "1" : "0"; + } +} strEqualNode; + +//---------------------------------------------------------------------------- +static const struct Angle_RNode : public cmGeneratorExpressionNode +{ + Angle_RNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return ">"; + } +} angle_rNode; + +//---------------------------------------------------------------------------- +static const struct CommaNode : public cmGeneratorExpressionNode +{ + CommaNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return ","; + } +} commaNode; + +//---------------------------------------------------------------------------- +static const struct ConfigurationNode : public cmGeneratorExpressionNode +{ + ConfigurationNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return context->Config ? context->Config : ""; + } +} configurationNode; + +//---------------------------------------------------------------------------- +static const struct ConfigurationTestNode : public cmGeneratorExpressionNode +{ + ConfigurationTestNode() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + cmsys::RegularExpression configValidator; + configValidator.compile("^[A-Za-z0-9_]*$"); + if (!configValidator.find(parameters.begin()->c_str())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + if (!context->Config) + { + return parameters.front().empty() ? "1" : "0"; + } + + return cmsysString_strcasecmp(parameters.begin()->c_str(), + context->Config) == 0 ? "1" : "0"; + } +} configurationTestNode; + +//---------------------------------------------------------------------------- +static const struct TargetPropertyNode : public cmGeneratorExpressionNode +{ + TargetPropertyNode() {} + + // This node handles errors on parameter count itself. + virtual int NumExpectedParameters() const { return -1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagCheckerParent + ) const + { + if (parameters.size() != 1 && parameters.size() != 2) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:...> expression requires one or two parameters"); + return std::string(); + } + cmsys::RegularExpression targetNameValidator; + // The ':' is supported to allow use with IMPORTED targets. At least + // Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter. + targetNameValidator.compile("^[A-Za-z0-9_.:-]+$"); + cmsys::RegularExpression propertyNameValidator; + propertyNameValidator.compile("^[A-Za-z0-9_]+$"); + + cmGeneratorTarget* target = context->Target; + std::string propertyName = *parameters.begin(); + if (parameters.size() == 2) + { + if (parameters.begin()->empty() && parameters[1].empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " + "target name and property name."); + return std::string(); + } + if (parameters.begin()->empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " + "target name."); + return std::string(); + } + + std::string targetName = parameters.front(); + propertyName = parameters[1]; + if (!targetNameValidator.find(targetName.c_str())) + { + if (!propertyNameValidator.find(propertyName.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Target name and property name not supported."); + return std::string(); + } + ::reportError(context, content->GetOriginalExpression(), + "Target name not supported."); + return std::string(); + } + target = context->Makefile->FindGeneratorTargetToUse( + targetName.c_str()); + + if (!target) + { + cmOStringStream e; + e << "Target \"" + << targetName + << "\" not found."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + } + + if (propertyName.empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:...> expression requires a non-empty property " + "name."); + return std::string(); + } + + if (!propertyNameValidator.find(propertyName.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Property name not supported."); + return std::string(); + } + + cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, + target->GetName(), + propertyName, + content, + dagCheckerParent); + + if (!dagChecker.check()) + { + dagChecker.reportError(context, content->GetOriginalExpression()); + return std::string(); + } + + const char *prop = target->GetProperty(propertyName.c_str()); + return prop ? prop : ""; + } +} targetPropertyNode; + +//---------------------------------------------------------------------------- +template<bool linker, bool soname> +struct TargetFilesystemArtifactResultCreator +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content); +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<false, true> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + // The target soname file (.so.1). + if(target->IsDLLPlatform()) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_SONAME_FILE is not allowed " + "for DLL target platforms."); + return std::string(); + } + if(target->GetType() != cmTarget::SHARED_LIBRARY) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_SONAME_FILE is allowed only for " + "SHARED libraries."); + return std::string(); + } + std::string result = target->GetDirectory(context->Config); + result += "/"; + result += target->GetSOName(context->Config); + return result; + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<true, false> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + // The file used to link to the target (.so, .lib, .a). + if(!target->IsLinkable()) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_LINKER_FILE is allowed only for libraries and " + "executables with ENABLE_EXPORTS."); + return std::string(); + } + return target->GetFullPath(context->Config, + target->HasImportLibrary()); + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<false, false> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *) + { + return target->GetFullPath(context->Config, false, true); + } +}; + + +//---------------------------------------------------------------------------- +template<bool dirQual, bool nameQual> +struct TargetFilesystemArtifactResultGetter +{ + static std::string Get(const std::string &result); +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter<false, true> +{ + static std::string Get(const std::string &result) + { return cmSystemTools::GetFilenameName(result); } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter<true, false> +{ + static std::string Get(const std::string &result) + { return cmSystemTools::GetFilenamePath(result); } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter<false, false> +{ + static std::string Get(const std::string &result) + { return result; } +}; + +//---------------------------------------------------------------------------- +template<bool linker, bool soname, bool dirQual, bool nameQual> +struct TargetFilesystemArtifact : public cmGeneratorExpressionNode +{ + TargetFilesystemArtifact() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + // Lookup the referenced target. + std::string name = *parameters.begin(); + + cmsys::RegularExpression targetValidator; + // The ':' is supported to allow use with IMPORTED targets. + targetValidator.compile("^[A-Za-z0-9_.:-]+$"); + if (!targetValidator.find(name.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + cmTarget* target = context->Makefile->FindTargetToUse(name.c_str()); + if(!target) + { + ::reportError(context, content->GetOriginalExpression(), + "No target \"" + name + "\""); + return std::string(); + } + if(target->GetType() >= cmTarget::UTILITY && + target->GetType() != cmTarget::UNKNOWN_LIBRARY) + { + ::reportError(context, content->GetOriginalExpression(), + "Target \"" + name + "\" is not an executable or library."); + return std::string(); + } + context->Targets.insert(target); + + std::string result = + TargetFilesystemArtifactResultCreator<linker, soname>::Create( + target, + context, + content); + if (context->HadError) + { + return std::string(); + } + return + TargetFilesystemArtifactResultGetter<dirQual, nameQual>::Get(result); + } +}; + +//---------------------------------------------------------------------------- +static const +TargetFilesystemArtifact<false, false, false, false> targetFileNode; +static const +TargetFilesystemArtifact<true, false, false, false> targetLinkerFileNode; +static const +TargetFilesystemArtifact<false, true, false, false> targetSoNameFileNode; +static const +TargetFilesystemArtifact<false, false, false, true> targetFileNameNode; +static const +TargetFilesystemArtifact<true, false, false, true> targetLinkerFileNameNode; +static const +TargetFilesystemArtifact<false, true, false, true> targetSoNameFileNameNode; +static const +TargetFilesystemArtifact<false, false, true, false> targetFileDirNode; +static const +TargetFilesystemArtifact<true, false, true, false> targetLinkerFileDirNode; +static const +TargetFilesystemArtifact<false, true, true, false> targetSoNameFileDirNode; + +//---------------------------------------------------------------------------- +static const +cmGeneratorExpressionNode* GetNode(const std::string &identifier) +{ + if (identifier == "0") + return &zeroNode; + if (identifier == "1") + return &oneNode; + if (identifier == "AND") + return &andNode; + if (identifier == "OR") + return &orNode; + if (identifier == "NOT") + return ¬Node; + else if (identifier == "CONFIGURATION") + return &configurationNode; + else if (identifier == "CONFIG") + return &configurationTestNode; + else if (identifier == "TARGET_FILE") + return &targetFileNode; + else if (identifier == "TARGET_LINKER_FILE") + return &targetLinkerFileNode; + else if (identifier == "TARGET_SONAME_FILE") + return &targetSoNameFileNode; + else if (identifier == "TARGET_FILE_NAME") + return &targetFileNameNode; + else if (identifier == "TARGET_LINKER_FILE_NAME") + return &targetLinkerFileNameNode; + else if (identifier == "TARGET_SONAME_FILE_NAME") + return &targetSoNameFileNameNode; + else if (identifier == "TARGET_FILE_DIR") + return &targetFileDirNode; + else if (identifier == "TARGET_LINKER_FILE_DIR") + return &targetLinkerFileDirNode; + else if (identifier == "TARGET_SONAME_FILE_DIR") + return &targetSoNameFileDirNode; + else if (identifier == "STREQUAL") + return &strEqualNode; + else if (identifier == "BOOL") + return &boolNode; + else if (identifier == "ANGLE-R") + return &angle_rNode; + else if (identifier == "COMMA") + return &commaNode; + else if (identifier == "TARGET_PROPERTY") + return &targetPropertyNode; + return 0; + +} + +//---------------------------------------------------------------------------- +GeneratorExpressionContent::GeneratorExpressionContent( + const char *startContent, + unsigned int length) + : StartContent(startContent), ContentLength(length) +{ + +} + +//---------------------------------------------------------------------------- +std::string GeneratorExpressionContent::GetOriginalExpression() const +{ + return std::string(this->StartContent, this->ContentLength); +} + +//---------------------------------------------------------------------------- +std::string GeneratorExpressionContent::Evaluate( + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker) const +{ + std::string identifier; + { + std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it + = this->IdentifierChildren.begin(); + const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end + = this->IdentifierChildren.end(); + for ( ; it != end; ++it) + { + identifier += (*it)->Evaluate(context, dagChecker); + if (context->HadError) + { + return std::string(); + } + } + } + + const cmGeneratorExpressionNode *node = GetNode(identifier); + + if (!node) + { + reportError(context, this->GetOriginalExpression(), + "Expression did not evaluate to a known generator expression"); + return std::string(); + } + + if (!node->GeneratesContent()) + { + return std::string(); + } + + if (node->AcceptsSingleArbitraryContentParameter()) + { + std::string result; + std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator + pit = this->ParamChildren.begin(); + const + std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator + pend = this->ParamChildren.end(); + for ( ; pit != pend; ++pit) + { + if (!result.empty()) + { + result += ","; + } + + std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it + = pit->begin(); + const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end + = pit->end(); + for ( ; it != end; ++it) + { + result += (*it)->Evaluate(context, dagChecker); + if (context->HadError) + { + return std::string(); + } + } + } + return result; + } + + std::vector<std::string> parameters; + { + std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator + pit = this->ParamChildren.begin(); + const + std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator + pend = this->ParamChildren.end(); + for ( ; pit != pend; ++pit) + { + std::string parameter; + std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it = + pit->begin(); + const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end = + pit->end(); + for ( ; it != end; ++it) + { + parameter += (*it)->Evaluate(context, dagChecker); + if (context->HadError) + { + return std::string(); + } + } + parameters.push_back(parameter); + } + } + + int numExpected = node->NumExpectedParameters(); + if ((numExpected != -1 && (unsigned int)numExpected != parameters.size())) + { + if (numExpected == 0) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires no parameters."); + } + else if (numExpected == 1) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires " + "exactly one parameter."); + } + else + { + cmOStringStream e; + e << "$<" + identifier + "> expression requires " + << numExpected + << " comma separated parameters, but got " + << parameters.size() << " instead."; + reportError(context, this->GetOriginalExpression(), e.str()); + } + return std::string(); + } + + if (numExpected == -1 && parameters.empty()) + { + reportError(context, this->GetOriginalExpression(), "$<" + identifier + + "> expression requires at least one parameter."); + return std::string(); + } + + return node->Evaluate(parameters, context, this, dagChecker); +} + +//---------------------------------------------------------------------------- +static void deleteAll(const std::vector<cmGeneratorExpressionEvaluator*> &c) +{ + std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it + = c.begin(); + const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end + = c.end(); + for ( ; it != end; ++it) + { + delete *it; + } +} + +//---------------------------------------------------------------------------- +GeneratorExpressionContent::~GeneratorExpressionContent() +{ + deleteAll(this->IdentifierChildren); + + typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector; + typedef std::vector<cmGeneratorExpressionToken> TokenVector; + std::vector<EvaluatorVector>::const_iterator pit = + this->ParamChildren.begin(); + const std::vector<EvaluatorVector>::const_iterator pend = + this->ParamChildren.end(); + for ( ; pit != pend; ++pit) + { + deleteAll(*pit); + } +} diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h new file mode 100644 index 0000000..04a2acd --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -0,0 +1,127 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionEvaluator_h +#define cmGeneratorExpressionEvaluator_h + +#include <vector> +#include <string> + +#include "cmListFileCache.h" + +class cmTarget; +class cmGeneratorTarget; + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionContext +{ + cmListFileBacktrace Backtrace; + std::set<cmTarget*> Targets; + cmMakefile *Makefile; + const char *Config; + cmGeneratorTarget *Target; + bool Quiet; + bool HadError; +}; + +struct cmGeneratorExpressionDAGChecker; + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionEvaluator +{ + cmGeneratorExpressionEvaluator() {} + virtual ~cmGeneratorExpressionEvaluator() {} + + enum Type + { + Text, + Generator + }; + + virtual Type GetType() const = 0; + + virtual std::string Evaluate(cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *) const = 0; + +private: + cmGeneratorExpressionEvaluator(const cmGeneratorExpressionEvaluator &); + void operator=(const cmGeneratorExpressionEvaluator &); +}; + +struct TextContent : public cmGeneratorExpressionEvaluator +{ + TextContent(const char *start, unsigned int length) + : Content(start), Length(length) + { + + } + + std::string Evaluate(cmGeneratorExpressionContext *, + cmGeneratorExpressionDAGChecker *) const + { + return std::string(this->Content, this->Length); + } + + Type GetType() const + { + return cmGeneratorExpressionEvaluator::Text; + } + + void Extend(unsigned int length) + { + this->Length += length; + } + + unsigned int GetLength() + { + return this->Length; + } + +private: + const char *Content; + unsigned int Length; +}; + +//---------------------------------------------------------------------------- +struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator +{ + GeneratorExpressionContent(const char *startContent, unsigned int length); + void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier) + { + this->IdentifierChildren = identifier; + } + + void SetParameters( + std::vector<std::vector<cmGeneratorExpressionEvaluator*> > parameters) + { + this->ParamChildren = parameters; + } + + Type GetType() const + { + return cmGeneratorExpressionEvaluator::Generator; + } + + std::string Evaluate(cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *) const; + + std::string GetOriginalExpression() const; + + ~GeneratorExpressionContent(); + +private: + std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren; + std::vector<std::vector<cmGeneratorExpressionEvaluator*> > ParamChildren; + const char *StartContent; + unsigned int ContentLength; +}; + +#endif diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx new file mode 100644 index 0000000..cd71ec0 --- /dev/null +++ b/Source/cmGeneratorExpressionLexer.cxx @@ -0,0 +1,85 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmGeneratorExpressionLexer.h" + + +//---------------------------------------------------------------------------- +cmGeneratorExpressionLexer::cmGeneratorExpressionLexer() + : SawBeginExpression(false), SawGeneratorExpression(false) +{ + +} + +//---------------------------------------------------------------------------- +static void InsertText(const char *upto, const char *c, + std::vector<cmGeneratorExpressionToken> &result) +{ + if (upto != c) + { + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::Text, upto, c - upto)); + } +} + +//---------------------------------------------------------------------------- +std::vector<cmGeneratorExpressionToken> +cmGeneratorExpressionLexer::Tokenize(const char *input) +{ + std::vector<cmGeneratorExpressionToken> result; + if (!input) + return result; + + const char *c = input; + const char *upto = c; + + for ( ; *c; ++c) + { + if(c[0] == '$' && c[1] == '<') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::BeginExpression, upto, 2)); + upto = c + 2; + ++c; + SawBeginExpression = true; + } + else if(c[0] == '>') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::EndExpression, upto, 1)); + upto = c + 1; + SawGeneratorExpression = SawBeginExpression; + } + else if(c[0] == ':') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::ColonSeparator, upto, 1)); + upto = c + 1; + } + else if(c[0] == ',') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::CommaSeparator, upto, 1)); + upto = c + 1; + } + } + InsertText(upto, c, result); + + return result; +} diff --git a/Source/cmGeneratorExpressionLexer.h b/Source/cmGeneratorExpressionLexer.h new file mode 100644 index 0000000..5f16712 --- /dev/null +++ b/Source/cmGeneratorExpressionLexer.h @@ -0,0 +1,58 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionLexer_h +#define cmGeneratorExpressionLexer_h + +#include "cmStandardIncludes.h" + +#include <vector> + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionToken +{ + cmGeneratorExpressionToken(unsigned type, const char *c, unsigned l) + : TokenType(type), Content(c), Length(l) + { + } + enum { + Text, + BeginExpression, + EndExpression, + ColonSeparator, + CommaSeparator + }; + unsigned TokenType; + const char *Content; + unsigned Length; +}; + +/** \class cmGeneratorExpressionLexer + * + */ +class cmGeneratorExpressionLexer +{ +public: + cmGeneratorExpressionLexer(); + + std::vector<cmGeneratorExpressionToken> Tokenize(const char *input); + + bool GetSawGeneratorExpression() const + { + return this->SawGeneratorExpression; + } + +private: + bool SawBeginExpression; + bool SawGeneratorExpression; +}; + +#endif diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx new file mode 100644 index 0000000..7a8fc51 --- /dev/null +++ b/Source/cmGeneratorExpressionParser.cxx @@ -0,0 +1,276 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionParser.h" + +#include "cmGeneratorExpressionEvaluator.h" + +#include "assert.h" + +//---------------------------------------------------------------------------- +cmGeneratorExpressionParser::cmGeneratorExpressionParser( + const std::vector<cmGeneratorExpressionToken> &tokens) + : Tokens(tokens), NestingLevel(0) +{ +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::Parse( + std::vector<cmGeneratorExpressionEvaluator*> &result) +{ + it = this->Tokens.begin(); + + while (this->it != this->Tokens.end()) + { + this->ParseContent(result); + } +} + +//---------------------------------------------------------------------------- +static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result, + std::vector<cmGeneratorExpressionToken>::const_iterator it) +{ + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1)); + textContent->Extend(it->Length); + } + else + { + TextContent *textContent = new TextContent(it->Content, it->Length); + result.push_back(textContent); + } +} + +//---------------------------------------------------------------------------- +static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result, + const std::vector<cmGeneratorExpressionEvaluator*> &contents) +{ + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text + && (*contents.begin())->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1)); + textContent->Extend( + static_cast<TextContent*>(*contents.begin())->GetLength()); + delete *contents.begin(); + result.insert(result.end(), contents.begin() + 1, contents.end()); + } else { + result.insert(result.end(), contents.begin(), contents.end()); + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::ParseGeneratorExpression( + std::vector<cmGeneratorExpressionEvaluator*> &result) +{ + assert(this->it != this->Tokens.end()); + unsigned int nestedLevel = this->NestingLevel; + ++this->NestingLevel; + + std::vector<cmGeneratorExpressionToken>::const_iterator startToken + = this->it - 1; + + std::vector<cmGeneratorExpressionEvaluator*> identifier; + while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression + && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) + { + this->ParseContent(identifier); + if (this->it == this->Tokens.end()) + { + break; + } + } + if (identifier.empty()) + { + // ERROR + } + + if (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + { + GeneratorExpressionContent *content = new GeneratorExpressionContent( + startToken->Content, this->it->Content + - startToken->Content + + this->it->Length); + assert(this->it != this->Tokens.end()); + ++this->it; + --this->NestingLevel; + content->SetIdentifier(identifier); + result.push_back(content); + return; + } + + std::vector<std::vector<cmGeneratorExpressionEvaluator*> > parameters; + std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator> + commaTokens; + std::vector<cmGeneratorExpressionToken>::const_iterator colonToken; + if (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + { + colonToken = this->it; + parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); + ++this->it; + + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + { + commaTokens.push_back(this->it); + parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); + ++this->it; + } + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + { + extendText(*(parameters.end() - 1), this->it); + assert(this->it != this->Tokens.end()); + ++this->it; + } + while (this->it != this->Tokens.end() && + this->it->TokenType != cmGeneratorExpressionToken::EndExpression) + { + this->ParseContent(*(parameters.end() - 1)); + if (this->it == this->Tokens.end()) + { + break; + } + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + { + commaTokens.push_back(this->it); + parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); + ++this->it; + } + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + { + extendText(*(parameters.end() - 1), this->it); + assert(this->it != this->Tokens.end()); + ++this->it; + } + } + if(this->it != this->Tokens.end() + && this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + { + --this->NestingLevel; + assert(this->it != this->Tokens.end()); + ++this->it; + } + } + + if (nestedLevel != this->NestingLevel) + { + // There was a '$<' in the text, but no corresponding '>'. Rebuild to + // treat the '$<' as having been plain text, along with the + // corresponding : and , tokens that might have been found. + extendText(result, startToken); + extendResult(result, identifier); + if (!parameters.empty()) + { + extendText(result, colonToken); + + typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector; + typedef std::vector<cmGeneratorExpressionToken> TokenVector; + std::vector<EvaluatorVector>::const_iterator pit = parameters.begin(); + const std::vector<EvaluatorVector>::const_iterator pend = + parameters.end(); + std::vector<TokenVector::const_iterator>::const_iterator commaIt = + commaTokens.begin(); + assert(parameters.size() > commaTokens.size()); + for ( ; pit != pend; ++pit, ++commaIt) + { + extendResult(result, *pit); + if (commaIt != commaTokens.end()) + { + extendText(result, *commaIt); + } + else + { + break; + } + } + } + return; + } + + int contentLength = ((this->it - 1)->Content + - startToken->Content) + + (this->it - 1)->Length; + GeneratorExpressionContent *content = new GeneratorExpressionContent( + startToken->Content, contentLength); + content->SetIdentifier(identifier); + content->SetParameters(parameters); + result.push_back(content); +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::ParseContent( + std::vector<cmGeneratorExpressionEvaluator*> &result) +{ + assert(this->it != this->Tokens.end()); + switch(this->it->TokenType) + { + case cmGeneratorExpressionToken::Text: + { + if (this->NestingLevel == 0) + { + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + // A comma in 'plain text' could have split text that should + // otherwise be continuous. Extend the last text content instead of + // creating a new one. + TextContent *textContent = + static_cast<TextContent*>(*(result.end() - 1)); + textContent->Extend(this->it->Length); + assert(this->it != this->Tokens.end()); + ++this->it; + return; + } + } + cmGeneratorExpressionEvaluator* n = new TextContent(this->it->Content, + this->it->Length); + result.push_back(n); + assert(this->it != this->Tokens.end()); + ++this->it; + return ; + } + case cmGeneratorExpressionToken::BeginExpression: + assert(this->it != this->Tokens.end()); + ++this->it; + this->ParseGeneratorExpression(result); + return; + case cmGeneratorExpressionToken::EndExpression: + case cmGeneratorExpressionToken::ColonSeparator: + case cmGeneratorExpressionToken::CommaSeparator: + if (this->NestingLevel == 0) + { + extendText(result, this->it); + } + else + { + assert(!"Got unexpected syntax token."); + } + assert(this->it != this->Tokens.end()); + ++this->it; + return; + } + assert(!"Unhandled token in generator expression."); +} diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h new file mode 100644 index 0000000..28f1441 --- /dev/null +++ b/Source/cmGeneratorExpressionParser.h @@ -0,0 +1,45 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionParser_h +#define cmGeneratorExpressionParser_h + +#include "cmGeneratorExpressionLexer.h" + +#include <set> +#include <vector> + +#include "cmListFileCache.h" + +class cmMakefile; +class cmTarget; +struct cmGeneratorExpressionEvaluator; + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionParser +{ + cmGeneratorExpressionParser( + const std::vector<cmGeneratorExpressionToken> &tokens); + + void Parse(std::vector<cmGeneratorExpressionEvaluator*> &result); + +private: + void ParseContent(std::vector<cmGeneratorExpressionEvaluator*> &); + void ParseGeneratorExpression( + std::vector<cmGeneratorExpressionEvaluator*> &); + +private: + std::vector<cmGeneratorExpressionToken>::const_iterator it; + const std::vector<cmGeneratorExpressionToken> Tokens; + unsigned int NestingLevel; +}; + +#endif diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6e2e23d..19b55c6 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -14,8 +14,13 @@ #include "cmTarget.h" #include "cmMakefile.h" #include "cmLocalGenerator.h" +#include "cmComputeLinkInformation.h" #include "cmGlobalGenerator.h" #include "cmSourceFile.h" +#include "cmGeneratorExpression.h" +#include "cmGeneratorExpressionDAGChecker.h" + +#include <assert.h> //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) @@ -27,6 +32,45 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) this->LookupObjectLibraries(); } +cmGeneratorTarget::~cmGeneratorTarget() +{ + for(std::map<cmStdString, cmComputeLinkInformation*>::iterator i + = LinkInformation.begin(); i != LinkInformation.end(); ++i) + { + delete i->second; + } +} + +//---------------------------------------------------------------------------- +int cmGeneratorTarget::GetType() const +{ + return this->Target->GetType(); +} + +//---------------------------------------------------------------------------- +const char *cmGeneratorTarget::GetName() const +{ + return this->Target->GetName(); +} + +//---------------------------------------------------------------------------- +const char *cmGeneratorTarget::GetProperty(const char *prop) +{ + return this->Target->GetProperty(prop); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::GetPropertyAsBool(const char *prop) +{ + return this->Target->GetPropertyAsBool(prop); +} + +//---------------------------------------------------------------------------- +std::vector<cmSourceFile*> const& cmGeneratorTarget::GetSourceFiles() +{ + return this->Target->GetSourceFiles(); +} + //---------------------------------------------------------------------------- void cmGeneratorTarget::ClassifySources() { @@ -175,3 +219,143 @@ void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) } } } + +//---------------------------------------------------------------------------- +cmComputeLinkInformation* +cmGeneratorTarget::GetLinkInformation(const char* config) +{ + // Lookup any existing information for this configuration. + std::map<cmStdString, cmComputeLinkInformation*>::iterator + i = this->LinkInformation.find(config?config:""); + if(i == this->LinkInformation.end()) + { + // Compute information for this configuration. + cmComputeLinkInformation* info = + new cmComputeLinkInformation(this->Target, config); + if(!info || !info->Compute()) + { + delete info; + info = 0; + } + + // Store the information for this configuration. + std::map<cmStdString, cmComputeLinkInformation*>::value_type + entry(config?config:"", info); + i = this->LinkInformation.insert(entry).first; + } + return i->second; +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetAppleArchs(const char* config, + std::vector<std::string>& archVec) +{ + const char* archs = 0; + if(config && *config) + { + std::string defVarName = "OSX_ARCHITECTURES_"; + defVarName += cmSystemTools::UpperCase(config); + archs = this->Target->GetProperty(defVarName.c_str()); + } + if(!archs) + { + archs = this->Target->GetProperty("OSX_ARCHITECTURES"); + } + if(archs) + { + cmSystemTools::ExpandListArgument(std::string(archs), archVec); + } +} + +//---------------------------------------------------------------------------- +const char* cmGeneratorTarget::GetCreateRuleVariable() +{ + switch(this->GetType()) + { + case cmTarget::STATIC_LIBRARY: + return "_CREATE_STATIC_LIBRARY"; + case cmTarget::SHARED_LIBRARY: + return "_CREATE_SHARED_LIBRARY"; + case cmTarget::MODULE_LIBRARY: + return "_CREATE_SHARED_MODULE"; + case cmTarget::EXECUTABLE: + return "_LINK_EXECUTABLE"; + default: + break; + } + return ""; +} + +//---------------------------------------------------------------------------- +std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories( + const char *config) +{ + std::vector<std::string> includes; + const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES"); + if(!prop) + { + return includes; + } + + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "INCLUDE_DIRECTORIES", 0, 0); + + cmSystemTools::ExpandListArgument(ge.Parse(prop) + .Evaluate(this->Makefile, + config, + false, + this, + &dagChecker), + includes); + + std::set<std::string> uniqueIncludes; + std::vector<std::string> orderedAndUniqueIncludes; + for(std::vector<std::string>::const_iterator + li = includes.begin(); li != includes.end(); ++li) + { + std::string inc = *li; + if (!cmSystemTools::IsOff(inc.c_str())) + { + cmSystemTools::ConvertToUnixSlashes(inc); + } + if(uniqueIncludes.insert(inc).second) + { + orderedAndUniqueIncludes.push_back(inc); + } + } + + return orderedAndUniqueIncludes; +} + +//---------------------------------------------------------------------------- +std::string cmGeneratorTarget::GetCompileDefinitions(const char *config) +{ + std::string defPropName = "COMPILE_DEFINITIONS"; + if (config) + { + defPropName += "_" + cmSystemTools::UpperCase(config); + } + + const char *prop = this->Target->GetProperty(defPropName.c_str()); + + if (!prop) + { + return ""; + } + + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + defPropName, 0, 0); + return ge.Parse(prop).Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); +} diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 5c7578d..a29a9f9 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -14,6 +14,7 @@ #include "cmStandardIncludes.h" +class cmComputeLinkInformation; class cmCustomCommand; class cmGlobalGenerator; class cmLocalGenerator; @@ -25,6 +26,13 @@ class cmGeneratorTarget { public: cmGeneratorTarget(cmTarget*); + ~cmGeneratorTarget(); + + int GetType() const; + const char *GetName() const; + const char *GetProperty(const char *prop); + bool GetPropertyAsBool(const char *prop); + std::vector<cmSourceFile*> const& GetSourceFiles(); cmTarget* Target; cmMakefile* Makefile; @@ -52,6 +60,22 @@ public: void UseObjectLibraries(std::vector<std::string>& objs); + std::map<cmStdString, cmComputeLinkInformation*> LinkInformation; + + cmComputeLinkInformation* GetLinkInformation(const char* config); + + void GetAppleArchs(const char* config, + std::vector<std::string>& archVec); + + ///! Return the rule variable used to create this type of target, + // need to add CMAKE_(LANG) for full name. + const char* GetCreateRuleVariable(); + + /** Get the include directories for this target. */ + std::vector<std::string> GetIncludeDirectories(const char *config); + + std::string GetCompileDefinitions(const char *config = 0); + private: void ClassifySources(); void LookupObjectLibraries(); @@ -60,4 +84,6 @@ private: void operator=(cmGeneratorTarget const&); }; +typedef std::map<cmTarget*, cmGeneratorTarget*> cmGeneratorTargetsType; + #endif diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h index 0a5917c..b77eaae 100644 --- a/Source/cmGetCMakePropertyCommand.h +++ b/Source/cmGetCMakePropertyCommand.h @@ -17,7 +17,7 @@ class cmGetCMakePropertyCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetCMakePropertyCommand; } @@ -46,7 +46,7 @@ public: { return "Get a property of the CMake instance."; } - + /** * Longer documentation. */ @@ -63,7 +63,7 @@ public: "\n" "See also the more general get_property() command."; } - + cmTypeMacro(cmGetCMakePropertyCommand, cmCommand); }; diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 5714b50..9e76e1b 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -22,12 +22,12 @@ bool cmGetDirectoryPropertyCommand this->SetError("called with incorrect number of arguments"); return false; } - + std::vector<std::string>::const_iterator i = args.begin(); std::string variable = *i; ++i; std::string output = ""; - + // get the directory argument if there is one cmMakefile *dir = this->Makefile; if (*i == "DIRECTORY") @@ -52,7 +52,7 @@ bool cmGetDirectoryPropertyCommand sd = cmSystemTools::CollapseFullPath(sd.c_str()); // lookup the makefile from the directory name - cmLocalGenerator *lg = + cmLocalGenerator *lg = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> FindLocalGenerator(sd.c_str()); if (!lg) @@ -69,7 +69,7 @@ bool cmGetDirectoryPropertyCommand // OK, now we have the directory to process, we just get the requested // information out of it - + if ( *i == "DEFINITION" ) { ++i; diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h index 901b90c..d0d5820 100644 --- a/Source/cmGetDirectoryPropertyCommand.h +++ b/Source/cmGetDirectoryPropertyCommand.h @@ -17,7 +17,7 @@ class cmGetDirectoryPropertyCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetDirectoryPropertyCommand; } @@ -46,7 +46,7 @@ public: { return "Get a property of DIRECTORY scope."; } - + /** * Longer documentation. */ @@ -69,7 +69,7 @@ public: "\n" "See also the more general get_property() command."; } - + cmTypeMacro(cmGetDirectoryPropertyCommand, cmCommand); }; diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 1a31d54..fd1ad60 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -32,7 +32,7 @@ bool cmGetFilenameComponentCommand return true; } } - + std::string result; std::string filename = args[1]; if(filename.find("[HKEY") != filename.npos) @@ -79,7 +79,7 @@ bool cmGetFilenameComponentCommand } } } - cmSystemTools::SplitProgramFromArgs(filename.c_str(), + cmSystemTools::SplitProgramFromArgs(filename.c_str(), result, programArgs); } else if (args[2] == "EXT") @@ -104,7 +104,7 @@ bool cmGetFilenameComponentCommand result = cmSystemTools::GetRealPath(result.c_str()); } } - else + else { std::string err = "unknown component " + args[2]; this->SetError(err.c_str()); @@ -125,7 +125,7 @@ bool cmGetFilenameComponentCommand args[2] == "PATH" ? cmCacheManager::FILEPATH : cmCacheManager::STRING); } - else + else { if(programArgs.size() && storeArgs.size()) { diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h index 0c8e57a..c461016 100644 --- a/Source/cmGetFilenameComponentCommand.h +++ b/Source/cmGetFilenameComponentCommand.h @@ -18,7 +18,7 @@ * \brief Get a specific component of a filename. * * cmGetFilenameComponentCommand is a utility command used to get the path, - * name, extension or name without extension of a full filename. + * name, extension or name without extension of a full filename. */ class cmGetFilenameComponentCommand : public cmCommand { @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetFilenameComponentCommand; } @@ -55,7 +55,7 @@ public: { return "Get a specific component of a full filename."; } - + /** * More documentation. */ @@ -82,7 +82,7 @@ public: "from the program name and stored in <ARG_VAR>. This is used to " "separate a program name from its arguments in a command line string."; } - + cmTypeMacro(cmGetFilenameComponentCommand, cmCommand); }; diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h index dca2627..3c597fd 100644 --- a/Source/cmGetPropertyCommand.h +++ b/Source/cmGetPropertyCommand.h @@ -19,7 +19,7 @@ class cmGetPropertyCommand : public cmCommand public: cmGetPropertyCommand(); - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetPropertyCommand; } @@ -48,7 +48,7 @@ public: { return "Get a property."; } - + /** * Longer documentation. */ @@ -92,7 +92,7 @@ public: "If documentation is requested for a property that has not been " "defined NOTFOUND is returned."; } - + cmTypeMacro(cmGetPropertyCommand, cmCommand); private: enum OutType { OutValue, OutDefined, OutBriefDoc, OutFullDoc, OutSet }; diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h index 6d52503..2ba8103 100644 --- a/Source/cmGetSourceFilePropertyCommand.h +++ b/Source/cmGetSourceFilePropertyCommand.h @@ -17,7 +17,7 @@ class cmGetSourceFilePropertyCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetSourceFilePropertyCommand; } @@ -41,7 +41,7 @@ public: { return "Get a property for a source file."; } - + /** * Longer documentation. */ @@ -57,7 +57,7 @@ public: "\n" "See also the more general get_property() command."; } - + cmTypeMacro(cmGetSourceFilePropertyCommand, cmCommand); }; diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h index b60abea..f5e1aa7 100644 --- a/Source/cmGetTargetPropertyCommand.h +++ b/Source/cmGetTargetPropertyCommand.h @@ -17,7 +17,7 @@ class cmGetTargetPropertyCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetTargetPropertyCommand; } @@ -41,7 +41,7 @@ public: { return "Get a property from a target."; } - + /** * Longer documentation. */ @@ -59,7 +59,7 @@ public: "\n" "See also the more general get_property() command."; } - + cmTypeMacro(cmGetTargetPropertyCommand, cmCommand); }; diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h index af6bafa..01f54d9 100644 --- a/Source/cmGetTestPropertyCommand.h +++ b/Source/cmGetTestPropertyCommand.h @@ -17,7 +17,7 @@ class cmGetTestPropertyCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmGetTestPropertyCommand; } diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index b87b7e1..8c6787a 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -25,14 +25,14 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator() void cmGlobalBorlandMakefileGenerator -::EnableLanguage(std::vector<std::string>const& l, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& l, + cmMakefile *mf, bool optional) { std::string outdir = this->CMakeInstance->GetStartOutputDirectory(); mf->AddDefinition("BORLAND", "1"); mf->AddDefinition("CMAKE_GENERATOR_CC", "bcc32"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "bcc32"); + mf->AddDefinition("CMAKE_GENERATOR_CXX", "bcc32"); this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 0d38689..c0cb8a6 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -23,9 +23,9 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalNMakeMakefileGenerator { public: cmGlobalBorlandMakefileGenerator(); - static cmGlobalGenerator* New() + static cmGlobalGenerator* New() { return new cmGlobalBorlandMakefileGenerator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalBorlandMakefileGenerator::GetActualName();} @@ -33,13 +33,13 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index f883041..b9de4d8 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -21,10 +21,11 @@ #include "cmQtAutomoc.h" #include "cmSourceFile.h" #include "cmVersion.h" -#include "cmExportInstallFileGenerator.h" +#include "cmTargetExport.h" #include "cmComputeTargetDepends.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" +#include "cmGeneratorExpression.h" #include <cmsys/Directory.hxx> @@ -76,12 +77,12 @@ cmGlobalGenerator::~cmGlobalGenerator() } this->ClearGeneratorTargets(); - this->ClearExportSets(); } void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, cmMakefile *mf, - bool optional) { + bool optional) +{ std::string langComp = "CMAKE_"; langComp += lang; langComp += "_COMPILER"; @@ -315,9 +316,11 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { rootBin = this->ConfiguredFilesPath; } + rootBin += "/"; + rootBin += cmVersion::GetCMakeVersion(); // set the dir for parent files so they can be used by modules - mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str()); + mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR",rootBin.c_str()); // find and make sure CMAKE_MAKE_PROGRAM is defined this->FindMakeProgram(mf); @@ -376,21 +379,16 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, std::string loadedLang = "CMAKE_"; loadedLang += lang; loadedLang += "_COMPILER_LOADED"; - // If the existing build tree was already configured with this - // version of CMake then try to load the configured file first - // to avoid duplicate compiler tests. - unsigned int cacheMajor = mf->GetCacheMajorVersion(); - unsigned int cacheMinor = mf->GetCacheMinorVersion(); - unsigned int selfMajor = cmVersion::GetMajorVersion(); - unsigned int selfMinor = cmVersion::GetMinorVersion(); - if((this->CMakeInstance->GetIsInTryCompile() || - (selfMajor == cacheMajor && selfMinor == cacheMinor)) - && !mf->GetDefinition(loadedLang.c_str())) + if(!mf->GetDefinition(loadedLang.c_str())) { fpath = rootBin; fpath += "/CMake"; fpath += lang; fpath += "Compiler.cmake"; + + // If the existing build tree was already configured with this + // version of CMake then try to load the configured file first + // to avoid duplicate compiler tests. if(cmSystemTools::FileExists(fpath.c_str())) { if(!mf->ReadListFile(0,fpath.c_str())) @@ -586,6 +584,16 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } } // end if in try compile } // end need test language + // Store the shared library flags so that we can satisfy CMP0018 + std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_"; + sharedLibFlagsVar += lang; + sharedLibFlagsVar += "_FLAGS"; + const char* sharedLibFlags = + mf->GetSafeDefinition(sharedLibFlagsVar.c_str()); + if (sharedLibFlags) + { + this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags; + } } // end for each language // Now load files that can override any settings on the platform or for @@ -810,7 +818,7 @@ void cmGlobalGenerator::Configure() { this->FirstTimeProgress = 0.0f; this->ClearGeneratorTargets(); - this->ClearExportSets(); + this->ExportSets.clear(); // Delete any existing cmLocalGenerators unsigned int i; for (i = 0; i < this->LocalGenerators.size(); ++i) @@ -886,7 +894,7 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() << "The \"" << this->GetName() << "\" generator does not support " << "duplicate custom targets. " << "Consider using a Makefiles generator or fix the project to not " - << "use duplicat target names."; + << "use duplicate target names."; cmSystemTools::Error(e.str().c_str()); return false; } @@ -1068,23 +1076,56 @@ void cmGlobalGenerator::CreateGeneratorTargets() // Construct per-target generator information. for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { - cmTargets& targets = - this->LocalGenerators[i]->GetMakefile()->GetTargets(); + cmGeneratorTargetsType generatorTargets; + + cmMakefile *mf = this->LocalGenerators[i]->GetMakefile(); + const char *noconfig_compile_definitions = + mf->GetProperty("COMPILE_DEFINITIONS"); + + std::vector<std::string> configs; + mf->GetConfigurations(configs); + + cmTargets& targets = mf->GetTargets(); for(cmTargets::iterator ti = targets.begin(); ti != targets.end(); ++ti) { cmTarget* t = &ti->second; + + { + t->AppendProperty("COMPILE_DEFINITIONS", noconfig_compile_definitions); + for(std::vector<std::string>::const_iterator ci = configs.begin(); + ci != configs.end(); ++ci) + { + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += cmSystemTools::UpperCase(*ci); + t->AppendProperty(defPropName.c_str(), + mf->GetProperty(defPropName.c_str())); + } + } + cmGeneratorTarget* gt = new cmGeneratorTarget(t); this->GeneratorTargets[t] = gt; this->ComputeTargetObjects(gt); + generatorTargets[t] = gt; } + + for(std::vector<cmTarget*>::const_iterator + j = mf->GetOwnedImportedTargets().begin(); + j != mf->GetOwnedImportedTargets().end(); ++j) + { + cmGeneratorTarget* gt = new cmGeneratorTarget(*j); + this->GeneratorTargets[*j] = gt; + generatorTargets[*j] = gt; + } + + mf->SetGeneratorTargets(generatorTargets); } } //---------------------------------------------------------------------------- void cmGlobalGenerator::ClearGeneratorTargets() { - for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); + for(cmGeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); i != this->GeneratorTargets.end(); ++i) { delete i->second; @@ -1095,7 +1136,7 @@ void cmGlobalGenerator::ClearGeneratorTargets() //---------------------------------------------------------------------------- cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const { - GeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t); + cmGeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t); if(ti == this->GeneratorTargets.end()) { this->CMakeInstance->IssueMessage( @@ -1122,7 +1163,7 @@ void cmGlobalGenerator::CheckLocalGenerators() { manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager(); this->LocalGenerators[i]->ConfigureFinalPass(); - cmTargets & targets = + cmTargets &targets = this->LocalGenerators[i]->GetMakefile()->GetTargets(); for (cmTargets::iterator l = targets.begin(); l != targets.end(); l++) @@ -1151,7 +1192,16 @@ void cmGlobalGenerator::CheckLocalGenerators() } } std::vector<std::string> incs; - this->LocalGenerators[i]->GetIncludeDirectories(incs, &l->second); + const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES"); + if (!incDirProp) + { + continue; + } + + std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp, + cmGeneratorExpression::StripAllGeneratorExpressions); + + cmSystemTools::ExpandListArgument(incDirs.c_str(), incs); for( std::vector<std::string>::const_iterator incDir = incs.begin(); incDir != incs.end(); ++incDir) @@ -1459,52 +1509,6 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } } -void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, - cmTarget* target, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runTime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* headers) -{ - if ((exportSetName) && (*exportSetName) && (target)) - { - cmTargetExport* te = new cmTargetExport(target, archive, runTime, library, - framework, bundle, headers); - this->ExportSets[exportSetName].push_back(te); - } -} - -//---------------------------------------------------------------------------- -void cmGlobalGenerator::ClearExportSets() -{ - for(std::map<cmStdString, std::vector<cmTargetExport*> >::iterator - setIt = this->ExportSets.begin(); - setIt != this->ExportSets.end(); ++setIt) - { - for(unsigned int i = 0; i < setIt->second.size(); ++i) - { - delete setIt->second[i]; - } - } - this->ExportSets.clear(); -} - -const std::vector<cmTargetExport*>* cmGlobalGenerator::GetExportSet( - const char* name) const -{ - std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator - exportSetIt = this->ExportSets.find(name); - if (exportSetIt != this->ExportSets.end()) - { - return &exportSetIt->second; - } - - return 0; -} - - void cmGlobalGenerator::EnableInstallTarget() { this->InstallTargetEnabled = true; @@ -2107,6 +2111,17 @@ cmGlobalGenerator::GenerateRuleFile(std::string const& output) const } //---------------------------------------------------------------------------- +std::string cmGlobalGenerator::GetSharedLibFlagsForLanguage( + std::string const& l) +{ + if(this->LanguageToOriginalSharedLibFlags.count(l) > 0) + { + return this->LanguageToOriginalSharedLibFlags[l]; + } + return ""; +} + +//---------------------------------------------------------------------------- void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*, const char*, std::string&) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 8535edc..0aab2d6 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -18,13 +18,15 @@ #include "cmTarget.h" // For cmTargets #include "cmTargetDepend.h" // For cmTargetDependSet #include "cmSystemTools.h" // for cmSystemTools::OutputOption +#include "cmExportSetMap.h" // For cmExportSetMap +#include "cmGeneratorTarget.h" + class cmake; class cmGeneratorTarget; class cmMakefile; class cmLocalGenerator; class cmExternalMakefileProjectGenerator; class cmTarget; -class cmTargetExport; class cmInstallTargetGenerator; class cmInstallFilesGenerator; @@ -127,8 +129,8 @@ public: void SetCMakeInstance(cmake *cm); ///! Get the CMake instance - cmake *GetCMakeInstance() { return this->CMakeInstance; }; - const cmake *GetCMakeInstance() const { return this->CMakeInstance; }; + cmake *GetCMakeInstance() { return this->CMakeInstance; } + const cmake *GetCMakeInstance() const { return this->CMakeInstance; } void SetConfiguredFilesPath(cmGlobalGenerator* gen); const std::vector<cmLocalGenerator *>& GetLocalGenerators() const { @@ -151,18 +153,9 @@ public: void AddInstallComponent(const char* component); const std::set<cmStdString>* GetInstallComponents() const - { return &InstallComponents; } - - ///! Add one installed target to the sets of the exports - void AddTargetToExports(const char* exportSet, cmTarget* target, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runTime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* publicHeaders); - ///! Get the export target set with the given name - const std::vector<cmTargetExport*>* GetExportSet(const char* name) const; + { return &this->InstallComponents; } + + cmExportSetMap& GetExportSets() {return this->ExportSets;} /** Add a file to the manifest of generated targets for a configuration. */ void AddToManifest(const char* config, std::string const& f); @@ -222,7 +215,7 @@ public: /** Get the manifest of all targets that will be built for each configuration. This is valid during generation only. */ cmTargetManifest const& GetTargetManifest() const - { return this->TargetManifest; } + { return this->TargetManifest; } /** Get the content of a directory. Directory listings are loaded from disk at most once and cached. During the generation step @@ -277,6 +270,8 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ virtual bool IsMultiConfig() { return false; } + std::string GetSharedLibFlagsForLanguage(std::string const& lang); + /** Generate an <output>.rule file path for a given command output. */ virtual std::string GenerateRuleFile(std::string const& output) const; @@ -326,15 +321,13 @@ protected: cmLocalGenerator* CurrentLocalGenerator; // map from project name to vector of local generators in that project std::map<cmStdString, std::vector<cmLocalGenerator*> > ProjectMap; - std::map<cmLocalGenerator*, std::set<cmTarget *> > - LocalGeneratorToTargetMap; + std::map<cmLocalGenerator*, std::set<cmTarget *> > LocalGeneratorToTargetMap; // Set of named installation components requested by the project. std::set<cmStdString> InstallComponents; bool InstallTargetEnabled; // Sets of named target exports - std::map<cmStdString, std::vector<cmTargetExport*> > ExportSets; - void ClearExportSets(); + cmExportSetMap ExportSets; // Manifest of all targets that will be built for each configuration. // This is computed just before local generators generate. @@ -359,6 +352,7 @@ private: std::map<cmStdString, cmStdString> LanguageToOutputExtension; std::map<cmStdString, cmStdString> ExtensionToLanguage; std::map<cmStdString, int> LanguageToLinkerPreference; + std::map<cmStdString, cmStdString> LanguageToOriginalSharedLibFlags; // Record hashes for rules and outputs. struct RuleHash { char Data[32]; }; @@ -380,8 +374,7 @@ private: TargetDependMap TargetDependencies; // Per-target generator information. - typedef std::map<cmTarget*, cmGeneratorTarget*> GeneratorTargetsType; - GeneratorTargetsType GeneratorTargets; + cmGeneratorTargetsType GeneratorTargets; void CreateGeneratorTargets(); void ClearGeneratorTargets(); virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 411e28b..ef42bd4 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -22,14 +22,14 @@ cmGlobalJOMMakefileGenerator::cmGlobalJOMMakefileGenerator() } void cmGlobalJOMMakefileGenerator -::EnableLanguage(std::vector<std::string>const& l, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& l, + cmMakefile *mf, bool optional) { - // pick a default + // pick a default mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); - if(!(cmSystemTools::GetEnv("INCLUDE") && + if(!(cmSystemTools::GetEnv("INCLUDE") && cmSystemTools::GetEnv("LIB")) ) { @@ -40,7 +40,7 @@ void cmGlobalJOMMakefileGenerator mf->IssueMessage(cmake::WARNING, message); } - + this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index 08be4b4..691ebdb 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -34,13 +34,13 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx index 56b9e9c..a81c26c 100644 --- a/Source/cmGlobalKdevelopGenerator.cxx +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -44,15 +44,18 @@ cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator() :cmExternalMakefileProjectGenerator() { this->SupportedGlobalGenerators.push_back("Unix Makefiles"); +#ifdef CMAKE_USE_NINJA + this->SupportedGlobalGenerators.push_back("Ninja"); +#endif } void cmGlobalKdevelopGenerator::Generate() { - // for each sub project in the project create + // for each sub project in the project create // a kdevelop project - for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator - it = this->GlobalGenerator->GetProjectMap().begin(); - it!= this->GlobalGenerator->GetProjectMap().end(); + for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator + it = this->GlobalGenerator->GetProjectMap().begin(); + it!= this->GlobalGenerator->GetProjectMap().end(); ++it) { cmMakefile* mf = it->second[0]->GetMakefile(); @@ -91,7 +94,7 @@ void cmGlobalKdevelopGenerator::Generate() break; } } - + // now create a project file this->CreateProjectFile(outputDir, projectDir, projectName, executable, cmakeFilePattern, fileToOpen); @@ -100,7 +103,7 @@ void cmGlobalKdevelopGenerator::Generate() bool cmGlobalKdevelopGenerator ::CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs, - const std::string& outputDir, + const std::string& outputDir, const std::string& projectDirIn, const std::string& projectname, std::string& cmakeFilePattern, @@ -112,24 +115,24 @@ bool cmGlobalKdevelopGenerator std::set<cmStdString> files; std::string tmp; - for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin(); + for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin(); it!=lgs.end(); it++) { cmMakefile* makefile=(*it)->GetMakefile(); const std::vector<std::string>& listFiles=makefile->GetListFiles(); - for (std::vector<std::string>::const_iterator lt=listFiles.begin(); + for (std::vector<std::string>::const_iterator lt=listFiles.begin(); lt!=listFiles.end(); lt++) { tmp=*lt; cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); // make sure the file is part of this source tree - if ((tmp[0]!='/') && - (strstr(tmp.c_str(), + if ((tmp[0]!='/') && + (strstr(tmp.c_str(), cmake::GetCMakeFilesDirectoryPostSlash())==0)) { files.insert(tmp); tmp=cmSystemTools::GetFilenameName(tmp); - //add all files which dont match the default + //add all files which dont match the default // */CMakeLists.txt;*cmake; to the file pattern if ((tmp!="CMakeLists.txt") && (strstr(tmp.c_str(), ".cmake")==0)) @@ -138,7 +141,7 @@ bool cmGlobalKdevelopGenerator } } } - + //get all sources cmTargets& targets=makefile->GetTargets(); for (cmTargets::iterator ti = targets.begin(); @@ -155,8 +158,8 @@ bool cmGlobalKdevelopGenerator cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); - if ((tmp[0]!='/') && - (strstr(tmp.c_str(), + if ((tmp[0]!='/') && + (strstr(tmp.c_str(), cmake::GetCMakeFilesDirectoryPostSlash())==0) && (cmSystemTools::GetFilenameExtension(tmp)!=".moc")) { @@ -184,8 +187,8 @@ bool cmGlobalKdevelopGenerator { tmp=*lt; cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); - if ((tmp[0]!='/') && - (strstr(tmp.c_str(), + if ((tmp[0]!='/') && + (strstr(tmp.c_str(), cmake::GetCMakeFilesDirectoryPostSlash())==0)) { files.insert(tmp.c_str()); @@ -220,9 +223,9 @@ bool cmGlobalKdevelopGenerator { return false; } - + fileToOpen=""; - for (std::set<cmStdString>::const_iterator it=files.begin(); + for (std::set<cmStdString>::const_iterator it=files.begin(); it!=files.end(); it++) { // get the full path to the file @@ -254,7 +257,7 @@ existing one, otherwise create a new one */ void cmGlobalKdevelopGenerator ::CreateProjectFile(const std::string& outputDir, const std::string& projectDir, - const std::string& projectname, + const std::string& projectname, const std::string& executable, const std::string& cmakeFilePattern, const std::string& fileToOpen) @@ -268,13 +271,13 @@ void cmGlobalKdevelopGenerator if (cmSystemTools::FileExists(filename.c_str())) { - this->MergeProjectFiles(outputDir, projectDir, filename, - executable, cmakeFilePattern, + this->MergeProjectFiles(outputDir, projectDir, filename, + executable, cmakeFilePattern, fileToOpen, sessionFilename); } else { - // add all subdirectories which are cmake build directories to the + // add all subdirectories which are cmake build directories to the // kdevelop blacklist so they are not monitored for added or removed files // since this is handled by adding files to the cmake files cmsys::Directory d; @@ -292,7 +295,7 @@ void cmGlobalKdevelopGenerator if (cmSystemTools::FileIsDirectory(tmp.c_str())) { tmp += "/CMakeCache.txt"; - if ((nextFile == "CMakeFiles") + if ((nextFile == "CMakeFiles") || (cmSystemTools::FileExists(tmp.c_str()))) { this->Blacklist.push_back(nextFile); @@ -302,17 +305,17 @@ void cmGlobalKdevelopGenerator } } this->CreateNewProjectFile(outputDir, projectDir, filename, - executable, cmakeFilePattern, + executable, cmakeFilePattern, fileToOpen, sessionFilename); } } void cmGlobalKdevelopGenerator -::MergeProjectFiles(const std::string& outputDir, - const std::string& projectDir, - const std::string& filename, - const std::string& executable, +::MergeProjectFiles(const std::string& outputDir, + const std::string& projectDir, + const std::string& filename, + const std::string& executable, const std::string& cmakeFilePattern, const std::string& fileToOpen, const std::string& sessionFilename) @@ -320,8 +323,8 @@ void cmGlobalKdevelopGenerator std::ifstream oldProjectFile(filename.c_str()); if (!oldProjectFile) { - this->CreateNewProjectFile(outputDir, projectDir, filename, - executable, cmakeFilePattern, + this->CreateNewProjectFile(outputDir, projectDir, filename, + executable, cmakeFilePattern, fileToOpen, sessionFilename); return; } @@ -343,7 +346,7 @@ void cmGlobalKdevelopGenerator return; } - for (std::vector<std::string>::const_iterator it=lines.begin(); + for (std::vector<std::string>::const_iterator it=lines.begin(); it!=lines.end(); it++) { const char* line=(*it).c_str(); @@ -365,7 +368,7 @@ void cmGlobalKdevelopGenerator if (strstr(line, "<general>")) { fout<< " <projectmanagement>KDevCustomProject</projectmanagement>\n"; - fout<< " <projectdirectory>" <<projectDir.c_str() + fout<< " <projectdirectory>" <<projectDir.c_str() << "</projectdirectory>\n"; //this one is important fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one @@ -404,7 +407,7 @@ void cmGlobalKdevelopGenerator bool hasSvn = cmSystemTools::FileExists((projectDir + "/.svn").c_str()); bool hasCvs = cmSystemTools::FileExists((projectDir + "/CVS").c_str()); - bool enableCxx = (this->GlobalGenerator->GetLanguageEnabled("C") + bool enableCxx = (this->GlobalGenerator->GetLanguageEnabled("C") || this->GlobalGenerator->GetLanguageEnabled("CXX")); bool enableFortran = this->GlobalGenerator->GetLanguageEnabled("Fortran"); std::string primaryLanguage = "C++"; @@ -422,7 +425,7 @@ void cmGlobalKdevelopGenerator " <projectmanagement>KDevCustomProject</projectmanagement>\n" " <primarylanguage>" << primaryLanguage << "</primarylanguage>\n" " <ignoreparts/>\n" - " <projectdirectory>" << projectDir.c_str() << + " <projectdirectory>" << projectDir.c_str() << "</projectdirectory>\n"; //this one is important fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one @@ -469,7 +472,7 @@ void cmGlobalKdevelopGenerator " <numberofjobs>1</numberofjobs>\n" " <dontact>false</dontact>\n" " <makebin>" << this->GlobalGenerator->GetLocalGenerators()[0]-> - GetMakefile()->GetRequiredDefinition("CMAKE_BUILD_TOOL") + GetMakefile()->GetRequiredDefinition("CMAKE_BUILD_TOOL") << " </makebin>\n" " <selectedenvironment>default</selectedenvironment>\n" " <environments>\n" diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx index 820e7e6..80526aa 100644 --- a/Source/cmGlobalMSYSMakefileGenerator.cxx +++ b/Source/cmGlobalMSYSMakefileGenerator.cxx @@ -22,7 +22,7 @@ cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator() this->UseLinkScript = false; } -std::string +std::string cmGlobalMSYSMakefileGenerator::FindMinGW(std::string const& makeloc) { std::string fstab = makeloc; @@ -45,8 +45,8 @@ cmGlobalMSYSMakefileGenerator::FindMinGW(std::string const& makeloc) } void cmGlobalMSYSMakefileGenerator -::EnableLanguage(std::vector<std::string>const& l, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& l, + cmMakefile *mf, bool optional) { this->FindMakeProgram(mf); diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h index b5294ac..b76a5bf 100644 --- a/Source/cmGlobalMSYSMakefileGenerator.h +++ b/Source/cmGlobalMSYSMakefileGenerator.h @@ -23,7 +23,7 @@ class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: cmGlobalMSYSMakefileGenerator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalMSYSMakefileGenerator; } ///! Get the name for the generator. @@ -33,13 +33,13 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx index a9e7798..d6045c8 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.cxx +++ b/Source/cmGlobalMinGWMakefileGenerator.cxx @@ -22,10 +22,10 @@ cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator() } void cmGlobalMinGWMakefileGenerator -::EnableLanguage(std::vector<std::string>const& l, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& l, + cmMakefile *mf, bool optional) -{ +{ this->FindMakeProgram(mf); std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); std::vector<std::string> locations; diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h index 366146b..9a6a513 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.h +++ b/Source/cmGlobalMinGWMakefileGenerator.h @@ -23,7 +23,7 @@ class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3 { public: cmGlobalMinGWMakefileGenerator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalMinGWMakefileGenerator; } ///! Get the name for the generator. virtual const char* GetName() const { @@ -32,13 +32,13 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index c3c15e7..57a26c8 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -22,14 +22,14 @@ cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator() } void cmGlobalNMakeMakefileGenerator -::EnableLanguage(std::vector<std::string>const& l, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& l, + cmMakefile *mf, bool optional) { - // pick a default + // pick a default mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); - if(!(cmSystemTools::GetEnv("INCLUDE") && + if(!(cmSystemTools::GetEnv("INCLUDE") && cmSystemTools::GetEnv("LIB")) ) { @@ -40,7 +40,7 @@ void cmGlobalNMakeMakefileGenerator mf->IssueMessage(cmake::WARNING, message); } - + this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index 70a8c190..de33b8f 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -32,13 +32,13 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 0e89fab..05f5b4c 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -43,12 +43,13 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os, std::string replace = comment; std::string::size_type lpos = 0; std::string::size_type rpos; + os << "\n#############################################\n"; while((rpos = replace.find('\n', lpos)) != std::string::npos) { os << "# " << replace.substr(lpos, rpos - lpos) << "\n"; lpos = rpos + 1; } - os << "# " << replace.substr(lpos) << "\n"; + os << "# " << replace.substr(lpos) << "\n\n"; } static bool IsIdentChar(char c) @@ -66,7 +67,7 @@ std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string &ident, if (std::find_if(ident.begin(), ident.end(), std::not1(std::ptr_fun(IsIdentChar))) != ident.end()) { static unsigned VarNum = 0; - std::ostringstream names; + cmOStringStream names; names << "ident" << VarNum++; vars << names.str() << " = " << ident << "\n"; return "$" + names.str(); @@ -89,7 +90,10 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) { std::string result = path; #ifdef _WIN32 - cmSystemTools::ReplaceString(result, "/", "\\"); + if(UsingMinGW) + cmSystemTools::ReplaceString(result, "\\", "/"); + else + cmSystemTools::ReplaceString(result, "/", "\\"); #endif return EncodeLiteral(result); } @@ -101,7 +105,9 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, const cmNinjaDeps& orderOnlyDeps, - const cmNinjaVars& variables) + const cmNinjaVars& variables, + const std::string& rspfile, + int cmdLineLimit) { // Make sure there is a rule. if(rule.empty()) @@ -123,56 +129,72 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, cmGlobalNinjaGenerator::WriteComment(os, comment); - std::ostringstream builds; + cmOStringStream arguments; // TODO: Better formatting for when there are multiple input/output files. - // Write outputs files. - builds << "build"; - for(cmNinjaDeps::const_iterator i = outputs.begin(); - i != outputs.end(); - ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); - builds << ":"; - - // Write the rule. - builds << " " << rule; - // Write explicit dependencies. for(cmNinjaDeps::const_iterator i = explicitDeps.begin(); i != explicitDeps.end(); ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); + arguments << " " << EncodeIdent(EncodePath(*i), os); // Write implicit dependencies. if(!implicitDeps.empty()) { - builds << " |"; + arguments << " |"; for(cmNinjaDeps::const_iterator i = implicitDeps.begin(); i != implicitDeps.end(); ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); + arguments << " " << EncodeIdent(EncodePath(*i), os); } // Write order-only dependencies. if(!orderOnlyDeps.empty()) { - builds << " ||"; + arguments << " ||"; for(cmNinjaDeps::const_iterator i = orderOnlyDeps.begin(); i != orderOnlyDeps.end(); ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); + arguments << " " << EncodeIdent(EncodePath(*i), os); } - builds << "\n"; + arguments << "\n"; + + cmOStringStream build; + + // Write outputs files. + build << "build"; + for(cmNinjaDeps::const_iterator i = outputs.begin(); + i != outputs.end(); ++i) + build << " " << EncodeIdent(EncodePath(*i), os); + build << ":"; - os << builds.str(); + // Write the rule. + build << " " << rule; // Write the variables bound to this build statement. + cmOStringStream variable_assignments; for(cmNinjaVars::const_iterator i = variables.begin(); - i != variables.end(); - ++i) - cmGlobalNinjaGenerator::WriteVariable(os, i->first, i->second, "", 1); + i != variables.end(); ++i) + cmGlobalNinjaGenerator::WriteVariable(variable_assignments, + i->first, i->second, "", 1); + + // check if a response file rule should be used + std::string buildstr = build.str(); + std::string assignments = variable_assignments.str(); + const std::string args = arguments.str(); + if (cmdLineLimit > 0 + && args.size() + buildstr.size() + assignments.size() + > (size_t) cmdLineLimit) { + buildstr += "_RSP_FILE"; + variable_assignments.clear(); + cmGlobalNinjaGenerator::WriteVariable(variable_assignments, + "RSP_FILE", rspfile, "", 1); + assignments += variable_assignments.str(); + } + + os << buildstr << args << assignments; } void cmGlobalNinjaGenerator::WritePhonyBuild(std::ostream& os, @@ -200,6 +222,8 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() "$DESC", "Rule for running custom commands.", /*depfile*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", /*restat*/ true); } @@ -211,10 +235,17 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, const cmNinjaDeps& deps, const cmNinjaDeps& orderOnlyDeps) { + std::string cmd = command; +#ifdef _WIN32 + if (cmd.empty()) + // TODO Shouldn't an empty command be handled by ninja? + cmd = "cmd.exe /c"; +#endif + this->AddCustomCommandRule(); cmNinjaVars vars; - vars["COMMAND"] = command; + vars["COMMAND"] = cmd; vars["DESC"] = EncodeLiteral(description); cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, @@ -227,12 +258,56 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, vars); } +void +cmGlobalNinjaGenerator::AddMacOSXContentRule() +{ + cmLocalGenerator *lg = this->LocalGenerators[0]; + cmMakefile* mfRoot = lg->GetMakefile(); + + cmOStringStream cmd; + cmd << lg->ConvertToOutputFormat( + mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL) + << " -E copy $in $out"; + + this->AddRule("COPY_OSX_CONTENT", + cmd.str(), + "Copying OS X Content $out", + "Rule for copying OS X bundle content file." + /*depfile*/ "", + /*rspfile*/ ""); +} + +void +cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, + const std::string& output) +{ + this->AddMacOSXContentRule(); + + cmNinjaDeps outputs; + outputs.push_back(output); + cmNinjaDeps deps; + deps.push_back(input); + cmNinjaVars vars; + + cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, + "", + "COPY_OSX_CONTENT", + outputs, + deps, + cmNinjaDeps(), + cmNinjaDeps(), + cmNinjaVars()); +} + void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& name, const std::string& command, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& rspfile, + const std::string& rspcontent, bool restat, bool generator) { @@ -277,6 +352,19 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, os << "description = " << description << "\n"; } + if(!rspfile.empty()) + { + if (rspcontent.empty()) + { + cmSystemTools::Error("No rspfile_content given!", comment.c_str()); + return; + } + cmGlobalNinjaGenerator::Indent(os, 1); + os << "rspfile = " << rspfile << "\n"; + cmGlobalNinjaGenerator::Indent(os, 1); + os << "rspfile_content = " << rspcontent << "\n"; + } + if(restat) { cmGlobalNinjaGenerator::Indent(os, 1); @@ -288,6 +376,8 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, cmGlobalNinjaGenerator::Indent(os, 1); os << "generator = 1\n"; } + + os << "\n"; } void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os, @@ -350,6 +440,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake"; } + //---------------------------------------------------------------------------- // Virtual public methods. @@ -404,16 +495,19 @@ void cmGlobalNinjaGenerator cmMakefile *mf, bool optional) { - this->cmGlobalGenerator::EnableLanguage(languages, mf, optional); std::string path; for(std::vector<std::string>::const_iterator l = languages.begin(); l != languages.end(); ++l) { + std::vector<std::string> language; + language.push_back(*l); + if(*l == "NONE") { + this->cmGlobalGenerator::EnableLanguage(language, mf, optional); continue; } - if(*l == "Fortran") + else if(*l == "Fortran") { std::string message = "The \""; message += this->GetName(); @@ -422,10 +516,48 @@ void cmGlobalNinjaGenerator message += "\" yet."; cmSystemTools::Error(message.c_str()); } + else if(*l == "RC") + { + // check if mingw is used + if(mf->IsOn("CMAKE_COMPILER_IS_MINGW")) + { + UsingMinGW = true; + if(!mf->GetDefinition("CMAKE_RC_COMPILER")) + { + std::string windres = cmSystemTools::FindProgram("windres"); + if(windres.empty()) + { + std::string compiler_path; + std::string::size_type prefix = std::string::npos; + if (mf->GetDefinition("CMAKE_C_COMPILER")) + { + compiler_path = mf->GetDefinition("CMAKE_C_COMPILER"); + prefix = compiler_path.rfind("gcc"); + } + else if (mf->GetDefinition("CMAKE_CXX_COMPILER")) + { + compiler_path = mf->GetDefinition("CMAKE_CXX_COMPILER"); + prefix = compiler_path.rfind("++"); + prefix--; + } + if (prefix != std::string::npos) + { + windres = compiler_path.substr(0, prefix) + "windres"; + windres = cmSystemTools::FindProgram(windres.c_str()); + } + } + if(!windres.empty()) + mf->AddDefinition("CMAKE_RC_COMPILER", windres.c_str()); + } + } + } + this->cmGlobalGenerator::EnableLanguage(language, mf, optional); this->ResolveLanguageCompiler(*l, mf, optional); } } +bool cmGlobalNinjaGenerator::UsingMinGW = false; + // Implemented by: // cmGlobalUnixMakefileGenerator3 // cmGlobalVisualStudio10Generator @@ -483,12 +615,16 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& rspfile, + const std::string& rspcontent, bool restat, bool generator) { // Do not add the same rule twice. if (this->HasRule(name)) + { return; + } this->Rules.insert(name); cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, @@ -497,8 +633,12 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, description, comment, depfile, + rspfile, + rspcontent, restat, generator); + + this->RuleCmdLength[name] = (int) command.size(); } bool cmGlobalNinjaGenerator::HasRule(const std::string &name) @@ -644,13 +784,22 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand( *this->CompileCommandsStream << "," << std::endl; } + std::string sourceFileName = sourceFile; + if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str())) + { + sourceFileName = cmSystemTools::CollapseFullPath( + sourceFileName.c_str(), + this->GetCMakeInstance()->GetHomeOutputDirectory()); + } + + *this->CompileCommandsStream << "\n{\n" << " \"directory\": \"" << cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n" << " \"command\": \"" << cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n" << " \"file\": \"" - << cmGlobalGenerator::EscapeJSON(sourceFile) << "\"\n" + << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\"\n" << "}"; } @@ -680,6 +829,11 @@ void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target) this->AppendTargetOutputs(target, this->AllDependencies); } +void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input) +{ + this->AllDependencies.push_back(input); +} + void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (std::map<std::string, std::set<std::string> >::iterator @@ -767,7 +921,7 @@ void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias, // Insert the alias into the map. If the alias was already present in the // map and referred to another target, mark it as ambiguous. std::pair<TargetAliasMap::iterator, bool> newAlias = - TargetAliases.insert(make_pair(alias, target)); + TargetAliases.insert(std::make_pair(alias, target)); if (newAlias.second && newAlias.first->second != target) newAlias.first->second = 0; } @@ -825,7 +979,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmLocalGenerator *lg = this->LocalGenerators[0]; cmMakefile* mfRoot = lg->GetMakefile(); - std::ostringstream cmd; + cmOStringStream cmd; cmd << lg->ConvertToOutputFormat( mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), cmLocalGenerator::SHELL) @@ -841,6 +995,8 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) "Re-running CMake...", "Rule for re-running cmake.", /*depfile=*/ "", + /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ true); @@ -870,14 +1026,27 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmNinjaDeps()); } +std::string cmGlobalNinjaGenerator::ninjaCmd() const +{ + cmLocalGenerator* lgen = this->LocalGenerators[0]; + if (lgen) { + return lgen->ConvertToOutputFormat( + lgen->GetMakefile()->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"), + cmLocalGenerator::SHELL); + } + return "ninja"; +} + void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) { WriteRule(*this->RulesFileStream, "CLEAN", - "ninja -t clean", + (ninjaCmd() + " -t clean").c_str(), "Cleaning all built files...", "Rule for cleaning all built files.", /*depfile=*/ "", + /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, @@ -894,10 +1063,12 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) { WriteRule(*this->RulesFileStream, "HELP", - "ninja -t targets", + (ninjaCmd() + " -t targets").c_str(), "All primary targets available:", "Rule for printing all primary targets available.", /*depfile=*/ "", + /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 7b6b9b7..24c3916 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -16,6 +16,8 @@ # include "cmGlobalGenerator.h" # include "cmNinjaTypes.h" +//#define NINJA_GEN_VERBOSE_FILES + class cmLocalGenerator; class cmGeneratedFileStream; class cmGeneratorTarget; @@ -81,7 +83,9 @@ public: const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, const cmNinjaDeps& orderOnlyDeps, - const cmNinjaVars& variables); + const cmNinjaVars& variables, + const std::string& rspfile = std::string(), + int cmdLineLimit = -1); /** * Helper to write a build statement with the special 'phony' rule. @@ -100,6 +104,8 @@ public: const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + void WriteMacOSXContentBuild(const std::string& input, + const std::string& output); /** * Write a rule statement named @a name to @a os with the @a comment, @@ -111,10 +117,12 @@ public: const std::string& name, const std::string& command, const std::string& description, - const std::string& comment = "", - const std::string& depfile = "", - bool restat = false, - bool generator = false); + const std::string& comment, + const std::string& depfile, + const std::string& rspfile, + const std::string& rspcontent, + bool restat, + bool generator); /** * Write a variable named @a name to @a os with value @a value and an @@ -143,6 +151,10 @@ public: const cmNinjaDeps& targets, const std::string& comment = ""); + + static bool IsMinGW() { return UsingMinGW; } + + public: /// Default constructor. cmGlobalNinjaGenerator(); @@ -206,12 +218,12 @@ public: } virtual const char* GetCleanTargetName() const { return "clean"; } -public: - cmGeneratedFileStream* GetBuildFileStream() const - { return this->BuildFileStream; } - cmGeneratedFileStream* GetRulesFileStream() const - { return this->RulesFileStream; } + cmGeneratedFileStream* GetBuildFileStream() const { + return this->BuildFileStream; } + + cmGeneratedFileStream* GetRulesFileStream() const { + return this->RulesFileStream; } void AddCXXCompileCommand(const std::string &commandLine, const std::string &sourceFile); @@ -224,14 +236,62 @@ public: void AddRule(const std::string& name, const std::string& command, const std::string& description, - const std::string& comment = "", + const std::string& comment, const std::string& depfile = "", + const std::string& rspfile = "", + const std::string& rspcontent = "", bool restat = false, bool generator = false); bool HasRule(const std::string& name); void AddCustomCommandRule(); + void AddMacOSXContentRule(); + + bool HasCustomCommandOutput(const std::string &output) { + return this->CustomCommandOutputs.find(output) != + this->CustomCommandOutputs.end(); + } + + /// Called when we have seen the given custom command. Returns true + /// if we has seen it before. + bool SeenCustomCommand(cmCustomCommand const *cc) { + return !this->CustomCommands.insert(cc).second; + } + + /// Called when we have seen the given custom command output. + void SeenCustomCommandOutput(const std::string &output) { + this->CustomCommandOutputs.insert(output); + // We don't need the assumed dependencies anymore, because we have + // an output. + this->AssumedSourceDependencies.erase(output); + } + + void AddAssumedSourceDependencies(const std::string &source, + const cmNinjaDeps &deps) { + std::set<std::string> &ASD = this->AssumedSourceDependencies[source]; + // Because we may see the same source file multiple times (same source + // specified in multiple targets), compute the union of any assumed + // dependencies. + ASD.insert(deps.begin(), deps.end()); + } + + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); + void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); + void AddDependencyToAll(cmTarget* target); + void AddDependencyToAll(const std::string& input); + + const std::vector<cmLocalGenerator*>& GetLocalGenerators() const { + return LocalGenerators; } + + bool IsExcluded(cmLocalGenerator* root, cmTarget& target) { + return cmGlobalGenerator::IsExcluded(root, target); } + + int GetRuleCmdLength(const std::string& name) { + return RuleCmdLength[name]; } + + void AddTargetAlias(const std::string& alias, cmTarget* target); + protected: @@ -239,21 +299,12 @@ protected: /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; } + private: /// @see cmGlobalGenerator::ComputeTargetObjects virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; -private: - // In order to access the AddDependencyToAll() functions and co. - friend class cmLocalNinjaGenerator; - - // In order to access the SeenCustomCommand() function. - friend class cmNinjaTargetGenerator; - friend class cmNinjaNormalTargetGenerator; - friend class cmNinjaUtilityTargetGenerator; - -private: void OpenBuildFileStream(); void CloseBuildFileStream(); @@ -265,14 +316,8 @@ private: /// Write the common disclaimer text at the top of each build file. void WriteDisclaimer(std::ostream& os); - void AddDependencyToAll(cmTarget* target); - void WriteAssumedSourceDependencies(); - void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); - void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); - - void AddTargetAlias(const std::string& alias, cmTarget* target); void WriteTargetAliases(std::ostream& os); void WriteBuiltinTargets(std::ostream& os); @@ -281,35 +326,9 @@ private: void WriteTargetClean(std::ostream& os); void WriteTargetHelp(std::ostream& os); - /// Called when we have seen the given custom command. Returns true - /// if we has seen it before. - bool SeenCustomCommand(cmCustomCommand const *cc) { - return !this->CustomCommands.insert(cc).second; - } - - /// Called when we have seen the given custom command output. - void SeenCustomCommandOutput(const std::string &output) { - this->CustomCommandOutputs.insert(output); - // We don't need the assumed dependencies anymore, because we have - // an output. - this->AssumedSourceDependencies.erase(output); - } - - bool HasCustomCommandOutput(const std::string &output) { - return this->CustomCommandOutputs.find(output) != - this->CustomCommandOutputs.end(); - } + std::string ninjaCmd() const; - void AddAssumedSourceDependencies(const std::string &source, - const cmNinjaDeps &deps) { - std::set<std::string> &ASD = this->AssumedSourceDependencies[source]; - // Because we may see the same source file multiple times (same source - // specified in multiple targets), compute the union of any assumed - // dependencies. - ASD.insert(deps.begin(), deps.end()); - } -private: /// The file containing the build statement. (the relation ship of the /// compilation DAG). cmGeneratedFileStream* BuildFileStream; @@ -325,6 +344,9 @@ private: /// The set of rules added to the generated build system. RulesSetType Rules; + /// Length of rule command, used by rsp file evaluation + std::map<std::string, int> RuleCmdLength; + /// The set of dependencies to add to the "all" target. cmNinjaDeps AllDependencies; @@ -341,6 +363,9 @@ private: TargetAliasMap TargetAliases; static cmLocalGenerator* LocalGenerator; + + static bool UsingMinGW; + }; #endif // ! cmGlobalNinjaGenerator_h diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 947a1c9..480c577 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -29,9 +29,12 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator() //---------------------------------------------------------------------------- void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf) { - mf->AddDefinition("MSVC10", "1"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); + cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf); + if(!this->PlatformToolset.empty()) + { + mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", + this->PlatformToolset.c_str()); + } } //---------------------------------------------------------------------------- @@ -94,7 +97,7 @@ void cmGlobalVisualStudio10Generator //---------------------------------------------------------------------------- void cmGlobalVisualStudio10Generator -::EnableLanguage(std::vector<std::string>const & lang, +::EnableLanguage(std::vector<std::string>const & lang, cmMakefile *mf, bool optional) { cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional); @@ -146,12 +149,12 @@ std::string cmGlobalVisualStudio10Generator::GetUserMacrosRegKeyBase() std::string cmGlobalVisualStudio10Generator ::GenerateBuildCommand(const char* makeProgram, - const char *projectName, + const char *projectName, const char* additionalOptions, const char *targetName, const char* config, bool ignoreErrors, bool fast) { // now build the test - std::string makeCommand + std::string makeCommand = cmSystemTools::ConvertToOutputPath(makeProgram); std::string lowerCaseCommand = makeCommand; cmSystemTools::LowerCase(lowerCaseCommand); @@ -177,7 +180,7 @@ std::string cmGlobalVisualStudio10Generator if(!targetName || strlen(targetName) == 0) { targetName = "ALL_BUILD"; - } + } bool clean = false; if ( targetName && strcmp(targetName, "clean") == 0 ) { @@ -202,6 +205,8 @@ std::string cmGlobalVisualStudio10Generator { makeCommand += "Debug"; } + makeCommand += " /p:VisualStudioVersion="; + makeCommand += this->GetIDEVersion(); if ( additionalOptions ) { makeCommand += " "; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 060cdff..47ce790 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -20,26 +20,26 @@ * * cmGlobalVisualStudio10Generator manages UNIX build process for a tree */ -class cmGlobalVisualStudio10Generator : +class cmGlobalVisualStudio10Generator : public cmGlobalVisualStudio8Generator { public: cmGlobalVisualStudio10Generator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio10Generator; } - - virtual std::string + + virtual std::string GenerateBuildCommand(const char* makeProgram, - const char *projectName, + const char *projectName, const char* additionalOptions, const char *targetName, const char* config, bool ignoreErrors, bool); - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio10Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 10";} virtual void AddPlatformDefinitions(cmMakefile* mf); - + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; @@ -50,9 +50,9 @@ public: /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string>const& languages, + virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); virtual void WriteSLNHeader(std::ostream& fout); diff --git a/Source/cmGlobalVisualStudio10IA64Generator.cxx b/Source/cmGlobalVisualStudio10IA64Generator.cxx index 5f70f6b..25dd88f 100644 --- a/Source/cmGlobalVisualStudio10IA64Generator.cxx +++ b/Source/cmGlobalVisualStudio10IA64Generator.cxx @@ -16,6 +16,7 @@ //---------------------------------------------------------------------------- cmGlobalVisualStudio10IA64Generator::cmGlobalVisualStudio10IA64Generator() { + this->ArchitectureId = "x64"; } //---------------------------------------------------------------------------- @@ -33,8 +34,6 @@ void cmGlobalVisualStudio10IA64Generator { this->cmGlobalVisualStudio10Generator::AddPlatformDefinitions(mf); mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64"); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio10Win64Generator.cxx b/Source/cmGlobalVisualStudio10Win64Generator.cxx index 49dc473..d0a0c49 100644 --- a/Source/cmGlobalVisualStudio10Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio10Win64Generator.cxx @@ -16,6 +16,7 @@ //---------------------------------------------------------------------------- cmGlobalVisualStudio10Win64Generator::cmGlobalVisualStudio10Win64Generator() { + this->ArchitectureId = "x64"; } //---------------------------------------------------------------------------- @@ -33,8 +34,6 @@ void cmGlobalVisualStudio10Win64Generator { this->cmGlobalVisualStudio10Generator::AddPlatformDefinitions(mf); mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64"); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio11ARMGenerator.cxx b/Source/cmGlobalVisualStudio11ARMGenerator.cxx index fef1aba..efd71c6 100644 --- a/Source/cmGlobalVisualStudio11ARMGenerator.cxx +++ b/Source/cmGlobalVisualStudio11ARMGenerator.cxx @@ -14,19 +14,16 @@ #include "cmake.h" //---------------------------------------------------------------------------- -void cmGlobalVisualStudio11ARMGenerator -::GetDocumentation(cmDocumentationEntry& entry) const +cmGlobalVisualStudio11ARMGenerator::cmGlobalVisualStudio11ARMGenerator() { - entry.Name = this->GetName(); - entry.Brief = "Generates Visual Studio 11 ARM project files."; - entry.Full = ""; + this->ArchitectureId = "ARM"; } //---------------------------------------------------------------------------- void cmGlobalVisualStudio11ARMGenerator -::AddPlatformDefinitions(cmMakefile* mf) +::GetDocumentation(cmDocumentationEntry& entry) const { - this->cmGlobalVisualStudio11Generator::AddPlatformDefinitions(mf); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "ARM"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "ARM"); + entry.Name = this->GetName(); + entry.Brief = "Generates Visual Studio 11 ARM project files."; + entry.Full = ""; } diff --git a/Source/cmGlobalVisualStudio11ARMGenerator.h b/Source/cmGlobalVisualStudio11ARMGenerator.h index 77e1429..71dbf2e 100644 --- a/Source/cmGlobalVisualStudio11ARMGenerator.h +++ b/Source/cmGlobalVisualStudio11ARMGenerator.h @@ -18,7 +18,7 @@ class cmGlobalVisualStudio11ARMGenerator : public cmGlobalVisualStudio11Generator { public: - cmGlobalVisualStudio11ARMGenerator() {} + cmGlobalVisualStudio11ARMGenerator(); static cmGlobalGenerator* New() { return new cmGlobalVisualStudio11ARMGenerator; } @@ -31,7 +31,5 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - - virtual void AddPlatformDefinitions(cmMakefile* mf); }; #endif diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index be7fd55..23a1204 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -17,19 +17,14 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator() { this->FindMakeProgramFile = "CMakeVS11FindMake.cmake"; - this->ExpressEdition = false; // TODO: VS 11 Express support + std::string vc11Express; + this->ExpressEdition = cmSystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;" + "ProductDir", vc11Express, cmSystemTools::KeyWOW64_32); this->PlatformToolset = "v110"; } //---------------------------------------------------------------------------- -void cmGlobalVisualStudio11Generator::AddPlatformDefinitions(cmMakefile* mf) -{ - mf->AddDefinition("MSVC11", "1"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); -} - -//---------------------------------------------------------------------------- void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout) { fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h index 7e8f6aa..56337a4 100644 --- a/Source/cmGlobalVisualStudio11Generator.h +++ b/Source/cmGlobalVisualStudio11Generator.h @@ -28,7 +28,6 @@ public: virtual const char* GetName() const { return cmGlobalVisualStudio11Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 11";} - virtual void AddPlatformDefinitions(cmMakefile* mf); virtual void WriteSLNHeader(std::ostream& fout); diff --git a/Source/cmGlobalVisualStudio11Win64Generator.cxx b/Source/cmGlobalVisualStudio11Win64Generator.cxx index 10c9027..94e07bf 100644 --- a/Source/cmGlobalVisualStudio11Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio11Win64Generator.cxx @@ -14,6 +14,12 @@ #include "cmake.h" //---------------------------------------------------------------------------- +cmGlobalVisualStudio11Win64Generator::cmGlobalVisualStudio11Win64Generator() +{ + this->ArchitectureId = "x64"; +} + +//---------------------------------------------------------------------------- void cmGlobalVisualStudio11Win64Generator ::GetDocumentation(cmDocumentationEntry& entry) const { @@ -28,6 +34,4 @@ void cmGlobalVisualStudio11Win64Generator { this->cmGlobalVisualStudio11Generator::AddPlatformDefinitions(mf); mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64"); } diff --git a/Source/cmGlobalVisualStudio11Win64Generator.h b/Source/cmGlobalVisualStudio11Win64Generator.h index 53f1953..9445d15 100644 --- a/Source/cmGlobalVisualStudio11Win64Generator.h +++ b/Source/cmGlobalVisualStudio11Win64Generator.h @@ -18,7 +18,7 @@ class cmGlobalVisualStudio11Win64Generator : public cmGlobalVisualStudio11Generator { public: - cmGlobalVisualStudio11Win64Generator() {} + cmGlobalVisualStudio11Win64Generator(); static cmGlobalGenerator* New() { return new cmGlobalVisualStudio11Win64Generator; } diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index fe44e20..e8ca788 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -36,18 +36,16 @@ cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator() } void cmGlobalVisualStudio6Generator -::EnableLanguage(std::vector<std::string>const& lang, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& lang, + cmMakefile *mf, bool optional) { + cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf); mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); - mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); + mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC60", "1"); this->GenerateConfigurations(mf); this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); } @@ -84,10 +82,10 @@ void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf) std::string cmGlobalVisualStudio6Generator ::GenerateBuildCommand(const char* makeProgram, - const char *projectName, - const char* additionalOptions, + const char *projectName, + const char* additionalOptions, const char *targetName, - const char* config, + const char* config, bool ignoreErrors, bool) { @@ -100,7 +98,7 @@ std::string cmGlobalVisualStudio6Generator "\\6.0\\Setup;VsCommonDir]/MSDev98/Bin"); cmSystemTools::ExpandRegistryValues(mp[0]); std::string originalCommand = makeProgram; - std::string makeCommand = + std::string makeCommand = cmSystemTools::FindProgram(makeProgram, mp); if(makeCommand.size() == 0) { @@ -116,7 +114,7 @@ std::string cmGlobalVisualStudio6Generator // if there are spaces in the makeCommand, assume a full path // and convert it to a path with no spaces in it as the // RunSingleCommand does not like spaces -#if defined(_WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) if(makeCommand.find(' ') != std::string::npos) { cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); @@ -226,7 +224,7 @@ void cmGlobalVisualStudio6Generator } void cmGlobalVisualStudio6Generator -::OutputDSWFile(cmLocalGenerator* root, +::OutputDSWFile(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { if(generators.size() == 0) @@ -250,7 +248,7 @@ void cmGlobalVisualStudio6Generator // output the DSW file void cmGlobalVisualStudio6Generator::OutputDSWFile() -{ +{ std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it) { @@ -259,16 +257,16 @@ void cmGlobalVisualStudio6Generator::OutputDSWFile() } // Write a dsp file into the DSW file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here -void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout, +void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout, const char* dspname, const char* dir, cmTarget& target) { fout << "#########################################################" "######################\n\n"; - fout << "Project: \"" << dspname << "\"=" + fout << "Project: \"" << dspname << "\"=" << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n"; fout << "Package=<5>\n{{{\n}}}\n\n"; fout << "Package=<4>\n"; @@ -304,22 +302,22 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout, // Write a dsp file into the DSW file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here -void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout, +void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout, const char* name, const char* location, const std::set<cmStdString>& dependencies) { fout << "#########################################################" "######################\n\n"; - fout << "Project: \"" << name << "\"=" + fout << "Project: \"" << name << "\"=" << location << " - Package Owner=<4>\n\n"; fout << "Package=<5>\n{{{\n}}}\n\n"; fout << "Package=<4>\n"; fout << "{{{\n"; - + std::set<cmStdString>::const_iterator i, end; // write dependencies. i = dependencies.begin(); @@ -347,7 +345,7 @@ void cmGlobalVisualStudio6Generator::WriteDSWFooter(std::ostream& fout) "##########################\n\n"; } - + // ouput standard header for dsw file void cmGlobalVisualStudio6Generator::WriteDSWHeader(std::ostream& fout) { diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h index da08a12..259aa8d 100644 --- a/Source/cmGlobalVisualStudio6Generator.h +++ b/Source/cmGlobalVisualStudio6Generator.h @@ -25,9 +25,9 @@ class cmGlobalVisualStudio6Generator : public cmGlobalVisualStudioGenerator { public: cmGlobalVisualStudio6Generator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio6Generator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio6Generator::GetActualName();} @@ -35,15 +35,15 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string>const& languages, + virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); /** @@ -52,8 +52,8 @@ public: */ virtual std::string GenerateBuildCommand(const char* makeProgram, const char *projectName, - const char* additionalOptions, - const char *targetName, + const char* additionalOptions, + const char *targetName, const char* config, bool ignoreErrors, bool fast); @@ -61,7 +61,7 @@ public: /** * Generate the all required files for building this project/tree. This * basically creates a series of LocalGenerators for each directory and - * requests that they Generate. + * requests that they Generate. */ virtual void Generate(); @@ -90,9 +90,9 @@ private: void GenerateConfigurations(cmMakefile* mf); void WriteDSWFile(std::ostream& fout); void WriteDSWHeader(std::ostream& fout); - void WriteProject(std::ostream& fout, + void WriteProject(std::ostream& fout, const char* name, const char* path, cmTarget &t); - void WriteExternalProject(std::ostream& fout, + void WriteExternalProject(std::ostream& fout, const char* name, const char* path, const std::set<cmStdString>& dependencies); void WriteDSWFooter(std::ostream& fout); diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index d6b653c..ab2308f 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -34,14 +34,6 @@ cmLocalGenerator *cmGlobalVisualStudio71Generator::CreateLocalGenerator() } //---------------------------------------------------------------------------- -void cmGlobalVisualStudio71Generator::AddPlatformDefinitions(cmMakefile* mf) -{ - this->cmGlobalVisualStudio7Generator::AddPlatformDefinitions(mf); - mf->RemoveDefinition("MSVC70"); - mf->AddDefinition("MSVC71", "1"); -} - -//---------------------------------------------------------------------------- std::string cmGlobalVisualStudio71Generator::GetUserMacrosDirectory() { // Macros not supported on Visual Studio 7.1 and earlier because @@ -99,7 +91,7 @@ void cmGlobalVisualStudio71Generator ::WriteSLNFile(std::ostream& fout, cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) -{ +{ // Write out the header for a SLN file this->WriteSLNHeader(fout); @@ -156,7 +148,7 @@ cmGlobalVisualStudio71Generator //---------------------------------------------------------------------------- // Write a dsp file into the SLN file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, @@ -166,11 +158,11 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, { // check to see if this is a fortran build const char* ext = ".vcproj"; - const char* project = + const char* project = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""; if(this->TargetIsFortranOnly(t)) { - ext = ".vfproj"; + ext = ".vfproj"; project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \""; } const char* targetExt = t.GetProperty("GENERATOR_FILE_NAME_EXT"); @@ -187,7 +179,7 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, fout << "\tProjectSection(ProjectDependencies) = postProject\n"; this->WriteProjectDepends(fout, dspname, dir, t); fout << "\tEndProjectSection\n"; - + fout <<"EndProject\n"; UtilityDependsMap::iterator ui = this->UtilityDepends.find(&t); @@ -208,7 +200,7 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, //---------------------------------------------------------------------------- // Write a dsp file into the SLN file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here void cmGlobalVisualStudio71Generator @@ -238,12 +230,12 @@ cmGlobalVisualStudio71Generator // Write a dsp file into the SLN file, Note, that dependencies from // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator -::WriteExternalProject(std::ostream& fout, +::WriteExternalProject(std::ostream& fout, const char* name, const char* location, const char* typeGuid, const std::set<cmStdString>& depends) -{ +{ fout << "Project(\"{" << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942") << "}\") = \"" @@ -251,7 +243,7 @@ void cmGlobalVisualStudio71Generator << this->ConvertToSolutionPath(location) << "\", \"{" << this->GetGUID(name) << "}\"\n"; - + // write out the dependencies here VS 7.1 includes dependencies with the // project instead of in the global section if(!depends.empty()) @@ -262,18 +254,18 @@ void cmGlobalVisualStudio71Generator { if(it->size() > 0) { - fout << "\t\t{" - << this->GetGUID(it->c_str()) - << "} = {" - << this->GetGUID(it->c_str()) + fout << "\t\t{" + << this->GetGUID(it->c_str()) + << "} = {" + << this->GetGUID(it->c_str()) << "}\n"; } } fout << "\tEndProjectSection\n"; - } + } fout << "EndProject\n"; - + } @@ -289,7 +281,7 @@ void cmGlobalVisualStudio71Generator for(std::vector<std::string>::iterator i = this->Configurations.begin(); i != this->Configurations.end(); ++i) { - fout << "\t\t{" << guid << "}." << *i + fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << *i << "|" << (platformMapping ? platformMapping : "Win32") << std::endl; if(partOfDefaultBuild) diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index 503b708..a8daad6 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -24,9 +24,9 @@ class cmGlobalVisualStudio71Generator : public cmGlobalVisualStudio7Generator { public: cmGlobalVisualStudio71Generator(); - static cmGlobalGenerator* New() + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio71Generator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio71Generator::GetActualName();} @@ -34,7 +34,7 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); @@ -53,14 +53,13 @@ public: protected: virtual const char* GetIDEVersion() { return "7.1"; } - virtual void AddPlatformDefinitions(cmMakefile* mf); - virtual void WriteSLNFile(std::ostream& fout, + virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); virtual void WriteSolutionConfigurations(std::ostream& fout); - virtual void WriteProject(std::ostream& fout, + virtual void WriteProject(std::ostream& fout, const char* name, const char* path, cmTarget &t); - virtual void WriteProjectDepends(std::ostream& fout, + virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); virtual void WriteProjectConfigurations(std::ostream& fout, const char* name, diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 6332d0b..15ef738 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -23,7 +23,7 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator() void cmGlobalVisualStudio7Generator -::EnableLanguage(std::vector<std::string>const & lang, +::EnableLanguage(std::vector<std::string>const & lang, cmMakefile *mf, bool optional) { mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); @@ -32,13 +32,13 @@ void cmGlobalVisualStudio7Generator mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort"); this->AddPlatformDefinitions(mf); - + // Create list of configurations requested by user's cache, if any. this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); this->GenerateConfigurations(mf); - + // if this environment variable is set, then copy it to - // a static cache entry. It will be used by + // a static cache entry. It will be used by // cmLocalGenerator::ConstructScript, to add an extra PATH // to all custom commands. This is because the VS IDE // does not use the environment it is run in, and this allows @@ -48,23 +48,16 @@ void cmGlobalVisualStudio7Generator if(extraPath) { mf->AddCacheDefinition - ("CMAKE_MSVCIDE_RUN_PATH", extraPath, + ("CMAKE_MSVCIDE_RUN_PATH", extraPath, "Saved environment variable CMAKE_MSVCIDE_RUN_PATH", cmCacheManager::STATIC); } } -void cmGlobalVisualStudio7Generator::AddPlatformDefinitions(cmMakefile* mf) -{ - mf->AddDefinition("MSVC70", "1"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); -} - std::string cmGlobalVisualStudio7Generator ::GenerateBuildCommand(const char* makeProgram, - const char *projectName, + const char *projectName, const char* additionalOptions, const char *targetName, const char* config, bool ignoreErrors, bool) { @@ -72,7 +65,7 @@ std::string cmGlobalVisualStudio7Generator (void) ignoreErrors; // now build the test - std::string makeCommand = + std::string makeCommand = cmSystemTools::ConvertToOutputPath(makeProgram); std::string lowerCaseCommand = makeCommand; cmSystemTools::LowerCase(lowerCaseCommand); @@ -80,7 +73,7 @@ std::string cmGlobalVisualStudio7Generator // if there are spaces in the makeCommand, assume a full path // and convert it to a path with no spaces in it as the // RunSingleCommand does not like spaces -#if defined(_WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) if(makeCommand.find(' ') != std::string::npos) { cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand); @@ -143,7 +136,7 @@ cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator() void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf) { // process the configurations - const char* ct + const char* ct = this->CMakeInstance->GetCacheDefinition("CMAKE_CONFIGURATION_TYPES"); if ( ct ) { @@ -152,7 +145,7 @@ void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf) for(std::vector<std::string>::iterator i = argsOut.begin(); i != argsOut.end(); ++i) { - if(std::find(this->Configurations.begin(), + if(std::find(this->Configurations.begin(), this->Configurations.end(), *i) == this->Configurations.end()) { @@ -166,7 +159,7 @@ void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf) this->Configurations.push_back("Debug"); this->Configurations.push_back("Release"); } - + // Reset the entry to have a semi-colon separated list. std::string configs = this->Configurations[0]; for(unsigned int i=1; i < this->Configurations.size(); ++i) @@ -237,7 +230,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile() void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( - std::ostream& fout, + std::ostream& fout, cmLocalGenerator* root, OrderedTargetDependSet const& projectTargets) { @@ -258,7 +251,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( { bool partOfDefaultBuild = this->IsPartOfDefaultBuild( root->GetMakefile()->GetProjectName(), target); - const char *vcprojName = + const char *vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { @@ -275,6 +268,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( cmLocalGenerator* root, OrderedTargetDependSet const& projectTargets) { + VisualStudioFolders.clear(); + for(OrderedTargetDependSet::const_iterator tt = projectTargets.begin(); tt != projectTargets.end(); ++tt) { @@ -369,13 +364,13 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends( projectTargets.begin(); tt != projectTargets.end(); ++tt) { cmTarget* target = *tt; - cmMakefile* mf = target->GetMakefile(); - const char *vcprojName = + cmMakefile* mf = target->GetMakefile(); + const char *vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) - { + { std::string dir = mf->GetStartDirectory(); - this->WriteProjectDepends(fout, vcprojName, + this->WriteProjectDepends(fout, vcprojName, dir.c_str(), *target); } } @@ -409,7 +404,7 @@ void cmGlobalVisualStudio7Generator // Write out the configurations information for the solution fout << "Global\n" << "\tGlobalSection(SolutionConfiguration) = preSolution\n"; - + int c = 0; for(std::vector<std::string>::iterator i = this->Configurations.begin(); i != this->Configurations.end(); ++i) @@ -418,7 +413,7 @@ void cmGlobalVisualStudio7Generator c++; } fout << "\tEndGlobalSection\n"; - // Write out project(target) depends + // Write out project(target) depends fout << "\tGlobalSection(ProjectDependencies) = postSolution\n"; this->WriteTargetDepends(fout, orderedProjectTargets); fout << "\tEndGlobalSection\n"; @@ -506,12 +501,12 @@ cmGlobalVisualStudio7Generator::ConvertToSolutionPath(const char* path) } // Write a dsp file into the SLN file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here -void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout, +void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout, const char* dspname, const char* dir, cmTarget& target) -{ +{ // check to see if this is a fortran build const char* ext = ".vcproj"; const char* project = @@ -544,7 +539,7 @@ void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout, // Write a dsp file into the SLN file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here void cmGlobalVisualStudio7Generator @@ -607,14 +602,14 @@ void cmGlobalVisualStudio7Generator // Write a dsp file into the SLN file, -// Note, that dependencies from executables to +// Note, that dependencies from executables to // the libraries it uses are also done here -void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout, +void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout, const char* name, const char* location, const char* typeGuid, const std::set<cmStdString>&) -{ +{ std::string d = cmSystemTools::ConvertToOutputPath(location); fout << "Project(" << "\"{" @@ -639,7 +634,7 @@ void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout) << "EndGlobal\n"; } - + // ouput standard header for dsw file void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout) { @@ -705,7 +700,7 @@ std::string cmGlobalVisualStudio7Generator::GetGUID(const char* name) { std::string guidStoreName = name; guidStoreName += "_GUID_CMAKE"; - const char* storedGUID = + const char* storedGUID = this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()); if(storedGUID) { @@ -733,8 +728,8 @@ void cmGlobalVisualStudio7Generator::CreateGUID(const char* name) ret = reinterpret_cast<char*>(uidstr); RpcStringFree(&uidstr); ret = cmSystemTools::UpperCase(ret); - this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(), - ret.c_str(), "Stored GUID", + this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(), + ret.c_str(), "Stored GUID", cmCacheManager::INTERNAL); } @@ -775,7 +770,7 @@ bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project, { return false; } - // if it is a utilitiy target then only make it part of the + // if it is a utilitiy target then only make it part of the // default build if another target depends on it int type = target->GetType(); if (type == cmTarget::GLOBAL_TARGET) @@ -785,7 +780,7 @@ bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project, if(type == cmTarget::UTILITY) { return this->IsDependedOn(project, target); - } + } // default is to be part of the build return true; } diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 9b9107d..1df58f9 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -112,7 +112,6 @@ protected: virtual void WriteSLNFooter(std::ostream& fout); virtual void WriteSLNHeader(std::ostream& fout); virtual std::string WriteUtilityDepend(cmTarget* target); - virtual void AddPlatformDefinitions(cmMakefile* mf); virtual void WriteTargetsToSolution( std::ostream& fout, diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index e7c4232..bca1754 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -21,7 +21,6 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator() { this->FindMakeProgramFile = "CMakeVS8FindMake.cmake"; this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms"; - this->ArchitectureId = "X86"; } //---------------------------------------------------------------------------- @@ -35,7 +34,7 @@ cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator() lg->SetGlobalGenerator(this); return lg; } - + //---------------------------------------------------------------------------- // ouput standard header for dsw file void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout) @@ -49,19 +48,11 @@ void cmGlobalVisualStudio8Generator ::GetDocumentation(cmDocumentationEntry& entry) const { entry.Name = this->GetName(); - entry.Brief = "Generates Visual Studio .NET 2005 project files."; + entry.Brief = "Generates Visual Studio 8 2005 project files."; entry.Full = ""; } //---------------------------------------------------------------------------- -void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf) -{ - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId); - mf->AddDefinition("MSVC80", "1"); -} - -//---------------------------------------------------------------------------- void cmGlobalVisualStudio8Generator::Configure() { this->cmGlobalVisualStudio7Generator::Configure(); @@ -336,7 +327,7 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies( //---------------------------------------------------------------------------- static cmVS7FlagTable cmVS8ExtraFlagTable[] = -{ +{ {"CallingConvention", "Gd", "cdecl", "0", 0 }, {"CallingConvention", "Gr", "fastcall", "1", 0 }, {"CallingConvention", "Gz", "stdcall", "2", 0 }, diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 7dae429..5009f29 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -24,9 +24,9 @@ class cmGlobalVisualStudio8Generator : public cmGlobalVisualStudio71Generator { public: cmGlobalVisualStudio8Generator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio8Generator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio8Generator::GetActualName();} @@ -36,7 +36,7 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); @@ -72,7 +72,6 @@ protected: void AddCheckTarget(); static cmIDEFlagTable const* GetExtraFlagTableVS8(); - virtual void AddPlatformDefinitions(cmMakefile* mf); virtual void WriteSLNHeader(std::ostream& fout); virtual void WriteSolutionConfigurations(std::ostream& fout); virtual void WriteProjectConfigurations(std::ostream& fout, @@ -82,7 +81,5 @@ protected: virtual bool ComputeTargetDepends(); virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); - - const char* ArchitectureId; }; #endif diff --git a/Source/cmGlobalVisualStudio8Win64Generator.cxx b/Source/cmGlobalVisualStudio8Win64Generator.cxx index 60e45b8..4cbc275 100644 --- a/Source/cmGlobalVisualStudio8Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio8Win64Generator.cxx @@ -22,23 +22,12 @@ cmGlobalVisualStudio8Win64Generator::cmGlobalVisualStudio8Win64Generator() this->ArchitectureId = "x64"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator *cmGlobalVisualStudio8Win64Generator::CreateLocalGenerator() -{ - cmLocalVisualStudio7Generator *lg - = new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8); - lg->SetPlatformName(this->GetPlatformName()); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - lg->SetGlobalGenerator(this); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio8Win64Generator ::GetDocumentation(cmDocumentationEntry& entry) const { entry.Name = this->GetName(); - entry.Brief = "Generates Visual Studio .NET 2005 Win64 project files."; + entry.Brief = "Generates Visual Studio 8 2005 Win64 project files."; entry.Full = ""; } diff --git a/Source/cmGlobalVisualStudio8Win64Generator.h b/Source/cmGlobalVisualStudio8Win64Generator.h index 084ba69..12f8012 100644 --- a/Source/cmGlobalVisualStudio8Win64Generator.h +++ b/Source/cmGlobalVisualStudio8Win64Generator.h @@ -20,14 +20,14 @@ * * cmGlobalVisualStudio8Win64Generator manages UNIX build process for a tree */ -class cmGlobalVisualStudio8Win64Generator : +class cmGlobalVisualStudio8Win64Generator : public cmGlobalVisualStudio8Generator { public: cmGlobalVisualStudio8Win64Generator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio8Win64Generator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio8Win64Generator::GetActualName();} @@ -38,12 +38,9 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(); - /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void AddPlatformDefinitions(cmMakefile *); }; diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index f082675..70af50d 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -23,14 +23,6 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator() } //---------------------------------------------------------------------------- -void cmGlobalVisualStudio9Generator::AddPlatformDefinitions(cmMakefile* mf) -{ - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId); - mf->AddDefinition("MSVC90", "1"); -} - -//---------------------------------------------------------------------------- void cmGlobalVisualStudio9Generator::WriteSLNHeader(std::ostream& fout) { fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n"; @@ -59,7 +51,7 @@ void cmGlobalVisualStudio9Generator //---------------------------------------------------------------------------- void cmGlobalVisualStudio9Generator -::EnableLanguage(std::vector<std::string>const & lang, +::EnableLanguage(std::vector<std::string>const & lang, cmMakefile *mf, bool optional) { cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional); diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h index bfb03c4c..0b0d143 100644 --- a/Source/cmGlobalVisualStudio9Generator.h +++ b/Source/cmGlobalVisualStudio9Generator.h @@ -20,20 +20,19 @@ * * cmGlobalVisualStudio9Generator manages UNIX build process for a tree */ -class cmGlobalVisualStudio9Generator : +class cmGlobalVisualStudio9Generator : public cmGlobalVisualStudio8Generator { public: cmGlobalVisualStudio9Generator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio9Generator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio9Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 9 2008";} - virtual void AddPlatformDefinitions(cmMakefile* mf); - + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; @@ -42,9 +41,9 @@ public: /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string>const& languages, + virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); virtual void WriteSLNHeader(std::ostream& fout); diff --git a/Source/cmGlobalVisualStudio9IA64Generator.cxx b/Source/cmGlobalVisualStudio9IA64Generator.cxx index 993340a..38dbfac 100644 --- a/Source/cmGlobalVisualStudio9IA64Generator.cxx +++ b/Source/cmGlobalVisualStudio9IA64Generator.cxx @@ -19,17 +19,6 @@ cmGlobalVisualStudio9IA64Generator::cmGlobalVisualStudio9IA64Generator() this->ArchitectureId = "Itanium"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator *cmGlobalVisualStudio9IA64Generator::CreateLocalGenerator() -{ - cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9); - lg->SetPlatformName(this->GetPlatformName()); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - lg->SetGlobalGenerator(this); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio9IA64Generator ::GetDocumentation(cmDocumentationEntry& entry) const diff --git a/Source/cmGlobalVisualStudio9IA64Generator.h b/Source/cmGlobalVisualStudio9IA64Generator.h index e33ee15..989b0d1 100644 --- a/Source/cmGlobalVisualStudio9IA64Generator.h +++ b/Source/cmGlobalVisualStudio9IA64Generator.h @@ -38,9 +38,6 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(); - /** * Try to determine system infomation such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalVisualStudio9Win64Generator.cxx b/Source/cmGlobalVisualStudio9Win64Generator.cxx index 08f537d..4d8a646 100644 --- a/Source/cmGlobalVisualStudio9Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio9Win64Generator.cxx @@ -19,17 +19,6 @@ cmGlobalVisualStudio9Win64Generator::cmGlobalVisualStudio9Win64Generator() this->ArchitectureId = "x64"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator *cmGlobalVisualStudio9Win64Generator::CreateLocalGenerator() -{ - cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9); - lg->SetPlatformName(this->GetPlatformName()); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - lg->SetGlobalGenerator(this); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio9Win64Generator ::GetDocumentation(cmDocumentationEntry& entry) const diff --git a/Source/cmGlobalVisualStudio9Win64Generator.h b/Source/cmGlobalVisualStudio9Win64Generator.h index f6dcc03..7c20cf4 100644 --- a/Source/cmGlobalVisualStudio9Win64Generator.h +++ b/Source/cmGlobalVisualStudio9Win64Generator.h @@ -20,14 +20,14 @@ * * cmGlobalVisualStudio8Win64Generator manages UNIX build process for a tree */ -class cmGlobalVisualStudio9Win64Generator : +class cmGlobalVisualStudio9Win64Generator : public cmGlobalVisualStudio9Generator { public: cmGlobalVisualStudio9Win64Generator(); - static cmGlobalGenerator* New() { + static cmGlobalGenerator* New() { return new cmGlobalVisualStudio9Win64Generator; } - + ///! Get the name for the generator. virtual const char* GetName() const { return cmGlobalVisualStudio9Win64Generator::GetActualName();} @@ -38,12 +38,9 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(); - /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ virtual void AddPlatformDefinitions(cmMakefile *); }; diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 2a918c9..0968b77 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -21,6 +21,7 @@ //---------------------------------------------------------------------------- cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator() { + this->ArchitectureId = "X86"; } //---------------------------------------------------------------------------- @@ -53,7 +54,7 @@ void cmGlobalVisualStudioGenerator::Generate() { // Use no actual command lines so that the target itself is not // considered always out of date. - cmTarget* allBuild = + cmTarget* allBuild = gen[0]->GetMakefile()-> AddUtilityCommand("ALL_BUILD", true, no_working_dir, no_depends, no_commands, false, @@ -489,6 +490,13 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) } //---------------------------------------------------------------------------- +void cmGlobalVisualStudioGenerator::AddPlatformDefinitions(cmMakefile* mf) +{ + mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId); + mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId); +} + +//---------------------------------------------------------------------------- std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget* target) { UtilityDependsMap::iterator i = this->UtilityDepends.find(target); diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index b62ba22..cebf7d7 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -58,7 +58,7 @@ public: */ virtual void CallVisualStudioMacro(MacroName m, const char* vsSolutionFile = 0); - + // return true if target is fortran only bool TargetIsFortranOnly(cmTarget& t); @@ -84,6 +84,8 @@ protected: virtual const char* GetIDEVersion() = 0; + virtual void AddPlatformDefinitions(cmMakefile* mf); + virtual bool ComputeTargetDepends(); class VSDependSet: public std::set<cmStdString> {}; class VSDependMap: public std::map<cmTarget*, VSDependSet> {}; @@ -96,6 +98,8 @@ protected: std::string GetUtilityDepend(cmTarget* target); typedef std::map<cmTarget*, cmStdString> UtilityDependsMap; UtilityDependsMap UtilityDepends; + const char* ArchitectureId; + private: void ComputeTargetObjects(cmGeneratorTarget* gt) const; diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 8c6dff9..45b171f 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -23,11 +23,11 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator() } void cmGlobalWatcomWMakeGenerator -::EnableLanguage(std::vector<std::string>const& l, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& l, + cmMakefile *mf, bool optional) { - // pick a default + // pick a default mf->AddDefinition("WATCOM", "1"); mf->AddDefinition("CMAKE_QUOTE_INCLUDE_PATHS", "1"); mf->AddDefinition("CMAKE_MANGLE_OBJECT_FILE_NAMES", "1"); diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index b416bb1..ee16eae 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -31,15 +31,15 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string>const& languages, + virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); }; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 522f3da..5b2ddd8 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -136,8 +136,23 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::New() { #if defined(CMAKE_BUILD_WITH_CMAKE) cmXcodeVersionParser parser; - if (cmSystemTools::FileExists( - "/Applications/Xcode.app/Contents/version.plist")) + std::string versionFile; + { + std::string out; + std::string::size_type pos; + if(cmSystemTools::RunSingleCommand("xcode-select --print-path", &out, 0, 0, + cmSystemTools::OUTPUT_NONE) && + (pos = out.find(".app/"), pos != out.npos)) + { + versionFile = out.substr(0, pos+5)+"Contents/version.plist"; + } + } + if(!versionFile.empty() && cmSystemTools::FileExists(versionFile.c_str())) + { + parser.ParseFile(versionFile.c_str()); + } + else if (cmSystemTools::FileExists( + "/Applications/Xcode.app/Contents/version.plist")) { parser.ParseFile ("/Applications/Xcode.app/Contents/version.plist"); @@ -480,8 +495,12 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile( (this->CurrentReRunCMakeMakefile.c_str()); makefileStream.SetCopyIfDifferent(true); makefileStream << "# Generated by CMake, DO NOT EDIT\n"; - makefileStream << cmake::GetCMakeFilesDirectoryPostSlash(); - makefileStream << "cmake.check_cache: "; + std::string checkCache = mf->GetHomeOutputDirectory(); + checkCache += "/"; + checkCache += cmake::GetCMakeFilesDirectoryPostSlash(); + checkCache += "cmake.check_cache"; + makefileStream << this->ConvertToRelativeForMake(checkCache.c_str()) + << ": "; for(std::vector<std::string>::const_iterator i = lfiles.begin(); i != lfiles.end(); ++i) { @@ -772,6 +791,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext, { sourcecode += ".fortran.f90"; } + else if(lang == "ASM") + { + sourcecode += ".asm"; + } //else // { // // Already specialized above or we leave sourcecode == "sourcecode" @@ -1594,14 +1617,14 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, if(strcmp(lang, "CXX") == 0) { this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName); - this->CurrentLocalGenerator->AddSharedFlags(cflags, lang, shared); + this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C"); } // Add language-specific flags. this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName); // Add shared-library flags if needed. - this->CurrentLocalGenerator->AddSharedFlags(flags, lang, shared); + this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang); } else if(binary) { @@ -1628,16 +1651,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // Add the export symbol definition for shared library objects. this->AppendDefines(ppDefs, exportMacro); } - this->AppendDefines - (ppDefs, this->CurrentMakefile->GetProperty("COMPILE_DEFINITIONS")); - this->AppendDefines(ppDefs, target.GetProperty("COMPILE_DEFINITIONS")); + cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); + this->AppendDefines(ppDefs, gtgt->GetCompileDefinitions().c_str()); if(configName) { - std::string defVarName = "COMPILE_DEFINITIONS_"; - defVarName += cmSystemTools::UpperCase(configName); - this->AppendDefines - (ppDefs, this->CurrentMakefile->GetProperty(defVarName.c_str())); - this->AppendDefines(ppDefs, target.GetProperty(defVarName.c_str())); + this->AppendDefines(ppDefs, + gtgt->GetCompileDefinitions(configName).c_str()); } buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); @@ -1694,7 +1713,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // Set target-specific architectures. std::vector<std::string> archs; - target.GetAppleArchs(configName, archs); + gtgt->GetAppleArchs(configName, archs); + if(!archs.empty()) { // Enable ARCHS attribute. @@ -1931,7 +1951,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, BuildObjectListOrString dirs(this, this->XcodeVersion >= 30); BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30); std::vector<std::string> includes; - this->CurrentLocalGenerator->GetIncludeDirectories(includes, &target); + this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, + "C", configName); std::set<cmStdString> emitted; emitted.insert("/System/Library/Frameworks"); for(std::vector<std::string>::iterator i = includes.begin(); @@ -2606,7 +2627,8 @@ void cmGlobalXCodeGenerator } // Compute the link library and directory information. - cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName); + cmGeneratorTarget* gtgt = this->GetGeneratorTarget(cmtarget); + cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName); if(!pcli) { continue; @@ -3099,18 +3121,14 @@ void cmGlobalXCodeGenerator const char* sysroot = this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT"); - const char* sysrootDefault = - this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT_DEFAULT"); const char* deploymentTarget = this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); if(osxArch && sysroot) { - bool flagsUsed = false; // recompute this as it may have been changed since enable language this->Architectures.clear(); cmSystemTools::ExpandListArgument(std::string(osxArch), this->Architectures); - flagsUsed = true; buildSettings->AddAttribute("SDKROOT", this->CreateString(sysroot)); std::string archString; @@ -3125,12 +3143,6 @@ void cmGlobalXCodeGenerator } buildSettings->AddAttribute("ARCHS", this->CreateString(archString.c_str())); - if(!flagsUsed && sysrootDefault && - strcmp(sysroot, sysrootDefault) != 0) - { - buildSettings->AddAttribute("SDKROOT", - this->CreateString(sysroot)); - } } if(deploymentTarget && *deploymentTarget) { @@ -3739,7 +3751,7 @@ cmGlobalXCodeGenerator const char* configName = this->GetCMakeCFGIntDir(); std::string dir = this->GetObjectsNormalDirectory( - this->CurrentProject, configName, gt->Target); + "$(PROJECT_NAME)", configName, gt->Target); if(this->XcodeVersion >= 21) { dir += "$(CURRENT_ARCH)/"; diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 800963b..afa1ca2 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -38,15 +38,15 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); /** * Try to determine system infomation such as shared library - * extension, pthreads, byte order etc. + * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string>const& languages, + virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional); /** * Try running cmake and building a file. This is used for dynalically @@ -54,16 +54,16 @@ public: */ virtual std::string GenerateBuildCommand(const char* makeProgram, const char *projectName, - const char* additionalOptions, + const char* additionalOptions, const char *targetName, - const char* config, + const char* config, bool ignoreErrors, bool fast); /** * Generate the all required files for building this project/tree. This * basically creates a series of LocalGenerators for each directory and - * requests that they Generate. + * requests that they Generate. */ virtual void Generate(); @@ -82,7 +82,7 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ virtual bool IsMultiConfig(); -private: +private: cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg); cmXCodeObject* CreatePBXGroup(cmXCodeObject *parent, @@ -107,18 +107,18 @@ private: void AddCommandsToBuildPhase(cmXCodeObject* buildphase, cmTarget& target, - std::vector<cmCustomCommand> + std::vector<cmCustomCommand> const & commands, const char* commandFileName); - - void CreateCustomRulesMakefile(const char* makefileBasename, + + void CreateCustomRulesMakefile(const char* makefileBasename, cmTarget& target, std::vector<cmCustomCommand> const & commands, const char* configName, - const std::map<cmStdString, cmStdString>& + const std::map<cmStdString, cmStdString>& multipleOutputPairs ); - + cmXCodeObject* FindXCodeTarget(cmTarget*); std::string GetOrCreateId(const char* name, const char* id); @@ -135,9 +135,9 @@ private: const char* GetTargetFileType(cmTarget& cmtarget); const char* GetTargetProductType(cmTarget& cmtarget); std::string AddConfigurations(cmXCodeObject* target, cmTarget& cmtarget); - void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr, + void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr, const char* value); - void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr, + void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr, const char* value, const char* configName); cmXCodeObject* CreateUtilityTarget(cmTarget& target); void AddDependAndLinkInformation(cmXCodeObject* target); @@ -161,10 +161,10 @@ private: const std::string &lang); cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf, cmTarget& cmtarget); - cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, + cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf, cmTarget& cmtarget); - void CreateXCodeTargets(cmLocalGenerator* gen, + void CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&); bool IsHeaderFile(cmSourceFile*); void AddDependTarget(cmXCodeObject* target, @@ -172,9 +172,9 @@ private: void CreateXCodeDependHackTarget(std::vector<cmXCodeObject*>& targets); bool SpecialTargetEmitted(std::string const& tname); void SetGenerationRoot(cmLocalGenerator* root); - void AddExtraTargets(cmLocalGenerator* root, + void AddExtraTargets(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& gens); - cmXCodeObject* CreateBuildPhase(const char* name, + cmXCodeObject* CreateBuildPhase(const char* name, const char* name2, cmTarget& cmtarget, const std::vector<cmCustomCommand>&); diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx index 2ff7945..a540825 100644 --- a/Source/cmHexFileConverter.cxx +++ b/Source/cmHexFileConverter.cxx @@ -22,8 +22,8 @@ // might go to SystemTools ? static bool cm_IsHexChar(char c) { - return (((c >= '0') && (c <= '9')) - || ((c >= 'a') && (c <= 'f')) + return (((c >= '0') && (c <= '9')) + || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'))); } @@ -45,7 +45,7 @@ static unsigned int ChompStrlen(const char* line) return length; } -static bool OutputBin(FILE* file, const char * buf, +static bool OutputBin(FILE* file, const char * buf, unsigned int startIndex, unsigned int stopIndex) { bool success = true; @@ -77,7 +77,7 @@ static bool OutputBin(FILE* file, const char * buf, static bool ConvertMotorolaSrecLine(const char* buf, FILE* outFile) { unsigned int slen = ChompStrlen(buf); - if ((slen < MOTOROLA_SREC_MIN_LINE_LENGTH) + if ((slen < MOTOROLA_SREC_MIN_LINE_LENGTH) || (slen > MOTOROLA_SREC_MAX_LINE_LENGTH)) { return false; @@ -125,7 +125,7 @@ static bool ConvertMotorolaSrecLine(const char* buf, FILE* outFile) static bool ConvertIntelHexLine(const char* buf, FILE* outFile) { unsigned int slen = ChompStrlen(buf); - if ((slen < INTEL_HEX_MIN_LINE_LENGTH) + if ((slen < INTEL_HEX_MIN_LINE_LENGTH) || (slen > INTEL_HEX_MAX_LINE_LENGTH)) { return false; @@ -148,7 +148,7 @@ static bool ConvertIntelHexLine(const char* buf, FILE* outFile) dataStart = 9; } // ignore extra address records - else if ((buf[8] == '2') || (buf[8] == '3') || (buf[8] == '4') + else if ((buf[8] == '2') || (buf[8] == '3') || (buf[8] == '4') || (buf[8] == '5')) { return true; diff --git a/Source/cmHexFileConverter.h b/Source/cmHexFileConverter.h index 94c757f..e11d74a 100644 --- a/Source/cmHexFileConverter.h +++ b/Source/cmHexFileConverter.h @@ -13,7 +13,7 @@ #define cmHexFileConverter_h /** \class cmHexFileConverter - * \brief Can detects Intel Hex and Motorola S-record files and convert them + * \brief Can detects Intel Hex and Motorola S-record files and convert them * to binary files. * */ diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index d9c0e87..76a60cf 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -177,3 +177,14 @@ void cmIDEOptions::RemoveFlag(const char* flag) { this->FlagMap.erase(flag); } + +//---------------------------------------------------------------------------- +const char* cmIDEOptions::GetFlag(const char* flag) +{ + std::map<cmStdString, cmStdString>::iterator i = this->FlagMap.find(flag); + if(i != this->FlagMap.end()) + { + return i->second.c_str(); + } + return 0; +} diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h index a5be8fb..e556bde 100644 --- a/Source/cmIDEOptions.h +++ b/Source/cmIDEOptions.h @@ -29,6 +29,7 @@ public: void AddDefines(const char* defines); void AddFlag(const char* flag, const char* value); void RemoveFlag(const char* flag); + const char* GetFlag(const char* flag); protected: // create a map of xml tags to the values they should have in the output diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index ffc0f35..56d7170 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -409,14 +409,18 @@ namespace enum Op { OpLess, OpEqual, OpGreater }; bool HandleVersionCompare(Op op, const char* lhs_str, const char* rhs_str) { - // Parse out up to 4 components. - unsigned int lhs[4] = {0,0,0,0}; - unsigned int rhs[4] = {0,0,0,0}; - sscanf(lhs_str, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]); - sscanf(rhs_str, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]); + // Parse out up to 8 components. + unsigned int lhs[8] = {0,0,0,0,0,0,0,0}; + unsigned int rhs[8] = {0,0,0,0,0,0,0,0}; + sscanf(lhs_str, "%u.%u.%u.%u.%u.%u.%u.%u", + &lhs[0], &lhs[1], &lhs[2], &lhs[3], + &lhs[4], &lhs[5], &lhs[6], &lhs[7]); + sscanf(rhs_str, "%u.%u.%u.%u.%u.%u.%u.%u", + &rhs[0], &rhs[1], &rhs[2], &rhs[3], + &rhs[4], &rhs[5], &rhs[6], &rhs[7]); // Do component-wise comparison. - for(unsigned int i=0; i < 4; ++i) + for(unsigned int i=0; i < 8; ++i) { if(lhs[i] < rhs[i]) { diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 83ea8a4..f794b78 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -26,7 +26,7 @@ public: cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - + std::vector<cmListFileArgument> Args; std::vector<cmListFileFunction> Functions; bool IsBlocking; @@ -41,7 +41,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmIfCommand; } @@ -52,7 +52,7 @@ public: */ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, cmExecutionStatus &); - + /** * This is called when the command is first encountered in * the CMakeLists.txt file. @@ -72,7 +72,7 @@ public: { return "Conditionally execute a group of commands."; } - + /** * This determines if the command is invoked when in script mode. */ @@ -114,7 +114,7 @@ public: "will be evaluated. Possible expressions are:\n" " if(<constant>)\n" "True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. " - "False if the constant is 0, OFF, NO, FALSE, N, IGNORE, \"\", " + "False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, '', " "or ends in the suffix '-NOTFOUND'. " "Named boolean constants are case-insensitive. " "If the argument is not one of these constants, " @@ -123,6 +123,7 @@ public: " if(<variable>)\n" "True if the variable is defined to a value that is not a false " "constant. False otherwise. " + "(Note macro arguments are not variables.)" "\n" " if(NOT <expression>)\n" "True if the expression is not true." @@ -148,7 +149,12 @@ public: " if(file1 IS_NEWER_THAN file2)\n" "True if file1 is newer than file2 or if one of the two files " "doesn't exist. " - "Behavior is well-defined only for full paths.\n" + "Behavior is well-defined only for full paths. " + "If the file time stamps are exactly the same, an " + "IS_NEWER_THAN comparison returns true, so that any dependent " + "build operations will occur in the event of a tie. " + "This includes the case of passing the same file name for both " + "file1 and file2.\n" " if(IS_DIRECTORY directory-name)\n" "True if the given name is a directory. " "Behavior is well-defined only for full paths.\n" @@ -237,22 +243,22 @@ public: "7) The left and right hand arguments to AND OR are " "independently tested to see if they are boolean constants, if " "so they are used as such, otherwise they are assumed to be " - "variables and are dereferenced. \n" + "variables and are dereferenced. \n" ; } // this is a shared function for both If and Else to determine if the // arguments were valid, and if so, was the response true. If there is // an error, the errorString will be set. - static bool IsTrue(const std::vector<std::string> &args, - std::string &errorString, cmMakefile *mf, + static bool IsTrue(const std::vector<std::string> &args, + std::string &errorString, cmMakefile *mf, cmake::MessageType &status); - + // Get a definition from the makefile. If it doesn't exist, // return the original string. static const char* GetVariableOrString(const char* str, const cmMakefile* mf); - + cmTypeMacro(cmIfCommand, cmCommand); }; diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index 0ac6df4..0d5f67b 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -70,6 +70,13 @@ bool cmIncludeCommand } } + if(fname.empty()) + { + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, + "include() given empty file name (ignored)."); + return true; + } + if(!cmSystemTools::FileIsFullPath(fname.c_str())) { // Not a path. Maybe module. diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index 9e6f4b6..ba81849 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -55,6 +55,11 @@ bool cmIncludeDirectoryCommand return true; } +static bool StartsWithGeneratorExpression(const std::string &input) +{ + return input[0] == '$' && input[1] == '<'; +} + // do a lot of cleanup on the arguments because this is one place where folks // sometimes take the output of a program and pass it directly into this // command not thinking that a single argument could be filled with spaces @@ -67,8 +72,8 @@ bool cmIncludeDirectoryCommand // output from a program and passing it into a command the cleanup doesn't // always happen // -void cmIncludeDirectoryCommand::AddDirectory(const char *i, - bool before, +void cmIncludeDirectoryCommand::AddDirectory(const char *i, + bool before, bool system) { // break apart any line feed arguments @@ -91,7 +96,7 @@ void cmIncludeDirectoryCommand::AddDirectory(const char *i, // remove any leading or trailing spaces and \r std::string::size_type b = ret.find_first_not_of(" \r"); std::string::size_type e = ret.find_last_not_of(" \r"); - if ((b!=ret.npos) && (e!=ret.npos)) + if ((b!=ret.npos) && (e!=ret.npos)) { ret.assign(ret, b, 1+e-b); // copy the remaining substring } @@ -105,10 +110,13 @@ void cmIncludeDirectoryCommand::AddDirectory(const char *i, cmSystemTools::ConvertToUnixSlashes(ret); if(!cmSystemTools::FileIsFullPath(ret.c_str())) { - std::string tmp = this->Makefile->GetStartDirectory(); - tmp += "/"; - tmp += ret; - ret = tmp; + if(!StartsWithGeneratorExpression(ret)) + { + std::string tmp = this->Makefile->GetStartDirectory(); + tmp += "/"; + tmp += ret; + ret = tmp; + } } } this->Makefile->AddIncludeDirectory(ret.c_str(), before); diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h index dcc116a..6751fc0 100644 --- a/Source/cmIncludeDirectoryCommand.h +++ b/Source/cmIncludeDirectoryCommand.h @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmIncludeDirectoryCommand; } @@ -50,7 +50,7 @@ public: { return "Add include directories to the build."; } - + /** * More documentation. */ @@ -76,7 +76,7 @@ public: "directories are meant as system include directories on some " "platforms."; } - + cmTypeMacro(cmIncludeDirectoryCommand, cmCommand); protected: diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx index d219c16..d40d8fe 100644 --- a/Source/cmIncludeExternalMSProjectCommand.cxx +++ b/Source/cmIncludeExternalMSProjectCommand.cxx @@ -15,7 +15,7 @@ bool cmIncludeExternalMSProjectCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { - if(args.size() < 2) + if(args.size() < 2) { this->SetError("INCLUDE_EXTERNAL_MSPROJECT called with incorrect " "number of arguments"); @@ -77,7 +77,7 @@ bool cmIncludeExternalMSProjectCommand } // Create a target instance for this utility. - cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY, + cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY, utility_name.c_str()); target->SetProperty("GENERATOR_FILE_NAME", utility_name.c_str()); diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h index 2b2ed0d..d5cec01 100644 --- a/Source/cmIncludeExternalMSProjectCommand.h +++ b/Source/cmIncludeExternalMSProjectCommand.h @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmIncludeExternalMSProjectCommand; } @@ -38,7 +38,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -51,7 +51,7 @@ public: { return "Include an external Microsoft project file in a workspace."; } - + /** * More documentation. */ @@ -75,7 +75,7 @@ public: "(e.g. WIX projects). " "These options are not supported by the Visual Studio 6 generator."; } - + cmTypeMacro(cmIncludeExternalMSProjectCommand, cmCommand); }; diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx index b0d8325..ef6e8c6 100644 --- a/Source/cmIncludeRegularExpressionCommand.cxx +++ b/Source/cmIncludeRegularExpressionCommand.cxx @@ -21,12 +21,12 @@ bool cmIncludeRegularExpressionCommand return false; } this->Makefile->SetIncludeRegularExpression(args[0].c_str()); - + if(args.size() > 1) { this->Makefile->SetComplainRegularExpression(args[1].c_str()); } - + return true; } diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h index 7c633c0..2e41775 100644 --- a/Source/cmIncludeRegularExpressionCommand.h +++ b/Source/cmIncludeRegularExpressionCommand.h @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmIncludeRegularExpressionCommand; } @@ -37,7 +37,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -50,7 +50,7 @@ public: { return "Set the regular expression used for dependency checking."; } - + /** * More documentation. */ @@ -66,7 +66,7 @@ public: " regex_match = \"^.*$\" (match everything)\n" " regex_complain = \"^$\" (match empty string only)"; } - + cmTypeMacro(cmIncludeRegularExpressionCommand, cmCommand); }; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 4016734..dcd418b 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -17,6 +17,8 @@ #include "cmInstallTargetGenerator.h" #include "cmInstallExportGenerator.h" #include "cmInstallCommandArguments.h" +#include "cmTargetExport.h" +#include "cmExportSet.h" #include <cmsys/Glob.hxx> @@ -735,11 +737,16 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // this is not a namelink-only rule. if(!exports.GetString().empty() && !namelinkOnly) { + cmTargetExport *te = new cmTargetExport; + te->Target = ⌖ + te->ArchiveGenerator = archiveGenerator; + te->BundleGenerator = bundleGenerator; + te->FrameworkGenerator = frameworkGenerator; + te->HeaderGenerator = publicHeaderGenerator; + te->LibraryGenerator = libraryGenerator; + te->RuntimeGenerator = runtimeGenerator; this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->AddTargetToExports(exports.GetCString(), &target, - archiveGenerator, runtimeGenerator, - libraryGenerator, frameworkGenerator, - bundleGenerator, publicHeaderGenerator); + ->GetExportSets()[exports.GetString()]->AddTargetExport(te); } } @@ -1264,7 +1271,9 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - exp.GetCString(), ica.GetDestination().c_str(), + this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator()->GetExportSets()[exp.GetString()], + ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), fname.c_str(), name_space.GetCString(), this->Makefile); diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index bf9fd9e..7c06009 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -70,7 +70,9 @@ public: "the directory on disk to which a file will be installed. " "If a full path (with a leading slash or drive letter) is given it " "is used directly. If a relative path is given it is interpreted " - "relative to the value of CMAKE_INSTALL_PREFIX.\n" + "relative to the value of CMAKE_INSTALL_PREFIX. The prefix can " + "be relocated at install time using DESTDIR mechanism explained in the " + "CMAKE_INSTALL_PREFIX variable documentation.\n" "PERMISSIONS arguments specify permissions for installed files. " "Valid permissions are " "OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, " @@ -85,7 +87,10 @@ public: "with which the install rule is associated, such as \"runtime\" or " "\"development\". During component-specific installation only " "install rules associated with the given component name will be " - "executed. During a full installation all components are installed.\n" + "executed. During a full installation all components are installed." + " If COMPONENT is not provided a default component \"Unspecified\" is" + " created. The default component name may be controlled with the " + "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME variable.\n" "The RENAME argument specifies a name for an installed file that " "may be different from the original file. Renaming is allowed only " "when a single file is installed by the command.\n" diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx index 0ba21c7..8e48f08 100644 --- a/Source/cmInstallCommandArguments.cxx +++ b/Source/cmInstallCommandArguments.cxx @@ -36,8 +36,8 @@ cmInstallCommandArguments::cmInstallCommandArguments( ,NamelinkOnly (&Parser, "NAMELINK_ONLY" , &ArgumentGroup) ,NamelinkSkip (&Parser, "NAMELINK_SKIP" , &ArgumentGroup) ,GenericArguments(0) +,DefaultComponentName(defaultComponent) { - this->Component.SetDefaultString(defaultComponent.c_str()); } const std::string& cmInstallCommandArguments::GetDestination() const @@ -63,7 +63,10 @@ const std::string& cmInstallCommandArguments::GetComponent() const { return this->GenericArguments->GetComponent(); } - + if (!this->DefaultComponentName.empty()) + { + return this->DefaultComponentName; + } static std::string unspecifiedComponent = "Unspecified"; return unspecifiedComponent; } diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h index 321454a..01f7d56 100644 --- a/Source/cmInstallCommandArguments.h +++ b/Source/cmInstallCommandArguments.h @@ -61,6 +61,7 @@ class cmInstallCommandArguments cmInstallCommandArguments* GenericArguments; static const char* PermissionsTable[]; static const std::string EmptyString; + std::string DefaultComponentName; bool CheckPermissions(); }; diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 28a19d7..0a645a8 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -23,10 +23,11 @@ #include "cmInstallFilesGenerator.h" #include "cmExportInstallFileGenerator.h" +#include "cmExportSet.h" //---------------------------------------------------------------------------- cmInstallExportGenerator::cmInstallExportGenerator( - const char* name, + cmExportSet* exportSet, const char* destination, const char* file_permissions, std::vector<std::string> const& configurations, @@ -34,13 +35,14 @@ cmInstallExportGenerator::cmInstallExportGenerator( const char* filename, const char* name_space, cmMakefile* mf) :cmInstallGenerator(destination, configurations, component) - ,Name(name) + ,ExportSet(exportSet) ,FilePermissions(file_permissions) ,FileName(filename) ,Namespace(name_space) ,Makefile(mf) { this->EFGen = new cmExportInstallFileGenerator(this); + exportSet->AddInstallation(this); } //---------------------------------------------------------------------------- @@ -113,16 +115,12 @@ void cmInstallExportGenerator::ComputeTempDir() //---------------------------------------------------------------------------- void cmInstallExportGenerator::GenerateScript(std::ostream& os) { - // Get the export set requested. - ExportSet const* exportSet = - this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->GetExportSet(this->Name.c_str()); - // Skip empty sets. - if(!exportSet) + if(ExportSet->GetTargetExports()->empty()) { cmOStringStream e; - e << "INSTALL(EXPORT) given unknown export \"" << this->Name << "\""; + e << "INSTALL(EXPORT) given unknown export \"" + << ExportSet->GetName() << "\""; cmSystemTools::Error(e.str().c_str()); return; } @@ -137,8 +135,6 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os) this->MainImportFile += this->FileName; // Generate the import file for this export set. - this->EFGen->SetName(this->Name.c_str()); - this->EFGen->SetExportSet(exportSet); this->EFGen->SetExportFile(this->MainImportFile.c_str()); this->EFGen->SetNamespace(this->Namespace.c_str()); if(this->ConfigurationTypes->empty()) diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 1ff6e38..ee92906 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -17,8 +17,7 @@ class cmExportInstallFileGenerator; class cmInstallFilesGenerator; class cmInstallTargetGenerator; -class cmTarget; -class cmTargetExport; +class cmExportSet; class cmMakefile; /** \class cmInstallExportGenerator @@ -27,24 +26,27 @@ class cmMakefile; class cmInstallExportGenerator: public cmInstallGenerator { public: - cmInstallExportGenerator(const char* name, + cmInstallExportGenerator(cmExportSet* exportSet, const char* dest, const char* file_permissions, const std::vector<std::string>& configurations, const char* component, const char* filename, const char* name_space, cmMakefile* mf); ~cmInstallExportGenerator(); -protected: - typedef std::vector<cmTargetExport*> ExportSet; + cmExportSet* GetExportSet() {return this->ExportSet;} + + const std::string& GetNamespace() const { return this->Namespace; } + +protected: virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent); virtual void GenerateScriptActions(std::ostream& os, Indent const& indent); - void GenerateImportFile(ExportSet const* exportSet); - void GenerateImportFile(const char* config, ExportSet const* exportSet); + void GenerateImportFile(cmExportSet const* exportSet); + void GenerateImportFile(const char* config, cmExportSet const* exportSet); void ComputeTempDir(); - std::string Name; + cmExportSet* ExportSet; std::string FilePermissions; std::string FileName; std::string Namespace; diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h index d3c7ed6..bb0a6cc 100644 --- a/Source/cmInstallFilesCommand.h +++ b/Source/cmInstallFilesCommand.h @@ -18,7 +18,7 @@ * \brief Specifies where to install some files * * cmInstallFilesCommand specifies the relative path where a list of - * files should be installed. + * files should be installed. */ class cmInstallFilesCommand : public cmCommand { @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmInstallFilesCommand; } @@ -50,7 +50,7 @@ public: { return "Deprecated. Use the install(FILES ) command instead."; } - + /** * This is called at the end after all the information * specified by the command is accumulated. Most commands do @@ -90,7 +90,7 @@ public: "The directory <dir> is relative to the installation prefix, which " "is stored in the variable CMAKE_INSTALL_PREFIX."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { @@ -102,7 +102,7 @@ public: protected: void CreateInstallGenerator() const; std::string FindInstallSource(const char* name) const; - + private: std::vector<std::string> FinalArgs; bool IsFilesForm; diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h index 29c84a0..27a0498 100644 --- a/Source/cmInstallProgramsCommand.h +++ b/Source/cmInstallProgramsCommand.h @@ -18,7 +18,7 @@ * \brief Specifies where to install some programs * * cmInstallProgramsCommand specifies the relative path where a list of - * programs should be installed. + * programs should be installed. */ class cmInstallProgramsCommand : public cmCommand { @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmInstallProgramsCommand; } @@ -50,7 +50,7 @@ public: { return "Deprecated. Use the install(PROGRAMS ) command instead."; } - + /** * This is called at the end after all the information * specified by the command is accumulated. Most commands do @@ -87,7 +87,7 @@ public: "The directory <dir> is relative to the installation prefix, which " "is stored in the variable CMAKE_INSTALL_PREFIX."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 5f9b658..347ad3e 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -16,6 +16,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmake.h" +#include "cmGeneratorTarget.h" #include <assert.h> @@ -26,7 +27,8 @@ cmInstallTargetGenerator std::vector<std::string> const& configurations, const char* component, bool optional): cmInstallGenerator(dest, configurations, component), Target(&t), - ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) + ImportLibrary(implib), FilePermissions(file_permissions), + Optional(optional), GeneratorTarget(0) { this->ActionsPerConfig = true; this->NamelinkMode = NamelinkModeNone; @@ -484,6 +486,17 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os, this->AddStripRule(os, indent, file); } +void cmInstallTargetGenerator::CreateGeneratorTarget() +{ + if (!this->GeneratorTarget) + { + this->GeneratorTarget = this->Target->GetMakefile() + ->GetLocalGenerator() + ->GetGlobalGenerator() + ->GetGeneratorTarget(this->Target); + } +} + //---------------------------------------------------------------------------- void cmInstallTargetGenerator @@ -507,10 +520,13 @@ cmInstallTargetGenerator return; } + this->CreateGeneratorTarget(); + // Build a map of build-tree install_name to install-tree install_name for // shared libraries linked to this target. std::map<cmStdString, cmStdString> install_name_remap; - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(config)) { std::set<cmTarget*> const& sharedLibs = cli->GetSharedLibrariesLinked(); for(std::set<cmTarget*>::const_iterator j = sharedLibs.begin(); @@ -608,9 +624,12 @@ cmInstallTargetGenerator return; } + this->CreateGeneratorTarget(); + // Get the link information for this target. // It can provide the RPATH. - cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); + cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(config); if(!cli) { return; @@ -639,9 +658,12 @@ cmInstallTargetGenerator return; } + this->CreateGeneratorTarget(); + // Get the link information for this target. // It can provide the RPATH. - cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); + cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(config); if(!cli) { return; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index b48d456..cab3e90 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -15,6 +15,8 @@ #include "cmInstallGenerator.h" #include "cmTarget.h" +class cmGeneratorTarget; + /** \class cmInstallTargetGenerator * \brief Generate target installation rules. */ @@ -24,7 +26,7 @@ public: cmInstallTargetGenerator( cmTarget& t, const char* dest, bool implib, const char* file_permissions = "", - std::vector<std::string> const& configurations + std::vector<std::string> const& configurations = std::vector<std::string>(), const char* component = "Unspecified", bool optional = false @@ -86,17 +88,20 @@ protected: void AddRPathCheckRule(std::ostream& os, Indent const& indent, const char* config, std::string const& toDestDirPath); - + void AddStripRule(std::ostream& os, Indent const& indent, const std::string& toDestDirPath); void AddRanlibRule(std::ostream& os, Indent const& indent, const std::string& toDestDirPath); + void CreateGeneratorTarget(); + cmTarget* Target; bool ImportLibrary; std::string FilePermissions; bool Optional; NamelinkModeType NamelinkMode; + cmGeneratorTarget* GeneratorTarget; }; #endif diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h index e05462f..c47b387 100644 --- a/Source/cmInstallTargetsCommand.h +++ b/Source/cmInstallTargetsCommand.h @@ -19,7 +19,7 @@ * * cmInstallTargetsCommand specifies the relative path where a list of * targets should be installed. The targets can be executables or - * libraries. + * libraries. */ class cmInstallTargetsCommand : public cmCommand { @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmInstallTargetsCommand; } @@ -51,7 +51,7 @@ public: { return "Deprecated. Use the install(TARGETS ) command instead."; } - + /** * More documentation. */ @@ -67,7 +67,7 @@ public: "is specified, then on systems with special runtime files " "(Windows DLL), the files will be copied to that directory."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h index a7cd583..889118c 100644 --- a/Source/cmLinkDirectoriesCommand.h +++ b/Source/cmLinkDirectoriesCommand.h @@ -18,8 +18,8 @@ * \brief Define a list of directories containing files to link. * * cmLinkDirectoriesCommand is used to specify a list - * of directories containing files to link into executable(s). - * Note that the command supports the use of CMake built-in variables + * of directories containing files to link into executable(s). + * Note that the command supports the use of CMake built-in variables * such as CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR. */ class cmLinkDirectoriesCommand : public cmCommand @@ -28,7 +28,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmLinkDirectoriesCommand; } @@ -52,7 +52,7 @@ public: { return "Specify directories in which the linker will look for libraries."; } - + /** * More documentation. */ @@ -73,7 +73,7 @@ public: "them." ; } - + cmTypeMacro(cmLinkDirectoriesCommand, cmCommand); private: void AddLinkDir(std::string const& dir); diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx index c4458aa..2f1db2a 100644 --- a/Source/cmLinkLibrariesCommand.cxx +++ b/Source/cmLinkLibrariesCommand.cxx @@ -19,7 +19,7 @@ bool cmLinkLibrariesCommand { return true; } - // add libraries, nothe that there is an optional prefix + // add libraries, nothe that there is an optional prefix // of debug and optimized than can be used for(std::vector<std::string>::const_iterator i = args.begin(); i != args.end(); ++i) @@ -50,10 +50,10 @@ bool cmLinkLibrariesCommand } else { - this->Makefile->AddLinkLibrary(i->c_str()); + this->Makefile->AddLinkLibrary(i->c_str()); } } - + return true; } diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h index 2c0212c..c450a1c 100644 --- a/Source/cmLinkLibrariesCommand.h +++ b/Source/cmLinkLibrariesCommand.h @@ -19,7 +19,7 @@ * * cmLinkLibrariesCommand is used to specify a list of libraries to link * into executable(s) or shared objects. The names of the libraries - * should be those defined by the LIBRARY(library) command(s). + * should be those defined by the LIBRARY(library) command(s). */ class cmLinkLibrariesCommand : public cmCommand { @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmLinkLibrariesCommand; } @@ -51,7 +51,7 @@ public: { return "Deprecated. Use the target_link_libraries() command instead."; } - + /** * More documentation. */ @@ -68,7 +68,7 @@ public: "the next library listed is to be used only for that specific " "type of build."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 908f3b0..df64695 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -15,13 +15,14 @@ #include <stdlib.h> // required for atoi #include <ctype.h> +#include <assert.h> //---------------------------------------------------------------------------- bool cmListCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { - if(args.size() < 1) + if(args.size() < 2) { - this->SetError("must be called with at least one argument."); + this->SetError("must be called with at least two arguments."); return false; } @@ -98,7 +99,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var) { return false; } - // if the size of the list + // if the size of the list if(listString.size() == 0) { return true; @@ -107,7 +108,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var) cmSystemTools::ExpandListArgument(listString, list, true); // check the list for empty values bool hasEmpty = false; - for(std::vector<std::string>::iterator i = list.begin(); + for(std::vector<std::string>::iterator i = list.begin(); i != list.end(); ++i) { if(i->size() == 0) @@ -116,7 +117,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var) break; } } - // if no empty elements then just return + // if no empty elements then just return if(!hasEmpty) { return true; @@ -124,7 +125,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var) // if we have empty elements we need to check policy CMP0007 switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0007)) { - case cmPolicies::WARN: + case cmPolicies::WARN: { // Default is to warn and use old behavior // OLD behavior is to allow compatibility, so recall @@ -243,11 +244,7 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) //---------------------------------------------------------------------------- bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) { - if(args.size() < 2) - { - this->SetError("sub-command APPEND requires at least one argument."); - return false; - } + assert(args.size() >= 2); // Skip if nothing to append. if(args.size() < 3) @@ -424,9 +421,11 @@ bool cmListCommand bool cmListCommand ::HandleReverseCommand(std::vector<std::string> const& args) { - if(args.size() < 2) + assert(args.size() >= 2); + if(args.size() > 2) { - this->SetError("sub-command REVERSE requires a list as an argument."); + this->SetError( + "sub-command REVERSE only takes one argument."); return false; } @@ -457,10 +456,11 @@ bool cmListCommand bool cmListCommand ::HandleRemoveDuplicatesCommand(std::vector<std::string> const& args) { - if(args.size() < 2) + assert(args.size() >= 2); + if(args.size() > 2) { this->SetError( - "sub-command REMOVE_DUPLICATES requires a list as an argument."); + "sub-command REMOVE_DUPLICATES only takes one argument."); return false; } @@ -501,9 +501,11 @@ bool cmListCommand bool cmListCommand ::HandleSortCommand(std::vector<std::string> const& args) { - if(args.size() < 2) + assert(args.size() >= 2); + if(args.size() > 2) { - this->SetError("sub-command SORT requires a list as an argument."); + this->SetError( + "sub-command SORT only takes one argument."); return false; } diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 84cb8fd..36d84f3 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -26,7 +26,7 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer, cmListFileFunction& function, const char* filename); -bool cmListFile::ParseFile(const char* filename, +bool cmListFile::ParseFile(const char* filename, bool topLevel, cmMakefile *mf) { @@ -47,7 +47,7 @@ bool cmListFile::ParseFile(const char* filename, if(!cmListFileLexer_SetFileName(lexer, filename)) { cmListFileLexer_Delete(lexer); - cmSystemTools::Error("cmListFileCache: error can not open file ", + cmSystemTools::Error("cmListFileCache: error can not open file ", filename); return false; } @@ -119,7 +119,7 @@ bool cmListFile::ParseFile(const char* filename, { bool hasVersion = false; // search for the right policy command - for(std::vector<cmListFileFunction>::iterator i + for(std::vector<cmListFileFunction>::iterator i = this->Functions.begin(); i != this->Functions.end(); ++i) { @@ -129,7 +129,7 @@ bool cmListFile::ParseFile(const char* filename, break; } } - // if no policy command is found this is an error if they use any + // if no policy command is found this is an error if they use any // non advanced functions or a lot of functions if(!hasVersion) { @@ -152,7 +152,7 @@ bool cmListFile::ParseFile(const char* filename, allowedCommands.insert("option"); allowedCommands.insert("message"); isProblem = false; - for(std::vector<cmListFileFunction>::iterator i + for(std::vector<cmListFileFunction>::iterator i = this->Functions.begin(); i != this->Functions.end(); ++i) { @@ -161,10 +161,10 @@ bool cmListFile::ParseFile(const char* filename, { isProblem = true; break; - } + } } } - + if (isProblem) { // Tell the top level cmMakefile to diagnose @@ -181,7 +181,7 @@ bool cmListFile::ParseFile(const char* filename, { bool hasProject = false; // search for a project command - for(std::vector<cmListFileFunction>::iterator i + for(std::vector<cmListFileFunction>::iterator i = this->Functions.begin(); i != this->Functions.end(); ++i) { @@ -256,7 +256,7 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer, parenDepth--; cmListFileArgument a(")", false, filename, token->line); - function.Arguments.push_back(a); + function.Arguments.push_back(a); } else if(token->type == cmListFileLexer_Token_Identifier || token->type == cmListFileLexer_Token_ArgumentUnquoted) @@ -276,7 +276,7 @@ bool cmListFileCacheParseFunction(cmListFileLexer* lexer, // Error. cmOStringStream error; error << "Error in cmake code at\n" - << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) + << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) << ":\n" << "Parse error. Function missing ending \")\". " << "Instead found " diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index ec5886d..c057754 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -22,7 +22,7 @@ */ class cmMakefile; - + struct cmListFileArgument { cmListFileArgument(): Value(), Quoted(false), FilePath(0), Line(0) {} @@ -64,11 +64,11 @@ class cmListFileBacktrace: public std::vector<cmListFileContext> {}; struct cmListFile { - cmListFile() - :ModifiedTime(0) + cmListFile() + :ModifiedTime(0) { } - bool ParseFile(const char* path, + bool ParseFile(const char* path, bool topLevel, cmMakefile *mf); diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c index df5dc2b..b6424d6 100644 --- a/Source/cmListFileLexer.c +++ b/Source/cmListFileLexer.c @@ -43,7 +43,7 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ @@ -165,7 +165,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires * access to the local variable yy_act. Since yyless() is a macro, it would break - * existing scanners that call yyless() from OUTSIDE cmListFileLexer_yylex. + * existing scanners that call yyless() from OUTSIDE cmListFileLexer_yylex. * One obvious solution it to make yy_act a global. I tried that, and saw * a 5% performance hit in a non-yylineno scanner, because yy_act is * normally declared as a register variable-- so it is not worth it. @@ -177,7 +177,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) - + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ @@ -242,7 +242,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -834,7 +834,7 @@ yy_find_action: int yyl; for ( yyl = 0; yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) - + do{ yylineno++; yycolumn=0; }while(0) @@ -1380,7 +1380,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yyg->yy_hold_char = *++yyg->yy_c_buf_p; if ( c == '\n' ) - + do{ yylineno++; yycolumn=0; }while(0) @@ -1463,7 +1463,7 @@ static void cmListFileLexer_yy_load_buffer_state (yyscan_t yyscanner) YY_BUFFER_STATE cmListFileLexer_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + b = (YY_BUFFER_STATE) cmListFileLexer_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_yy_create_buffer()" ); @@ -1529,7 +1529,7 @@ static void cmListFileLexer_yy_load_buffer_state (yyscan_t yyscanner) } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - + errno = oerrno; } @@ -1633,9 +1633,9 @@ static void cmListFileLexer_yyensure_buffer_stack (yyscan_t yyscanner) yyg->yy_buffer_stack = (struct yy_buffer_state**)cmListFileLexer_yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); - + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; @@ -1662,12 +1662,12 @@ static void cmListFileLexer_yyensure_buffer_stack (yyscan_t yyscanner) * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ YY_BUFFER_STATE cmListFileLexer_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; - + if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) @@ -1703,7 +1703,7 @@ YY_BUFFER_STATE cmListFileLexer_yy_scan_buffer (char * base, yy_size_t size , */ YY_BUFFER_STATE cmListFileLexer_yy_scan_string (yyconst char * yy_str , yyscan_t yyscanner) { - + return cmListFileLexer_yy_scan_bytes(yy_str,strlen(yy_str) ,yyscanner); } @@ -1720,7 +1720,7 @@ YY_BUFFER_STATE cmListFileLexer_yy_scan_bytes (yyconst char * bytes, int len , char *buf; yy_size_t n; int i; - + /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; buf = (char *) cmListFileLexer_yyalloc(n ,yyscanner ); @@ -1789,10 +1789,10 @@ YY_EXTRA_TYPE cmListFileLexer_yyget_extra (yyscan_t yyscanner) int cmListFileLexer_yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - + if (! YY_CURRENT_BUFFER) return 0; - + return yylineno; } @@ -1802,10 +1802,10 @@ int cmListFileLexer_yyget_lineno (yyscan_t yyscanner) int cmListFileLexer_yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - + if (! YY_CURRENT_BUFFER) return 0; - + return yycolumn; } @@ -1866,8 +1866,8 @@ void cmListFileLexer_yyset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "cmListFileLexer_yyset_lineno called with no buffer" , yyscanner); - + yy_fatal_error( "cmListFileLexer_yyset_lineno called with no buffer" , yyscanner); + yylineno = line_number; } @@ -1881,8 +1881,8 @@ void cmListFileLexer_yyset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "cmListFileLexer_yyset_column called with no buffer" , yyscanner); - + yy_fatal_error( "cmListFileLexer_yyset_column called with no buffer" , yyscanner); + yycolumn = column_no; } diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index a239e55..462e086 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -26,7 +26,7 @@ bool cmLoadCacheCommand { return this->ReadWithPrefix(args); } - + // Cache entries to be excluded from the import list. // If this set is empty, all cache entries are brought in // and they can not be overridden. @@ -97,7 +97,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) this->SetError("READ_WITH_PREFIX form must specify a prefix."); return false; } - + // Make sure the cache file exists. std::string cacheFile = args[0]+"/CMakeCache.txt"; if(!cmSystemTools::FileExists(cacheFile.c_str())) @@ -106,22 +106,22 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) this->SetError(e.c_str()); return false; } - + // Prepare the table of variables to read. this->Prefix = args[2]; for(unsigned int i=3; i < args.size(); ++i) { this->VariablesToRead.insert(args[i]); } - + // Read the cache file. - std::ifstream fin(cacheFile.c_str()); - + std::ifstream fin(cacheFile.c_str()); + // This is a big hack read loop to overcome a buggy ifstream // implementation on HP-UX. This should work on all platforms even // for small buffer sizes. const int bufferSize = 4096; - char buffer[bufferSize]; + char buffer[bufferSize]; std::string line; while(fin) { @@ -152,7 +152,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) // Completed a line. this->CheckLine(line.c_str()); line = ""; - + // Skip the newline character. ++i; } @@ -164,7 +164,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) // Partial last line. this->CheckLine(line.c_str()); } - + return true; } diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h index ac50f8d..f55cbb3 100644 --- a/Source/cmLoadCacheCommand.h +++ b/Source/cmLoadCacheCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmLoadCacheCommand; } @@ -49,7 +49,7 @@ public: { return "Load in the values from another project's CMake cache."; } - + /** * More documentation. */ @@ -74,13 +74,13 @@ public: "of this form of the command is strongly discouraged, but it is " "provided for backward compatibility."; } - + cmTypeMacro(cmLoadCacheCommand, cmCommand); protected: - + std::set<cmStdString> VariablesToRead; std::string Prefix; - + bool ReadWithPrefix(std::vector<std::string> const& args); void CheckLine(const char* line); }; diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 3a0115c..b2acf06 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -25,23 +25,23 @@ #include <signal.h> extern "C" void TrapsForSignalsCFunction(int sig); - + // a class for loadabple commands class cmLoadedCommand : public cmCommand { public: cmLoadedCommand() { - memset(&this->info,0,sizeof(this->info)); + memset(&this->info,0,sizeof(this->info)); this->info.CAPI = &cmStaticCAPI; } - + ///! clean up any memory allocated by the plugin ~cmLoadedCommand(); - + /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { cmLoadedCommand *newC = new cmLoadedCommand; // we must copy when we clone @@ -53,7 +53,7 @@ public: * This is called when the command is first encountered in * the CMakeLists.txt file. */ - virtual bool InitialPass(std::vector<std::string> const& args, + virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &); /** @@ -70,7 +70,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const { return info.Name; } - + /** * Succinct documentation. */ @@ -79,7 +79,7 @@ public: if (this->info.GetTerseDocumentation) { cmLoadedCommand::InstallSignalHandlers(info.Name); - const char* ret = info.GetTerseDocumentation(); + const char* ret = info.GetTerseDocumentation(); cmLoadedCommand::InstallSignalHandlers(info.Name, 1); return ret; } @@ -101,7 +101,7 @@ public: { cmLoadedCommand::LastName = "????"; } - + if(!remove) { signal(SIGSEGV, TrapsForSignalsCFunction); @@ -119,7 +119,7 @@ public: signal(SIGILL, 0); } } - + /** * More documentation. */ @@ -137,7 +137,7 @@ public: return "LoadedCommand without any additional documentation"; } } - + cmTypeMacro(cmLoadedCommand, cmCommand); cmLoadedCommandInfo info; @@ -164,7 +164,7 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, { free(this->info.Error); } - + // create argc and argv and then invoke the command int argc = static_cast<int> (args.size()); char **argv = 0; @@ -179,10 +179,10 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, } cmLoadedCommand::InstallSignalHandlers(info.Name); int result = info.InitialPass((void *)&info, - (void *)this->Makefile,argc,argv); + (void *)this->Makefile,argc,argv); cmLoadedCommand::InstallSignalHandlers(info.Name, 1); cmFreeArguments(argc,argv); - + if (result) { return true; @@ -249,7 +249,7 @@ bool cmLoadCommandCommand // expand variables std::string exp = args[j]; cmSystemTools::ExpandRegistryValues(exp); - + // Glob the entry in case of wildcards. cmSystemTools::GlobDirs(exp.c_str(), path); } @@ -298,7 +298,7 @@ bool cmLoadCommandCommand initFunction = (CM_INIT_FUNCTION)( cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName.c_str())); } - // if the symbol is found call it to set the name on the + // if the symbol is found call it to set the name on the // function blocker if(initFunction) { diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h index 6517019..f0b34ee 100644 --- a/Source/cmLoadCommandCommand.h +++ b/Source/cmLoadCommandCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmLoadCommandCommand; } @@ -41,7 +41,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "load_command";} - + /** * Succinct documentation. */ @@ -49,7 +49,7 @@ public: { return "Load a command into a running CMake."; } - + /** * More documentation. */ @@ -66,7 +66,7 @@ public: "will be set to the full path of the module that was loaded. " "Otherwise the variable will not be set."; } - + cmTypeMacro(cmLoadCommandCommand, cmCommand); }; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 8265d72..4952a8c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -554,9 +554,9 @@ void cmLocalGenerator::GenerateTargetManifest() } void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, - const char* lang, - cmSourceFile& source, - cmTarget& target) + const char* lang, + cmSourceFile& source, + cmGeneratorTarget& target) { std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname)); objectDir = this->Convert(objectDir.c_str(),START_OUTPUT,SHELL); @@ -635,7 +635,8 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, ); } -void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) +void cmLocalGenerator::AddBuildTargetRule(const char* llang, + cmGeneratorTarget& target) { cmStdString objs; std::vector<std::string> objVector; @@ -669,15 +670,19 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) std::string createRule = "CMAKE_"; createRule += llang; createRule += target.GetCreateRuleVariable(); - std::string targetName = target.GetFullName(); + std::string targetName = target.Target->GetFullName(); // Executable : // Shared Library: // Static Library: // Shared Module: std::string linkLibs; // should be set + std::string frameworkPath; + std::string linkPath; std::string flags; // should be set std::string linkFlags; // should be set - this->GetTargetFlags(linkLibs, flags, linkFlags, target); + this->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags, + &target); + linkLibs = frameworkPath + linkPath + linkLibs; cmLocalGenerator::RuleVariables vars; vars.Language = llang; vars.Objects = objs.c_str(); @@ -714,7 +719,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) // Store this command line. commandLines.push_back(commandLine); } - std::string targetFullPath = target.GetFullPath(); + std::string targetFullPath = target.Target->GetFullPath(); // Generate a meaningful comment for the command. std::string comment = "Linking "; comment += llang; @@ -728,7 +733,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) comment.c_str(), this->Makefile->GetStartOutputDirectory() ); - target.AddSourceFile + target.Target->AddSourceFile (this->Makefile->GetSource(targetFullPath.c_str())); } @@ -736,11 +741,15 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) void cmLocalGenerator ::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang) { - cmTargets &tgts = this->Makefile->GetTargets(); - for(cmTargets::iterator l = tgts.begin(); + cmGeneratorTargetsType tgts = this->Makefile->GetGeneratorTargets(); + for(cmGeneratorTargetsType::iterator l = tgts.begin(); l != tgts.end(); l++) { - cmTarget& target = l->second; + if (l->first->IsImported()) + { + continue; + } + cmGeneratorTarget& target = *l->second; switch(target.GetType()) { case cmTarget::STATIC_LIBRARY: @@ -748,12 +757,12 @@ void cmLocalGenerator case cmTarget::MODULE_LIBRARY: case cmTarget::EXECUTABLE: { - const char* llang = target.GetLinkerLanguage(); + const char* llang = target.Target->GetLinkerLanguage(); if(!llang) { cmSystemTools::Error ("CMake can not determine linker language for target:", - target.GetName()); + target.Target->GetName()); return; } // if the language is not in the set lang then create custom @@ -872,6 +881,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, return replaceValues.TargetPDB; } } + if(replaceValues.DependencyFile ) + { + if(variable == "DEP_FILE") + { + return replaceValues.DependencyFile; + } + } if(replaceValues.Target) { @@ -1311,8 +1327,9 @@ std::string cmLocalGenerator::GetIncludeFlags( //---------------------------------------------------------------------------- void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, - cmTarget* target, - const char* lang) + cmGeneratorTarget* target, + const char* lang, + const char *config) { // Need to decide whether to automatically include the source and // binary directories at the beginning of the include path. @@ -1382,6 +1399,11 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, } } + if(!target) + { + return; + } + // Load implicit include directories for this language. std::string impDirVar = "CMAKE_"; impDirVar += lang; @@ -1399,10 +1421,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, // Get the target-specific include directories. std::vector<std::string> includes; - if(target) - { - includes = target->GetIncludeDirectories(); - } + + includes = target->GetIncludeDirectories(config); // Support putting all the in-project include directories first if // it is requested by the project. @@ -1442,7 +1462,9 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, std::string& flags, std::string& linkFlags, - cmTarget& target) + std::string& frameworkPath, + std::string& linkPath, + cmGeneratorTarget* target) { std::string buildType = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); @@ -1450,12 +1472,12 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library - switch(target.GetType()) + switch(target->GetType()) { case cmTarget::STATIC_LIBRARY: { const char* targetLinkFlags = - target.GetProperty("STATIC_LIBRARY_FLAGS"); + target->GetProperty("STATIC_LIBRARY_FLAGS"); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1465,7 +1487,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, { std::string build = "STATIC_LIBRARY_FLAGS_"; build += buildType; - targetLinkFlags = target.GetProperty(build.c_str()); + targetLinkFlags = target->GetProperty(build.c_str()); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1491,7 +1513,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, if(this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW"))) { - const std::vector<cmSourceFile*>& sources = target.GetSourceFiles(); + const std::vector<cmSourceFile*>& sources = target->GetSourceFiles(); for(std::vector<cmSourceFile*>::const_iterator i = sources.begin(); i != sources.end(); ++i) { @@ -1506,7 +1528,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } } } - const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); + const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1516,16 +1538,15 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, { std::string configLinkFlags = "LINK_FLAGS_"; configLinkFlags += buildType; - targetLinkFlags = target.GetProperty(configLinkFlags.c_str()); + targetLinkFlags = target->GetProperty(configLinkFlags.c_str()); if(targetLinkFlags) { linkFlags += targetLinkFlags; linkFlags += " "; } } - cmOStringStream linklibsStr; - this->OutputLinkLibraries(linklibsStr, target, false); - linkLibs = linklibsStr.str(); + this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *target, false); } break; case cmTarget::EXECUTABLE: @@ -1540,24 +1561,17 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, linkFlags += this->Makefile->GetSafeDefinition(build.c_str()); linkFlags += " "; } - const char* linkLanguage = target.GetLinkerLanguage(); + const char* linkLanguage = target->Target->GetLinkerLanguage(); if(!linkLanguage) { cmSystemTools::Error ("CMake can not determine linker language for target:", - target.GetName()); + target->Target->GetName()); return; } this->AddLanguageFlags(flags, linkLanguage, buildType.c_str()); - std::string sharedFlagsVar = "CMAKE_SHARED_LIBRARY_"; - sharedFlagsVar += linkLanguage; - sharedFlagsVar += "_FLAGS"; - flags += " "; - flags += this->Makefile->GetSafeDefinition(sharedFlagsVar.c_str()); - flags += " "; - cmOStringStream linklibs; - this->OutputLinkLibraries(linklibs, target, false); - linkLibs = linklibs.str(); + this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *target, false); if(cmSystemTools::IsOn (this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { @@ -1566,7 +1580,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, linkFlags += this->Makefile->GetSafeDefinition(sFlagVar.c_str()); linkFlags += " "; } - if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") ) + if ( target->GetPropertyAsBool("WIN32_EXECUTABLE") ) { linkFlags += this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE"); @@ -1578,7 +1592,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"); linkFlags += " "; } - if (target.IsExecutableWithExports()) + if (target->Target->IsExecutableWithExports()) { std::string exportFlagVar = "CMAKE_EXE_EXPORTS_"; exportFlagVar += linkLanguage; @@ -1588,7 +1602,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, this->Makefile->GetSafeDefinition(exportFlagVar.c_str()); linkFlags += " "; } - const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); + const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1598,7 +1612,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, { std::string configLinkFlags = "LINK_FLAGS_"; configLinkFlags += buildType; - targetLinkFlags = target.GetProperty(configLinkFlags.c_str()); + targetLinkFlags = target->GetProperty(configLinkFlags.c_str()); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1649,10 +1663,13 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib) * targetLibrary should be a NULL pointer. For libraries, it should point * to the name of the library. This will not link a library against itself. */ -void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, - cmTarget& tgt, +void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, + std::string& frameworkPath, + std::string& linkPath, + cmGeneratorTarget &tgt, bool relink) { + cmOStringStream fout; const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config); if(!pcli) @@ -1686,9 +1703,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, for(std::vector<std::string>::const_iterator fdi = fwDirs.begin(); fdi != fwDirs.end(); ++fdi) { - linkLibs += "-F"; - linkLibs += this->Convert(fdi->c_str(), NONE, SHELL, false); - linkLibs += " "; + frameworkPath = " -F"; + frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false); + frameworkPath += " "; } // Append the library search path flags. @@ -1697,10 +1714,10 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, libDir != libDirs.end(); ++libDir) { std::string libpath = this->ConvertToOutputForExisting(libDir->c_str()); - linkLibs += libPathFlag; - linkLibs += libpath; - linkLibs += libPathTerminator; - linkLibs += " "; + linkPath += " " + libPathFlag; + linkPath += libpath; + linkPath += libPathTerminator; + linkPath += " "; } // Append the link items. @@ -1772,12 +1789,14 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, { fout << stdLibs << " "; } + + linkLibraries = fout.str(); } //---------------------------------------------------------------------------- void cmLocalGenerator::AddArchitectureFlags(std::string& flags, - cmTarget* target, + cmGeneratorTarget* target, const char *lang, const char* config) { @@ -1791,46 +1810,34 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, { std::vector<std::string> archs; target->GetAppleArchs(config, archs); - const char* sysroot = - this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT"); - const char* sysrootDefault = - this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT_DEFAULT"); + const char* sysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT"); + if(sysroot && sysroot[0] == '/' && !sysroot[1]) + { sysroot = 0; } + std::string sysrootFlagVar = + std::string("CMAKE_") + lang + "_SYSROOT_FLAG"; + const char* sysrootFlag = + this->Makefile->GetDefinition(sysrootFlagVar.c_str()); const char* deploymentTarget = this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); - std::string isysrootVar = std::string("CMAKE_") + lang + "_HAS_ISYSROOT"; - bool hasIsysroot = this->Makefile->IsOn(isysrootVar.c_str()); std::string deploymentTargetFlagVar = std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG"; const char* deploymentTargetFlag = this->Makefile->GetDefinition(deploymentTargetFlagVar.c_str()); - bool flagsUsed = false; - if(!archs.empty() && sysroot && lang && (lang[0] =='C' || lang[0] == 'F')) - { - // if there is more than one arch add the -arch and - // -isysroot flags, or if there is one arch flag, but - // it is not the default -arch flag for the system, then - // add it. Otherwize do not add -arch and -isysroot - if(archs[0] != "") + if(!archs.empty() && lang && (lang[0] =='C' || lang[0] == 'F')) + { + for(std::vector<std::string>::iterator i = archs.begin(); + i != archs.end(); ++i) { - for( std::vector<std::string>::iterator i = archs.begin(); - i != archs.end(); ++i) - { - flags += " -arch "; - flags += *i; - } - if(hasIsysroot) - { - flags += " -isysroot "; - flags += sysroot; - } - flagsUsed = true; + flags += " -arch "; + flags += *i; } } - if(!flagsUsed && sysroot && sysrootDefault && - strcmp(sysroot, sysrootDefault) != 0 && hasIsysroot) + if(sysrootFlag && *sysrootFlag && sysroot && *sysroot) { - flags += " -isysroot "; + flags += " "; + flags += sysrootFlag; + flags += " "; flags += sysroot; } @@ -1963,6 +1970,111 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags, } //---------------------------------------------------------------------------- +void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target, + std::string const& lang) +{ + int targetType = target->GetType(); + + bool shared = ((targetType == cmTarget::SHARED_LIBRARY) || + (targetType == cmTarget::MODULE_LIBRARY)); + + if (this->GetShouldUseOldFlags(shared, lang)) + { + this->AddSharedFlags(flags, lang.c_str(), shared); + } + else + { + // Add position independendent flags, if needed. + if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) + { + this->AddPositionIndependentFlags(flags, lang, targetType); + } + if (shared) + { + this->AppendFeatureOptions(flags, lang.c_str(), "DLL"); + } + } +} + +//---------------------------------------------------------------------------- +bool cmLocalGenerator::GetShouldUseOldFlags(bool shared, + const std::string &lang) const +{ + std::string originalFlags = + this->GlobalGenerator->GetSharedLibFlagsForLanguage(lang); + if (shared) + { + std::string flagsVar = "CMAKE_SHARED_LIBRARY_"; + flagsVar += lang; + flagsVar += "_FLAGS"; + const char* flags = + this->Makefile->GetSafeDefinition(flagsVar.c_str()); + + if (flags && flags != originalFlags) + { + switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0018)) + { + case cmPolicies::WARN: + { + cmOStringStream e; + e << "Variable " << flagsVar << " has been modified. CMake " + "will ignore the POSITION_INDEPENDENT_CODE target property for " + "shared libraries and will use the " << flagsVar << " variable " + "instead. This may cause errors if the original content of " + << flagsVar << " was removed.\n" + << this->Makefile->GetPolicies()->GetPolicyWarning( + cmPolicies::CMP0018); + + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str()); + // fall through to OLD behaviour + } + case cmPolicies::OLD: + return true; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + default: + return false; + } + } + } + return false; +} + +//---------------------------------------------------------------------------- +void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags, + std::string const& lang, + int targetType) +{ + const char* picFlags = 0; + + if(targetType == cmTarget::EXECUTABLE) + { + std::string flagsVar = "CMAKE_"; + flagsVar += lang; + flagsVar += "_COMPILE_OPTIONS_PIE"; + picFlags = this->Makefile->GetSafeDefinition(flagsVar.c_str()); + } + if (!picFlags) + { + std::string flagsVar = "CMAKE_"; + flagsVar += lang; + flagsVar += "_COMPILE_OPTIONS_PIC"; + picFlags = this->Makefile->GetSafeDefinition(flagsVar.c_str()); + } + if (picFlags) + { + std::vector<std::string> options; + cmSystemTools::ExpandListArgument(picFlags, options); + for(std::vector<std::string>::const_iterator oi = options.begin(); + oi != options.end(); ++oi) + { + this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str()); + } + } +} + +//---------------------------------------------------------------------------- void cmLocalGenerator::AddConfigVariableFlags(std::string& flags, const char* var, const char* config) @@ -1995,9 +2107,8 @@ void cmLocalGenerator::AppendFlags(std::string& flags, } //---------------------------------------------------------------------------- -void cmLocalGenerator::AppendDefines(std::string& defines, - const char* defines_list, - const char* lang) +void cmLocalGenerator::AppendDefines(std::set<std::string>& defines, + const char* defines_list) { // Short-circuit if there are no definitions. if(!defines_list) @@ -2009,12 +2120,23 @@ void cmLocalGenerator::AppendDefines(std::string& defines, std::vector<std::string> defines_vec; cmSystemTools::ExpandListArgument(defines_list, defines_vec); - // Short-circuit if there are no definitions. - if(defines_vec.empty()) + for(std::vector<std::string>::const_iterator di = defines_vec.begin(); + di != defines_vec.end(); ++di) { - return; + // Skip unsupported definitions. + if(!this->CheckDefinition(*di)) + { + continue; + } + defines.insert(*di); } +} +//---------------------------------------------------------------------------- +void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines, + std::string &definesString, + const char* lang) +{ // Lookup the define flag for the current language. std::string dflag = "-D"; if(lang) @@ -2029,23 +2151,13 @@ void cmLocalGenerator::AppendDefines(std::string& defines, } } - // Add each definition to the command line with appropriate escapes. - const char* dsep = defines.empty()? "" : " "; - for(std::vector<std::string>::const_iterator di = defines_vec.begin(); - di != defines_vec.end(); ++di) + std::set<std::string>::const_iterator defineIt = defines.begin(); + const std::set<std::string>::const_iterator defineEnd = defines.end(); + const char* itemSeparator = definesString.empty() ? "" : " "; + for( ; defineIt != defineEnd; ++defineIt) { - // Skip unsupported definitions. - if(!this->CheckDefinition(*di)) - { - continue; - } - - // Separate from previous definitions. - defines += dsep; - dsep = " "; - // Append the definition with proper escaping. - defines += dflag; + std::string def = dflag; if(this->WatcomWMake) { // The Watcom compiler does its own command line parsing instead @@ -2058,27 +2170,30 @@ void cmLocalGenerator::AppendDefines(std::string& defines, // command line without any escapes. However we still have to // get the '$' and '#' characters through WMake as '$$' and // '$#'. - for(const char* c = di->c_str(); *c; ++c) + for(const char* c = defineIt->c_str(); *c; ++c) { if(*c == '$' || *c == '#') { - defines += '$'; + def += '$'; } - defines += *c; + def += *c; } } else { // Make the definition appear properly on the command line. Use // -DNAME="value" instead of -D"NAME=value" to help VS6 parser. - std::string::size_type eq = di->find("="); - defines += di->substr(0, eq); - if(eq != di->npos) + std::string::size_type eq = defineIt->find("="); + def += defineIt->substr(0, eq); + if(eq != defineIt->npos) { - defines += "="; - defines += this->EscapeForShell(di->c_str() + eq + 1, true); + def += "="; + def += this->EscapeForShell(defineIt->c_str() + eq + 1, true); } } + definesString += itemSeparator; + itemSeparator = " "; + definesString += def; } } @@ -2759,10 +2874,13 @@ cmLocalGenerator bool replaceExt = this->NeedBackwardsCompatibility(2, 4); if(!replaceExt) { - std::string repVar = "CMAKE_"; - repVar += source.GetLanguage(); - repVar += "_OUTPUT_EXTENSION_REPLACE"; - replaceExt = this->Makefile->IsOn(repVar.c_str()); + if(const char* lang = source.GetLanguage()) + { + std::string repVar = "CMAKE_"; + repVar += lang; + repVar += "_OUTPUT_EXTENSION_REPLACE"; + replaceExt = this->Makefile->IsOn(repVar.c_str()); + } } // Remove the source extension if it is to be replaced. diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index cb84a30..bd58218 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -16,6 +16,7 @@ class cmMakefile; class cmGlobalGenerator; +class cmGeneratorTarget; class cmTarget; class cmTargetManifest; class cmSourceFile; @@ -135,12 +136,13 @@ public: std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; }; - void AddArchitectureFlags(std::string& flags, cmTarget* target, + void AddArchitectureFlags(std::string& flags, cmGeneratorTarget* target, const char *lang, const char* config); void AddLanguageFlags(std::string& flags, const char* lang, const char* config); - void AddSharedFlags(std::string& flags, const char* lang, bool shared); + void AddCMP0018Flags(std::string &flags, cmTarget* target, + std::string const& lang); void AddConfigVariableFlags(std::string& flags, const char* var, const char* config); ///! Append flags to a string. @@ -153,8 +155,19 @@ public: * Encode a list of preprocessor definitions for the compiler * command line. */ - void AppendDefines(std::string& defines, const char* defines_list, - const char* lang); + void AppendDefines(std::set<std::string>& defines, + const char* defines_list); + void AppendDefines(std::set<std::string>& defines, + std::string defines_list) + { + this->AppendDefines(defines, defines_list.c_str()); + } + /** + * Join a set of defines into a definesString with a space separator. + */ + void JoinDefines(const std::set<std::string>& defines, + std::string &definesString, + const char* lang); /** Lookup and append options associated with a particular feature. */ void AppendFeatureOptions(std::string& flags, const char* lang, @@ -198,12 +211,16 @@ public: /** Get the include flags for the current makefile and language. */ void GetIncludeDirectories(std::vector<std::string>& dirs, - cmTarget* target, - const char* lang = "C"); + cmGeneratorTarget* target, + const char* lang = "C", const char *config = 0); /** Compute the language used to compile the given source file. */ const char* GetSourceFileLanguage(const cmSourceFile& source); + // Fill the vector with the target names for the object files, + // preprocessed files and assembly files. + virtual void GetIndividualFileTargets(std::vector<std::string>&) {} + // Create a struct to hold the varibles passed into // ExpandRuleVariables struct RuleVariables @@ -235,6 +252,7 @@ public: const char* LanguageCompileFlags; const char* Defines; const char* RuleLauncher; + const char* DependencyFile; }; /** Set whether to treat conversions to SHELL as a link script shell. */ @@ -322,11 +340,17 @@ public: void GetTargetFlags(std::string& linkLibs, std::string& flags, std::string& linkFlags, - cmTarget&target); + std::string& frameworkPath, + std::string& linkPath, + cmGeneratorTarget* target); protected: ///! put all the libraries for a target on into the given stream - virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink); + virtual void OutputLinkLibraries(std::string& linkLibraries, + std::string& frameworkPath, + std::string& linkPath, + cmGeneratorTarget &, + bool relink); // Expand rule variables in CMake of the type found in language rules void ExpandRuleVariables(std::string& string, @@ -342,12 +366,12 @@ protected: /** Convert a target to a utility target for unsupported * languages of a generator */ - void AddBuildTargetRule(const char* llang, cmTarget& target); + void AddBuildTargetRule(const char* llang, cmGeneratorTarget& target); ///! add a custom command to build a .o file that is part of a target void AddCustomCommandToCreateObject(const char* ofname, const char* lang, cmSourceFile& source, - cmTarget& target); + cmGeneratorTarget& target); // Create Custom Targets and commands for unsupported languages // The set passed in should contain the languages supported by the // generator directly. Any targets containing files that are not @@ -425,6 +449,11 @@ protected: private: std::string ConvertToOutputForExistingCommon(const char* remote, std::string const& result); + + void AddSharedFlags(std::string& flags, const char* lang, bool shared); + bool GetShouldUseOldFlags(bool shared, const std::string &lang) const; + void AddPositionIndependentFlags(std::string& flags, std::string const& l, + int targetType); }; #endif diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 425b219..d902f4e 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -46,7 +46,9 @@ void cmLocalNinjaGenerator::Generate() this->SetConfigName(); this->WriteProcessedMakefile(this->GetBuildFileStream()); +#ifdef NINJA_GEN_VERBOSE_FILES this->WriteProcessedMakefile(this->GetRulesFileStream()); +#endif this->WriteBuildFileTop(); @@ -59,7 +61,7 @@ void cmLocalNinjaGenerator::Generate() tg->Generate(); // Add the target to "all" if required. if (!this->GetGlobalNinjaGenerator()->IsExcluded( - this->GetGlobalNinjaGenerator()->LocalGenerators[0], + this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0], t->second)) this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second); delete tg; @@ -270,21 +272,21 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( // don't use POST_BUILD. if (cmdLines.empty()) #ifdef _WIN32 - return "cd."; + return "cd ."; #else return ":"; #endif - // TODO: This will work only on Unix platforms. I don't - // want to use a link.txt file because I will lose the benefit of the - // $in variables. A discussion about dealing with multiple commands in - // a rule is started here: - // groups.google.com/group/ninja-build/browse_thread/thread/d515f23a78986008 - std::ostringstream cmd; + cmOStringStream cmd; for (std::vector<std::string>::const_iterator li = cmdLines.begin(); li != cmdLines.end(); ++li) { - if (li != cmdLines.begin()) + if (li != cmdLines.begin()) { cmd << " && "; +#ifdef _WIN32 + } else if (cmdLines.size() > 1) { + cmd << "cmd.exe /c "; +#endif + } cmd << *li; } return cmd.str(); @@ -299,7 +301,7 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc, if (!wd) wd = this->GetMakefile()->GetStartOutputDirectory(); - std::ostringstream cdCmd; + cmOStringStream cdCmd; cdCmd << "cd " << this->ConvertToOutputFormat(wd, SHELL); cmdLines.push_back(cdCmd.str()); } diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index ea44b2f..c450841 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -45,7 +45,6 @@ public: /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory() virtual std::string GetTargetDirectory(cmTarget const& target) const; -public: const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; cmGlobalNinjaGenerator* GetGlobalNinjaGenerator(); @@ -67,33 +66,8 @@ public: std::string GetHomeRelativeOutputPath() const { return this->HomeRelativeOutputPath; } -protected: - virtual std::string ConvertToLinkReference(std::string const& lib); - virtual std::string ConvertToIncludeReference(std::string const& path); - -private: - friend class cmGlobalNinjaGenerator; - - // In order to access to protected member of the local generator. - friend class cmNinjaTargetGenerator; - friend class cmNinjaNormalTargetGenerator; - friend class cmNinjaUtilityTargetGenerator; - -private: - cmGeneratedFileStream& GetBuildFileStream() const; - cmGeneratedFileStream& GetRulesFileStream() const; - - void WriteBuildFileTop(); - void WriteProjectHeader(std::ostream& os); - void WriteNinjaFilesInclusion(std::ostream& os); - void WriteProcessedMakefile(std::ostream& os); - - void SetConfigName(); - std::string ConvertToNinjaPath(const char *path); - struct map_to_ninja_path; - friend struct map_to_ninja_path; struct map_to_ninja_path { cmLocalNinjaGenerator *LocalGenerator; map_to_ninja_path(cmLocalNinjaGenerator *LocalGen) @@ -102,26 +76,52 @@ private: return LocalGenerator->ConvertToNinjaPath(path.c_str()); } }; + map_to_ninja_path MapToNinjaPath() { return map_to_ninja_path(this); } + void ExpandRuleVariables(std::string& string, + const RuleVariables& replaceValues) { + cmLocalGenerator::ExpandRuleVariables(string, replaceValues); + } + + std::string BuildCommandLine(const std::vector<std::string> &cmdLines); + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); - void AppendCustomCommandDeps(const cmCustomCommand *cc, - cmNinjaDeps &ninjaDeps); - std::string BuildCommandLine(const std::vector<std::string> &cmdLines); + void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); void AppendCustomCommandLines(const cmCustomCommand *cc, std::vector<std::string> &cmdLines); + void AppendCustomCommandDeps(const cmCustomCommand *cc, + cmNinjaDeps &ninjaDeps); + + virtual std::string ConvertToLinkReference(std::string const& lib); + + +protected: + virtual std::string ConvertToIncludeReference(std::string const& path); + + +private: + cmGeneratedFileStream& GetBuildFileStream() const; + cmGeneratedFileStream& GetRulesFileStream() const; + + void WriteBuildFileTop(); + void WriteProjectHeader(std::ostream& os); + void WriteNinjaFilesInclusion(std::ostream& os); + void WriteProcessedMakefile(std::ostream& os); + + void SetConfigName(); + void WriteCustomCommandRule(); void WriteCustomCommandBuildStatement(cmCustomCommand const *cc, const cmNinjaDeps& orderOnlyDeps); - void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); void WriteCustomCommandBuildStatements(); -private: + std::string ConfigName; std::string HomeRelativeOutputPath; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index a645303..820d25a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -36,6 +36,30 @@ #include <queue> //---------------------------------------------------------------------------- +// Escape special characters in Makefile dependency lines +class cmMakeSafe +{ +public: + cmMakeSafe(const char* s): Data(s) {} + cmMakeSafe(std::string const& s): Data(s.c_str()) {} +private: + const char* Data; + friend std::ostream& operator<<(std::ostream& os, + cmMakeSafe const& self) + { + for(const char* c = self.Data; *c; ++c) + { + switch (*c) + { + case '=': os << "$(EQUALS)"; break; + default: os << *c; break; + } + } + return os; + } +}; + +//---------------------------------------------------------------------------- // Helper function used below. static std::string cmSplitExtension(std::string const& in, std::string& base) { @@ -555,28 +579,13 @@ cmLocalUnixMakefileGenerator3 space = " "; } - // Warn about paths not supported by Make tools. - std::string::size_type pos = tgt.find_first_of("="); - if(pos != std::string::npos) - { - cmOStringStream m; - m << - "Make rule for\n" - " " << tgt << "\n" - "has '=' on left hand side. " - "The make tool may not support this."; - cmListFileBacktrace bt; - this->GlobalGenerator->GetCMakeInstance() - ->IssueMessage(cmake::WARNING, m.str(), bt); - } - // Mark the rule as symbolic if requested. if(symbolic) { if(const char* sym = this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) { - os << tgt.c_str() << space << ": " << sym << "\n"; + os << cmMakeSafe(tgt) << space << ": " << sym << "\n"; } } @@ -584,7 +593,7 @@ cmLocalUnixMakefileGenerator3 if(depends.empty()) { // No dependencies. The commands will always run. - os << tgt.c_str() << space << ":\n"; + os << cmMakeSafe(tgt) << space << ":\n"; } else { @@ -595,7 +604,7 @@ cmLocalUnixMakefileGenerator3 { replace = *dep; replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE); - os << tgt.c_str() << space << ": " << replace.c_str() << "\n"; + os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n"; } } @@ -608,7 +617,7 @@ cmLocalUnixMakefileGenerator3 } if(symbolic && !this->WatcomWMake) { - os << ".PHONY : " << tgt.c_str() << "\n"; + os << ".PHONY : " << cmMakeSafe(tgt) << "\n"; } os << "\n"; // Add the output to the local help if requested. @@ -687,6 +696,10 @@ cmLocalUnixMakefileGenerator3 << this->ConvertShellCommand(cmakecommand, FULL) << " -E remove -f\n" << "\n"; + makefileStream + << "# Escaping for special characters.\n" + << "EQUALS = =\n" + << "\n"; if(const char* edit_cmd = this->Makefile->GetDefinition("CMAKE_EDIT_COMMAND")) @@ -1926,8 +1939,12 @@ void cmLocalUnixMakefileGenerator3 for(ImplicitDependFileMap::const_iterator pi = implicitPairs.begin(); pi != implicitPairs.end(); ++pi) { - cmakefileStream << " \"" << pi->second << "\" "; - cmakefileStream << "\"" << pi->first << "\"\n"; + for(cmDepends::DependencyVector::const_iterator di = pi->second.begin(); + di != pi->second.end(); ++ di) + { + cmakefileStream << " \"" << *di << "\" "; + cmakefileStream << "\"" << pi->first << "\"\n"; + } } cmakefileStream << " )\n"; @@ -2191,7 +2208,7 @@ cmLocalUnixMakefileGenerator3::AddImplicitDepends(cmTarget const& tgt, const char* obj, const char* src) { - this->ImplicitDepends[tgt.GetName()][lang][obj] = src; + this->ImplicitDepends[tgt.GetName()][lang][obj].push_back(src); } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index e374959..703369e 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -209,7 +209,8 @@ public: // File pairs for implicit dependency scanning. The key of the map // is the depender and the value is the explicit dependee. - struct ImplicitDependFileMap: public std::map<cmStdString, cmStdString> {}; + struct ImplicitDependFileMap: + public std::map<cmStdString, cmDepends::DependencyVector> {}; struct ImplicitDependLanguageMap: public std::map<cmStdString, ImplicitDependFileMap> {}; struct ImplicitDependTargetMap: diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index ace7adf..c3789a0 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -21,9 +21,9 @@ class cmVS10XMLParser : public cmXMLParser public: virtual void EndElement(const char* /* name */) { - } + } virtual void CharacterDataHandler(const char* data, int length) - { + { if(this->DoGUID ) { this->GUID.assign(data+1, length-2); @@ -40,7 +40,7 @@ class cmVS10XMLParser : public cmXMLParser if(strcmp("ProjectGUID", name) == 0 || strcmp("ProjectGuid", name) == 0) { this->DoGUID = true; - } + } } int InitializeParser() { @@ -50,7 +50,7 @@ class cmVS10XMLParser : public cmXMLParser { return ret; } - // visual studio projects have a strange encoding, but it is + // visual studio projects have a strange encoding, but it is // really utf-8 XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8"); return 1; @@ -72,7 +72,7 @@ cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator() void cmLocalVisualStudio10Generator::Generate() { - + cmTargets &tgts = this->Makefile->GetTargets(); for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l) { @@ -98,7 +98,7 @@ void cmLocalVisualStudio10Generator const char* path) { cmVS10XMLParser parser; - parser.ParseFile(path); + parser.ParseFile(path); // if we can not find a GUID then create one if(parser.GUID.empty()) diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h index 699de4c..41db735 100644 --- a/Source/cmLocalVisualStudio10Generator.h +++ b/Source/cmLocalVisualStudio10Generator.h @@ -31,7 +31,7 @@ public: /** - * Generate the makefile for this directory. + * Generate the makefile for this directory. */ virtual void Generate(); virtual void ReadAndStoreExternalGUID(const char* name, diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 5ab223b..f15322b 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -108,7 +108,7 @@ void cmLocalVisualStudio6Generator::Generate() } void cmLocalVisualStudio6Generator::OutputDSPFile() -{ +{ // If not an in source build, then create the output directory if(strcmp(this->Makefile->GetStartOutputDirectory(), this->Makefile->GetHomeDirectory()) != 0) @@ -126,7 +126,7 @@ void cmLocalVisualStudio6Generator::OutputDSPFile() cmTargets &tgts = this->Makefile->GetTargets(); // build any targets - for(cmTargets::iterator l = tgts.begin(); + for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { switch(l->second.GetType()) @@ -152,7 +152,7 @@ void cmLocalVisualStudio6Generator::OutputDSPFile() } // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace // so don't build a projectfile for it - const char* path = + const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT"); if(!path) { @@ -178,7 +178,7 @@ void cmLocalVisualStudio6Generator::OutputDSPFile() // extern std::string GetVS6TargetName(const std::string& targetName); -void cmLocalVisualStudio6Generator::CreateSingleDSP(const char *lname, +void cmLocalVisualStudio6Generator::CreateSingleDSP(const char *lname, cmTarget &target) { // add to the list of projects @@ -210,7 +210,7 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt) { std::string dspname = GetVS6TargetName(tgt.GetName()); dspname += ".dsp.cmake"; - const char* dsprule = + const char* dsprule = this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"); cmCustomCommandLine commandLine; commandLine.push_back(dsprule); @@ -229,8 +229,8 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt) START_OUTPUT, UNCHANGED, true); commandLine.push_back(args); args = "-B"; - args += - this->Convert(this->Makefile->GetHomeOutputDirectory(), + args += + this->Convert(this->Makefile->GetHomeOutputDirectory(), START_OUTPUT, UNCHANGED, true); commandLine.push_back(args); @@ -254,7 +254,7 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt) } -void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, +void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, const char *libName, cmTarget &target) { @@ -301,21 +301,21 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, this->AddUtilityCommandHack(target, count++, depends, *cr); } } - + // We may be modifying the source groups temporarily, so make a copy. std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); - + // get the classes from the source lists then add them to the groups std::vector<cmSourceFile*> const & classes = target.GetSourceFiles(); // now all of the source files have been properly assigned to the target // now stick them into source groups using the reg expressions - for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); + for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); i != classes.end(); i++) { // Add the file to the list of sources. std::string source = (*i)->GetFullPath(); - cmSourceGroup& sourceGroup = + cmSourceGroup& sourceGroup = this->Makefile->FindSourceGroup(source.c_str(), sourceGroups); sourceGroup.AssignSource(*i); // while we are at it, if it is a .rule file then for visual studio 6 we @@ -326,11 +326,11 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, { cmSystemTools::ReplaceString(source, "$(IntDir)/", ""); #if defined(_WIN32) || defined(__CYGWIN__) - std::ofstream fout(source.c_str(), - std::ios::binary | std::ios::out + std::ofstream fout(source.c_str(), + std::ios::binary | std::ios::out | std::ios::trunc); #else - std::ofstream fout(source.c_str(), + std::ofstream fout(source.c_str(), std::ios::out | std::ios::trunc); #endif if(fout) @@ -345,14 +345,14 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, // Write the DSP file's header. this->WriteDSPHeader(fout, libName, target, sourceGroups); - + // Loop through every source group. for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin(); sg != sourceGroups.end(); ++sg) { this->WriteGroup(&(*sg), target, fout, libName); - } + } // Write the DSP file's footer. this->WriteDSPFooter(fout); @@ -364,15 +364,15 @@ void cmLocalVisualStudio6Generator { cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(&target); - const std::vector<const cmSourceFile *> &sourceFiles = + const std::vector<const cmSourceFile *> &sourceFiles = sg->GetSourceFiles(); // If the group is empty, don't write it at all. - + if(sourceFiles.empty() && sg->GetGroupChildren().empty()) - { - return; + { + return; } - + // If the group has a name, write the header. std::string name = sg->GetName(); if(name != "") @@ -385,7 +385,7 @@ void cmLocalVisualStudio6Generator sourceFiles.begin(); sf != sourceFiles.end(); ++sf) { std::string source = (*sf)->GetFullPath(); - const cmCustomCommand *command = + const cmCustomCommand *command = (*sf)->GetCustomCommand(); std::string compileFlags; std::vector<std::string> depends; @@ -418,30 +418,47 @@ void cmLocalVisualStudio6Generator // Add per-source and per-configuration preprocessor definitions. std::map<cmStdString, cmStdString> cdmap; - this->AppendDefines(compileFlags, - (*sf)->GetProperty("COMPILE_DEFINITIONS"), lang); + + { + std::set<std::string> targetCompileDefinitions; + + this->AppendDefines(targetCompileDefinitions, + (*sf)->GetProperty("COMPILE_DEFINITIONS")); + this->JoinDefines(targetCompileDefinitions, compileFlags, lang); + } + if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_DEBUG")) { - this->AppendDefines(cdmap["DEBUG"], cdefs, lang); + std::set<std::string> debugCompileDefinitions; + this->AppendDefines(debugCompileDefinitions, cdefs); + this->JoinDefines(debugCompileDefinitions, cdmap["DEBUG"], lang); } if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_RELEASE")) { - this->AppendDefines(cdmap["RELEASE"], cdefs, lang); + std::set<std::string> releaseCompileDefinitions; + this->AppendDefines(releaseCompileDefinitions, cdefs); + this->JoinDefines(releaseCompileDefinitions, cdmap["RELEASE"], lang); } if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL")) { - this->AppendDefines(cdmap["MINSIZEREL"], cdefs, lang); + std::set<std::string> minsizerelCompileDefinitions; + this->AppendDefines(minsizerelCompileDefinitions, cdefs); + this->JoinDefines(minsizerelCompileDefinitions, cdmap["MINSIZEREL"], + lang); } if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO")) { - this->AppendDefines(cdmap["RELWITHDEBINFO"], cdefs, lang); + std::set<std::string> relwithdebinfoCompileDefinitions; + this->AppendDefines(relwithdebinfoCompileDefinitions, cdefs); + this->JoinDefines(relwithdebinfoCompileDefinitions, + cdmap["RELWITHDEBINFO"], lang); } bool excludedFromBuild = (lang && (*sf)->GetPropertyAsBool("HEADER_FILE_ONLY")); - + // Check for extra object-file dependencies. const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS"); if(dependsValue) @@ -453,10 +470,10 @@ void cmLocalVisualStudio6Generator target.GetType() == cmTarget::GLOBAL_TARGET) { fout << "# Begin Source File\n\n"; - + // Tell MS-Dev what the source is. If the compiler knows how to // build it, then it will. - fout << "SOURCE=" << + fout << "SOURCE=" << this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n"; if(!depends.empty()) { @@ -464,8 +481,8 @@ void cmLocalVisualStudio6Generator fout << "USERDEP__HACK="; for(std::vector<std::string>::const_iterator d = depends.begin(); d != depends.end(); ++d) - { - fout << "\\\n\t" << + { + fout << "\\\n\t" << this->ConvertToOptionallyRelativeOutputPath(d->c_str()); } fout << "\n"; @@ -479,16 +496,16 @@ void cmLocalVisualStudio6Generator excludedFromBuild || !cdmap.empty()) { for(std::vector<std::string>::iterator i - = this->Configurations.begin(); + = this->Configurations.begin(); i != this->Configurations.end(); ++i) - { + { // Strip the subdirectory name out of the configuration name. std::string config = this->GetConfigName(*i); if (i == this->Configurations.begin()) { fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl; } - else + else { fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl; } @@ -512,7 +529,7 @@ void cmLocalVisualStudio6Generator fout << "\n# PROP Intermediate_Dir \"" << config << "/" << objectNameDir << "\"\n\n"; } - } + } fout << "!ENDIF\n\n"; } fout << "# End Source File\n"; @@ -528,7 +545,7 @@ void cmLocalVisualStudio6Generator - + // If the group has a name, write the footer. if(name != "") { @@ -586,7 +603,7 @@ cmLocalVisualStudio6Generator { comment = ""; } - + // Write the rule for each configuration. std::vector<std::string>::iterator i; for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i) @@ -594,12 +611,12 @@ cmLocalVisualStudio6Generator std::string config = this->GetConfigName(*i); std::string script = this->ConstructScript(command, config.c_str(), "\\\n\t"); - + if (i == this->Configurations.begin()) { fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl; } - else + else { fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl; } @@ -609,9 +626,9 @@ cmLocalVisualStudio6Generator } // Write out the dependencies for the rule. fout << "USERDEP__HACK="; - for(std::vector<std::string>::const_iterator d = + for(std::vector<std::string>::const_iterator d = command.GetDepends().begin(); - d != command.GetDepends().end(); + d != command.GetDepends().end(); ++d) { // Lookup the real name of the dependency in case it is a CMake target. @@ -633,15 +650,15 @@ cmLocalVisualStudio6Generator fout << "\n\n"; if(command.GetOutputs().empty()) { - fout << source + fout << source << "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t"; fout << script.c_str() << "\n\n"; } else { - for(std::vector<std::string>::const_iterator o = + for(std::vector<std::string>::const_iterator o = command.GetOutputs().begin(); - o != command.GetOutputs().end(); + o != command.GetOutputs().end(); ++o) { // Write a rule for every output generated by this command. @@ -652,12 +669,12 @@ cmLocalVisualStudio6Generator } fout << "# End Custom Build\n\n"; } - + fout << "!ENDIF\n\n"; } -void cmLocalVisualStudio6Generator::WriteDSPBeginGroup(std::ostream& fout, +void cmLocalVisualStudio6Generator::WriteDSPBeginGroup(std::ostream& fout, const char* group, const char* filter) { @@ -679,7 +696,7 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b, cmTarget& target) { std::string root= this->Makefile->GetRequiredDefinition("CMAKE_ROOT"); - const char *def= + const char *def= this->Makefile->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY"); if( def) @@ -690,7 +707,7 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b, { root += "/Templates"; } - + switch(b) { case STATIC_LIBRARY: @@ -740,7 +757,7 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b, } // reset this->Configurations - this->Configurations.erase(this->Configurations.begin(), + this->Configurations.erase(this->Configurations.begin(), this->Configurations.end()); // now add all the configurations possible @@ -785,9 +802,9 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target, } // look for custom rules on a target and collect them together -std::string -cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target, - const char* configName, +std::string +cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target, + const char* configName, const char * /* libName */) { if (target.GetType() >= cmTarget::UTILITY ) @@ -836,7 +853,8 @@ inline std::string removeQuotes(const std::string& s) std::string -cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target) +cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target, + const char *config) { std::string includeOptions; @@ -845,10 +863,13 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target) // the length threatens this problem. unsigned int maxIncludeLength = 3000; bool useShortPath = false; + + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); for(int j=0; j < 2; ++j) { std::vector<std::string> includes; - this->GetIncludeDirectories(includes, &target); + this->GetIncludeDirectories(includes, gt, "C", config); std::vector<std::string>::iterator i; for(i = includes.begin(); i != includes.end(); ++i) @@ -895,8 +916,8 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target) #define CM_USE_OLD_VS6 void cmLocalVisualStudio6Generator -::WriteDSPHeader(std::ostream& fout, - const char *libName, cmTarget &target, +::WriteDSPHeader(std::ostream& fout, + const char *libName, cmTarget &target, std::vector<cmSourceGroup> &) { bool targetBuilds = (target.GetType() >= cmTarget::EXECUTABLE && @@ -931,7 +952,7 @@ void cmLocalVisualStudio6Generator } std::set<std::string> pathEmitted; - + // determine the link directories std::string libOptions; std::string libDebugOptions; @@ -944,14 +965,14 @@ void cmLocalVisualStudio6Generator if(libPath.size()) { - std::string lpath = + std::string lpath = this->ConvertToOptionallyRelativeOutputPath(libPath.c_str()); if(lpath.size() == 0) { lpath = "."; } std::string lpathIntDir = libPath + "$(INTDIR)"; - lpathIntDir = + lpathIntDir = this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); if(pathEmitted.insert(lpath).second) { @@ -977,7 +998,7 @@ void cmLocalVisualStudio6Generator } if(exePath.size()) { - std::string lpath = + std::string lpath = this->ConvertToOptionallyRelativeOutputPath(exePath.c_str()); if(lpath.size() == 0) { @@ -986,7 +1007,7 @@ void cmLocalVisualStudio6Generator std::string lpathIntDir = exePath + "$(INTDIR)"; lpathIntDir = this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str()); - + if(pathEmitted.insert(lpath).second) { libOptions += " /LIBPATH:"; @@ -1018,7 +1039,7 @@ void cmLocalVisualStudio6Generator { path += "/"; } - std::string lpath = + std::string lpath = this->ConvertToOptionallyRelativeOutputPath(path.c_str()); if(lpath.size() == 0) { @@ -1035,7 +1056,7 @@ void cmLocalVisualStudio6Generator libOptions += " /LIBPATH:"; libOptions += lpath; libOptions += " "; - + libMultiLineOptions += "# ADD LINK32 /LIBPATH:"; libMultiLineOptions += lpathIntDir; libMultiLineOptions += " "; @@ -1059,8 +1080,8 @@ void cmLocalVisualStudio6Generator // a library in a library, bad recursion) // NEVER LINK STATIC LIBRARIES TO OTHER STATIC LIBRARIES if ((target.GetType() != cmTarget::SHARED_LIBRARY - && target.GetType() != cmTarget::STATIC_LIBRARY - && target.GetType() != cmTarget::MODULE_LIBRARY) || + && target.GetType() != cmTarget::STATIC_LIBRARY + && target.GetType() != cmTarget::MODULE_LIBRARY) || (target.GetType()==cmTarget::SHARED_LIBRARY && libName != GetVS6TargetName(j->first)) || (target.GetType()==cmTarget::MODULE_LIBRARY @@ -1090,7 +1111,7 @@ void cmLocalVisualStudio6Generator } } lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str()); - libDebug = + libDebug = this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str()); if (j->second == cmTarget::GENERAL) @@ -1121,13 +1142,21 @@ void cmLocalVisualStudio6Generator libMultiLineOptimizedOptions += "# ADD LINK32 "; libMultiLineOptimizedOptions += lib; libMultiLineOptimizedOptions += "\n"; - } + } } } #endif // Get include options for this target. - std::string includeOptions = this->GetTargetIncludeOptions(target); + std::string includeOptionsDebug = this->GetTargetIncludeOptions(target, + "DEBUG"); + std::string includeOptionsRelease = this->GetTargetIncludeOptions(target, + "RELEASE"); + std::string includeOptionsRelWithDebInfo = this->GetTargetIncludeOptions( + target, + "RELWITHDEBINFO"); + std::string includeOptionsMinSizeRel = this->GetTargetIncludeOptions(target, + "MINSIZEREL"); // Get extra linker options for this target type. std::string extraLinkOptions; @@ -1137,17 +1166,17 @@ void cmLocalVisualStudio6Generator std::string extraLinkOptionsRelWithDebInfo; if(target.GetType() == cmTarget::EXECUTABLE) { - extraLinkOptions = + extraLinkOptions = this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS"); } if(target.GetType() == cmTarget::SHARED_LIBRARY) { - extraLinkOptions = + extraLinkOptions = this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS"); } if(target.GetType() == cmTarget::MODULE_LIBRARY) { - extraLinkOptions = + extraLinkOptions = this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS"); } @@ -1229,7 +1258,7 @@ void cmLocalVisualStudio6Generator } // Compute the real name of the target. - std::string outputName = + std::string outputName = "(OUTPUT_NAME is for libraries and executables only)"; std::string outputNameDebug = outputName; std::string outputNameRelease = outputName; @@ -1380,13 +1409,13 @@ void cmLocalVisualStudio6Generator // are there any custom rules on the target itself // only if the target is a lib or exe - std::string customRuleCodeRelease + std::string customRuleCodeRelease = this->CreateTargetRules(target, "RELEASE", libName); - std::string customRuleCodeDebug + std::string customRuleCodeDebug = this->CreateTargetRules(target, "DEBUG", libName); - std::string customRuleCodeMinSizeRel + std::string customRuleCodeMinSizeRel = this->CreateTargetRules(target, "MINSIZEREL", libName); - std::string customRuleCodeRelWithDebInfo + std::string customRuleCodeRelWithDebInfo = this->CreateTargetRules(target, "RELWITHDEBINFO", libName); std::ifstream fin(this->DSPHeaderTemplate.c_str()); @@ -1400,7 +1429,7 @@ void cmLocalVisualStudio6Generator std::string staticLibOptionsMinSizeRel; std::string staticLibOptionsRelWithDebInfo; if(target.GetType() == cmTarget::STATIC_LIBRARY ) - { + { if(const char* libflags = target.GetProperty("STATIC_LIBRARY_FLAGS")) { staticLibOptions = libflags; @@ -1484,7 +1513,7 @@ void cmLocalVisualStudio6Generator staticLibOptionsRelWithDebInfo.c_str()); cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS", staticLibOptions.c_str()); - } + } if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) { cmSystemTools::ReplaceString(line, "/nologo", ""); @@ -1506,8 +1535,8 @@ void cmLocalVisualStudio6Generator cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES", libMultiLineOptimizedOptions.c_str()); #endif - - // Substitute the rules for custom command. When specifying just the + + // Substitute the rules for custom command. When specifying just the // target name for the command the command can be different for // different configs cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELEASE", @@ -1520,28 +1549,35 @@ void cmLocalVisualStudio6Generator customRuleCodeRelWithDebInfo.c_str()); // Substitute the real output name into the template. - cmSystemTools::ReplaceString(line, "OUTPUT_NAME_DEBUG", + cmSystemTools::ReplaceString(line, "OUTPUT_NAME_DEBUG", outputNameDebug.c_str()); - cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELEASE", + cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELEASE", outputNameRelease.c_str()); cmSystemTools::ReplaceString(line, "OUTPUT_NAME_MINSIZEREL", outputNameMinSizeRel.c_str()); - cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELWITHDEBINFO", + cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELWITHDEBINFO", outputNameRelWithDebInfo.c_str()); cmSystemTools::ReplaceString(line, "OUTPUT_NAME", outputName.c_str()); // Substitute the proper link information into the template. - cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_DEBUG", + cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_DEBUG", optionsDebug.c_str()); - cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELEASE", + cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELEASE", optionsRelease.c_str()); cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_MINSIZEREL", optionsMinSizeRel.c_str()); - cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELWITHDEBINFO", + cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELWITHDEBINFO", optionsRelWithDebInfo.c_str()); - cmSystemTools::ReplaceString(line, "BUILD_INCLUDES", - includeOptions.c_str()); + cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_DEBUG", + includeOptionsDebug.c_str()); + cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_RELEASE", + includeOptionsRelease.c_str()); + cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_MINSIZEREL", + includeOptionsMinSizeRel.c_str()); + cmSystemTools::ReplaceString(line, "BUILD_INCLUDES_RELWITHDEBINFO", + includeOptionsRelWithDebInfo.c_str()); + cmSystemTools::ReplaceString(line, "TARGET_VERSION_FLAG", targetVersionFlag.c_str()); cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_DEBUG", @@ -1588,12 +1624,12 @@ void cmLocalVisualStudio6Generator } } - cmSystemTools::ReplaceString(line, - "EXTRA_DEFINES", + cmSystemTools::ReplaceString(line, + "EXTRA_DEFINES", this->Makefile->GetDefineFlags()); const char* debugPostfix = this->Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX"); - cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX", + cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX", debugPostfix?debugPostfix:""); // store flags for each configuration std::string flags = " "; @@ -1601,7 +1637,7 @@ void cmLocalVisualStudio6Generator std::string flagsMinSize = " "; std::string flagsDebug = " "; std::string flagsDebugRel = " "; - if(target.GetType() >= cmTarget::EXECUTABLE && + if(target.GetType() >= cmTarget::EXECUTABLE && target.GetType() <= cmTarget::OBJECT_LIBRARY) { const char* linkLanguage = target.GetLinkerLanguage(); @@ -1617,7 +1653,7 @@ void cmLocalVisualStudio6Generator baseFlagVar += linkLanguage; baseFlagVar += "_FLAGS"; flags = this->Makefile->GetSafeDefinition(baseFlagVar.c_str()); - + std::string flagVar = baseFlagVar + "_RELEASE"; flagsRelease = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" "; @@ -1653,70 +1689,71 @@ void cmLocalVisualStudio6Generator } // Add per-target and per-configuration preprocessor definitions. - std::string defines = " "; - std::string debugDefines = " "; - std::string releaseDefines = " "; - std::string minsizeDefines = " "; - std::string debugrelDefines = " "; + std::set<std::string> definesSet; + std::set<std::string> debugDefinesSet; + std::set<std::string> releaseDefinesSet; + std::set<std::string> minsizeDefinesSet; + std::set<std::string> debugrelDefinesSet; - this->AppendDefines( - defines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS"), 0); - this->AppendDefines( - debugDefines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_DEBUG"),0); - this->AppendDefines( - releaseDefines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_RELEASE"), 0); - this->AppendDefines( - minsizeDefines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"), 0); - this->AppendDefines( - debugrelDefines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"), 0); + + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); this->AppendDefines( - defines, - target.GetProperty("COMPILE_DEFINITIONS"), 0); + definesSet, + gt->GetCompileDefinitions()); this->AppendDefines( - debugDefines, - target.GetProperty("COMPILE_DEFINITIONS_DEBUG"), 0); + debugDefinesSet, + gt->GetCompileDefinitions("DEBUG")); this->AppendDefines( - releaseDefines, - target.GetProperty("COMPILE_DEFINITIONS_RELEASE"), 0); + releaseDefinesSet, + gt->GetCompileDefinitions("RELEASE")); this->AppendDefines( - minsizeDefines, - target.GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"), 0); + minsizeDefinesSet, + gt->GetCompileDefinitions("MINSIZEREL")); this->AppendDefines( - debugrelDefines, - target.GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"), 0); + debugrelDefinesSet, + gt->GetCompileDefinitions("RELWITHDEBINFO")); + + std::string defines = " "; + std::string debugDefines = " "; + std::string releaseDefines = " "; + std::string minsizeDefines = " "; + std::string debugrelDefines = " "; + + this->JoinDefines(definesSet, defines, 0); + this->JoinDefines(debugDefinesSet, debugDefines, 0); + this->JoinDefines(releaseDefinesSet, releaseDefines, 0); + this->JoinDefines(minsizeDefinesSet, minsizeDefines, 0); + this->JoinDefines(debugrelDefinesSet, debugrelDefines, 0); + flags += defines; flagsDebug += debugDefines; flagsRelease += releaseDefines; flagsMinSize += minsizeDefines; flagsDebugRel += debugrelDefines; - + // The template files have CXX FLAGS in them, that need to be replaced. // There are not separate CXX and C template files, so we use the same // variable names. The previous code sets up flags* variables to contain // the correct C or CXX flags cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", flagsMinSize.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", flagsDebug.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO", + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO", flagsDebugRel.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE", + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE", flagsRelease.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str()); cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL", minsizeDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG", + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG", debugDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO", + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO", debugrelDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE", + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE", releaseDefines.c_str()); cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS", defines.c_str()); @@ -1725,7 +1762,7 @@ void cmLocalVisualStudio6Generator } void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout) -{ +{ std::ifstream fin(this->DSPFooterTemplate.c_str()); if(!fin) { @@ -1746,8 +1783,10 @@ void cmLocalVisualStudio6Generator const std::string extraOptions, std::string& options) { + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); // Compute the link information for this configuration. - cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); if(!pcli) { return; diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h index 1decc35..f45bc17 100644 --- a/Source/cmLocalVisualStudio6Generator.h +++ b/Source/cmLocalVisualStudio6Generator.h @@ -37,7 +37,7 @@ public: virtual void AddCMakeListsRules(); /** - * Generate the makefile for this directory. + * Generate the makefile for this directory. */ virtual void Generate(); @@ -57,9 +57,9 @@ private: std::string DSPFooterTemplate; void CreateSingleDSP(const char *lname, cmTarget &tgt); - void WriteDSPFile(std::ostream& fout, const char *libName, + void WriteDSPFile(std::ostream& fout, const char *libName, cmTarget &tgt); - void WriteDSPBeginGroup(std::ostream& fout, + void WriteDSPBeginGroup(std::ostream& fout, const char* group, const char* filter); void WriteDSPEndGroup(std::ostream& fout); @@ -82,15 +82,15 @@ private: friend class EventWriter; cmsys::auto_ptr<cmCustomCommand> MaybeCreateOutputDir(cmTarget& target, const char* config); - std::string CreateTargetRules(cmTarget &target, - const char* configName, + std::string CreateTargetRules(cmTarget &target, + const char* configName, const char *libName); void ComputeLinkOptions(cmTarget& target, const char* configName, const std::string extraOptions, std::string& options); void OutputObjects(cmTarget& target, const char* tool, std::string& options); - std::string GetTargetIncludeOptions(cmTarget &target); + std::string GetTargetIncludeOptions(cmTarget &target, const char *config); std::vector<std::string> Configurations; std::string GetConfigName(std::string const& configuration) const; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 9faf46d..f9a2d32 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -291,7 +291,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() comment += makefileIn; std::string args; args = "-H"; - args += this->Convert(this->Makefile->GetHomeDirectory(), + args += this->Convert(this->Makefile->GetHomeDirectory(), START_OUTPUT, UNCHANGED, true); commandLine.push_back(args); args = "-B"; @@ -343,8 +343,8 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout, fout << "\t</Configurations>\n"; } cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = -{ - {"Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0}, +{ + {"Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0}, {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0}, {"SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0}, {"SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0}, @@ -376,15 +376,15 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = {"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0}, {"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0}, - {"ModulePath", "module:", "", "", + {"ModulePath", "module:", "", "", cmVS7FlagTable::UserValueRequired}, - {"LoopUnrolling", "Qunroll:", "", "", + {"LoopUnrolling", "Qunroll:", "", "", cmVS7FlagTable::UserValueRequired}, - {"AutoParallelThreshold", "Qpar-threshold:", "", "", + {"AutoParallelThreshold", "Qpar-threshold:", "", "", cmVS7FlagTable::UserValueRequired}, - {"HeapArrays", "heap-arrays:", "", "", + {"HeapArrays", "heap-arrays:", "", "", cmVS7FlagTable::UserValueRequired}, - {"ObjectText", "bintext:", "", "", + {"ObjectText", "bintext:", "", "", cmVS7FlagTable::UserValueRequired}, {"Parallelization", "Qparallel", "", "true", 0}, {"PrefetchInsertion", "Qprefetch-", "", "false", 0}, @@ -476,7 +476,7 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = // boolean flags {"BufferSecurityCheck", "GS", "Buffer security check", "TRUE", 0}, {"BufferSecurityCheck", "GS-", "Turn off Buffer security check", "FALSE", 0}, - {"Detect64BitPortabilityProblems", "Wp64", + {"Detect64BitPortabilityProblems", "Wp64", "Detect 64-bit Portability Problems", "TRUE", 0}, {"EnableFiberSafeOptimizations", "GT", "Enable Fiber-safe Optimizations", "TRUE", 0}, @@ -566,7 +566,7 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {"TurnOffAssemblyGeneration", "NOASSEMBLY", "No assembly even if CLR information is present in objects.", "true", 0}, {"ModuleDefinitionFile", "DEF:", "add an export def file", "", - cmVS7FlagTable::UserValue}, + cmVS7FlagTable::UserValue}, {"GenerateMapFile", "MAP", "enable generation of map file", "TRUE", 0}, {0,0,0,0,0} }; @@ -724,10 +724,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, flags += targetFlags; } - std::string configUpper = cmSystemTools::UpperCase(configName); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += configUpper; - // Get preprocessor definitions for this directory. std::string defineFlags = this->Makefile->GetDefineFlags(); Options::Tool t = Options::Compiler; @@ -744,11 +740,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.Parse(flags.c_str()); targetOptions.Parse(defineFlags.c_str()); targetOptions.ParseFinish(); - targetOptions.AddDefines - (this->Makefile->GetProperty("COMPILE_DEFINITIONS")); - targetOptions.AddDefines(target.GetProperty("COMPILE_DEFINITIONS")); - targetOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str())); - targetOptions.AddDefines(target.GetProperty(defPropName.c_str())); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + targetOptions.AddDefines(gt->GetCompileDefinitions().c_str()); + targetOptions.AddDefines(gt->GetCompileDefinitions(configName).c_str()); targetOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); @@ -800,7 +795,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, if(this->FortranProject) { const char* target_mod_dir = - target.GetProperty("Fortran_MODULE_DIRECTORY"); + target.GetProperty("Fortran_MODULE_DIRECTORY"); std::string modDir; if(target_mod_dir) { @@ -812,21 +807,21 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, { modDir = "."; } - fout << "\t\t\t\tModulePath=\"" + fout << "\t\t\t\tModulePath=\"" << this->ConvertToXMLOutputPath(modDir.c_str()) << "\\$(ConfigurationName)\"\n"; } targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n"); fout << "\t\t\t\tAdditionalIncludeDirectories=\""; std::vector<std::string> includes; - this->GetIncludeDirectories(includes, &target); + this->GetIncludeDirectories(includes, gt, "C", configName); std::vector<std::string>::iterator i = includes.begin(); for(;i != includes.end(); ++i) { // output the include path std::string ipath = this->ConvertToXMLOutputPath(i->c_str()); fout << ipath << ";"; - // if this is fortran then output the include with + // if this is fortran then output the include with // a ConfigurationName on the end of it. if(this->FortranProject) { @@ -847,7 +842,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // non-debug configurations because VS still creates .idb files. fout << "\t\t\t\tProgramDataBaseFileName=\"" << this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()) + target.GetPDBDirectory(configName).c_str()) << "/" << target.GetPDBName(configName) << "\"\n"; } @@ -918,7 +913,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, // Add a flag telling the manifest tool to use a workaround // for FAT32 file systems, which can cause an empty manifest // to be embedded into the resulting executable. See CMake - // bug #2617. + // bug #2617. const char* tool = "VCManifestTool"; if(this->FortranProject) { @@ -941,7 +936,7 @@ cmLocalVisualStudio7Generator ::GetBuildTypeLinkerFlags(std::string rootLinkerFlags, const char* configName) { std::string configTypeUpper = cmSystemTools::UpperCase(configName); - std::string extraLinkOptionsBuildTypeDef = + std::string extraLinkOptionsBuildTypeDef = rootLinkerFlags + "_" + configTypeUpper; std::string extraLinkOptionsBuildType = @@ -962,23 +957,23 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, std::string extraLinkOptions; if(target.GetType() == cmTarget::EXECUTABLE) { - extraLinkOptions = - this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS") - + std::string(" ") + extraLinkOptions = + this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS") + + std::string(" ") + GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName); } if(target.GetType() == cmTarget::SHARED_LIBRARY) { - extraLinkOptions = - this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS") - + std::string(" ") + extraLinkOptions = + this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS") + + std::string(" ") + GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName); } if(target.GetType() == cmTarget::MODULE_LIBRARY) { - extraLinkOptions = - this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS") - + std::string(" ") + extraLinkOptions = + this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS") + + std::string(" ") + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName); } @@ -1079,7 +1074,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, targetNameImport, targetNamePDB, configName); // Compute the link library and directory information. - cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); if(!pcli) { return; @@ -1125,7 +1122,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalLibraryDirectories=\""; this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; - temp = target.GetDirectory(configName); + temp = target.GetPDBDirectory(configName); temp += "/"; temp += targetNamePDB; fout << "\t\t\t\tProgramDatabaseFile=\"" << @@ -1164,7 +1161,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, targetNameImport, targetNamePDB, configName); // Compute the link library and directory information. - cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); if(!pcli) { return; @@ -1203,7 +1202,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, temp = target.GetDirectory(configName); temp += "/"; temp += targetNameFull; - fout << "\t\t\t\tOutputFile=\"" + fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; this->WriteTargetVersionAttribute(fout, target); linkOptions.OutputFlagMap(fout, "\t\t\t\t"); @@ -1211,7 +1210,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, this->OutputLibraryDirectories(fout, cli.GetDirectories()); fout << "\"\n"; std::string path = this->ConvertToXMLOutputPathSingle( - target.GetDirectory(configName).c_str()); + target.GetPDBDirectory(configName).c_str()); fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/" << targetNamePDB << "\"\n"; @@ -1594,7 +1593,7 @@ cmLocalVisualStudio7Generator void cmLocalVisualStudio7Generator ::WriteGroup(const cmSourceGroup *sg, cmTarget& target, - std::ostream &fout, const char *libName, + std::ostream &fout, const char *libName, std::vector<std::string> *configs) { const std::vector<const cmSourceFile *> &sourceFiles = @@ -1652,7 +1651,7 @@ void cmLocalVisualStudio7Generator } if(ext == "rc") { - aCompilerTool = "VCResourceCompilerTool"; + aCompilerTool = "VCResourceCompilerTool"; lang = "RC"; if(this->FortranProject) { @@ -1744,7 +1743,7 @@ WriteCustomRule(std::ostream& fout, FCInfo& fcinfo) { std::string comment = this->ConstructComment(command); - + // Write the rule for each configuration. std::vector<std::string>::iterator i; std::vector<std::string> *configs = @@ -1780,9 +1779,9 @@ WriteCustomRule(std::ostream& fout, } fout << "\t\t\t\t\t<Tool\n" << "\t\t\t\t\tName=\"" << customTool << "\"\n" - << "\t\t\t\t\tDescription=\"" + << "\t\t\t\t\tDescription=\"" << this->EscapeForXML(comment.c_str()) << "\"\n" - << "\t\t\t\t\tCommandLine=\"" + << "\t\t\t\t\tCommandLine=\"" << this->EscapeForXML(script.c_str()) << "\"\n" << "\t\t\t\t\tAdditionalDependencies=\""; if(command.GetDepends().empty()) @@ -1799,9 +1798,9 @@ WriteCustomRule(std::ostream& fout, else { // Write out the dependencies for the rule. - for(std::vector<std::string>::const_iterator d = + for(std::vector<std::string>::const_iterator d = command.GetDepends().begin(); - d != command.GetDepends().end(); + d != command.GetDepends().end(); ++d) { // Get the real name of the dependency in case it is a CMake target. @@ -1823,9 +1822,9 @@ WriteCustomRule(std::ostream& fout, { // Write a rule for the output generated by this command. const char* sep = ""; - for(std::vector<std::string>::const_iterator o = - command.GetOutputs().begin(); - o != command.GetOutputs().end(); + for(std::vector<std::string>::const_iterator o = + command.GetOutputs().begin(); + o != command.GetOutputs().end(); ++o) { fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str()); @@ -1922,7 +1921,7 @@ cmLocalVisualStudio7Generator const char *libName, cmTarget & target) { - + cmGlobalVisualStudio7Generator* gg = static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); @@ -1933,9 +1932,11 @@ cmLocalVisualStudio7Generator vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion"; cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion, cmSystemTools::KeyWOW64_32); - if (intelVersion.find("12") == 0 || (intelVersion.find("11") == 0)) + if (intelVersion.find("13") == 0 || + intelVersion.find("12") == 0 || + intelVersion.find("11") == 0) { - // Version 11.x and 12.x actually use 11.0 in project files! + // Version 11.x, 12.x, and 13.x actually use 11.0 in project files! intelVersion = "11.0" ; } else if(intelVersion.find("10") == 0) @@ -1952,7 +1953,7 @@ cmLocalVisualStudio7Generator if(!keyword) { keyword = "Console Application"; - } + } const char* projectType = 0; switch(target.GetType()) { @@ -1988,7 +1989,7 @@ cmLocalVisualStudio7Generator fout << "\tProjectType=\"" << projectType << "\"\n"; } this->WriteProjectSCC(fout, target); - fout<< "\tKeyword=\"" << keyword << "\">\n" + fout<< "\tKeyword=\"" << keyword << "\">\n" << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n" << "\t<Platforms>\n" << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n" @@ -2108,7 +2109,7 @@ std::string cmLocalVisualStudio7Generator // This class is used to parse an existing vs 7 project -// and extract the GUID +// and extract the GUID class cmVS7XMLParser : public cmXMLParser { public: @@ -2128,7 +2129,7 @@ public: while(atts[i]) { if(strcmp(atts[i], "ProjectGUID") == 0) - { + { if(atts[i+1]) { this->GUID = atts[i+1]; @@ -2142,7 +2143,7 @@ public: } ++i; } - } + } } int InitializeParser() { @@ -2151,7 +2152,7 @@ public: { return ret; } - // visual studio projects have a strange encoding, but it is + // visual studio projects have a strange encoding, but it is // really utf-8 XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8"); return 1; diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 9aa408e..95db2cc 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -42,7 +42,7 @@ public: virtual void AddHelperCommands(); /** - * Generate the makefile for this directory. + * Generate the makefile for this directory. */ virtual void Generate(); @@ -77,17 +77,17 @@ private: void WriteVCProjHeader(std::ostream& fout, const char *libName, cmTarget &tgt, std::vector<cmSourceGroup> &sgs); void WriteVCProjFooter(std::ostream& fout, cmTarget &target); - void WriteVCProjFile(std::ostream& fout, const char *libName, + void WriteVCProjFile(std::ostream& fout, const char *libName, cmTarget &tgt); void WriteConfigurations(std::ostream& fout, const char *libName, cmTarget &tgt); void WriteConfiguration(std::ostream& fout, const char* configName, - const char* libName, cmTarget &tgt); + const char* libName, cmTarget &tgt); std::string EscapeForXML(const char* s); std::string ConvertToXMLOutputPath(const char* path); std::string ConvertToXMLOutputPathSingle(const char* path); - void OutputTargetRules(std::ostream& fout, const char* configName, + void OutputTargetRules(std::ostream& fout, const char* configName, cmTarget &target, const char *libName); void OutputBuildTool(std::ostream& fout, const char* configName, cmTarget& t, bool debug); @@ -98,18 +98,18 @@ private: cmTarget &tgt, std::vector<cmSourceGroup> &sgs); void WriteProjectStartFortran(std::ostream& fout, const char *libName, cmTarget &tgt); - void WriteVCProjBeginGroup(std::ostream& fout, + void WriteVCProjBeginGroup(std::ostream& fout, const char* group, const char* filter); void WriteVCProjEndGroup(std::ostream& fout); - + void WriteCustomRule(std::ostream& fout, const char* source, const cmCustomCommand& command, FCInfo& fcinfo); void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target); - void WriteGroup(const cmSourceGroup *sg, + void WriteGroup(const cmSourceGroup *sg, cmTarget& target, std::ostream &fout, const char *libName, std::vector<std::string> *configs); @@ -122,7 +122,7 @@ private: cmVS7FlagTable const* ExtraFlagTable; std::string ModuleDefinitionFile; bool FortranProject; - std::string PlatformName; // Win32 or x64 + std::string PlatformName; // Win32 or x64 cmLocalVisualStudio7GeneratorInternals* Internal; }; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 2599227..bd7ec00 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -56,7 +56,7 @@ public: * This is called when the command is first encountered in * the CMakeLists.txt file. */ - virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, + virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, cmExecutionStatus &); virtual bool InitialPass(std::vector<std::string> const&, @@ -66,7 +66,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const { return this->Args[0].c_str(); } - + /** * Succinct documentation. */ @@ -164,7 +164,7 @@ bool cmMacroHelperCommand::InvokeInitialPass { variable = "${"; variable += this->Args[j]; - variable += "}"; + variable += "}"; cmSystemTools::ReplaceString(tmps, variable.c_str(), expandedArgs[j-1].c_str()); } @@ -270,7 +270,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, else if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro")) { // if this is the endmacro for this macro then execute - if (!this->Depth) + if (!this->Depth) { std::string name = this->Args[0]; std::vector<std::string>::size_type cc; @@ -287,7 +287,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, f->Functions = this->Functions; mf.RecordPolicies(f->Policies); std::string newName = "_" + this->Args[0]; - mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(), + mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(), newName.c_str()); mf.AddCommand(f); @@ -341,7 +341,7 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args, cmMacroFunctionBlocker *f = new cmMacroFunctionBlocker(); for(std::vector<std::string>::const_iterator j = args.begin(); j != args.end(); ++j) - { + { f->Args.push_back(*j); } this->Makefile->AddFunctionBlocker(f); diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index 36e4b2f..f8c40c0 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -20,11 +20,11 @@ class cmMacroFunctionBlocker : public cmFunctionBlocker public: cmMacroFunctionBlocker() {this->Depth=0;} virtual ~cmMacroFunctionBlocker() {} - virtual bool IsFunctionBlocked(const cmListFileFunction&, + virtual bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf); - + std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; int Depth; diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 6055c55..2ae35ef 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmMakeDepend.h" #include "cmSystemTools.h" +#include "cmGeneratorExpression.h" #include <cmsys/RegularExpression.hxx> @@ -31,8 +32,8 @@ cmMakeDepend::cmMakeDepend() cmMakeDepend::~cmMakeDepend() -{ - for(DependInformationMapType::iterator i = +{ + for(DependInformationMapType::iterator i = this->DependInformationMap.begin(); i != this->DependInformationMap.end(); ++i) { @@ -58,11 +59,22 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile) // Now extract any include paths from the targets std::set<std::string> uniqueIncludes; std::vector<std::string> orderedAndUniqueIncludes; - cmTargets & targets = this->Makefile->GetTargets(); - for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) + cmTargets &targets = this->Makefile->GetTargets(); + for (cmTargets::iterator l = targets.begin(); + l != targets.end(); ++l) { - const std::vector<std::string>& includes = - l->second.GetIncludeDirectories(); + const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES"); + if (!incDirProp) + { + continue; + } + + std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp, + cmGeneratorExpression::StripAllGeneratorExpressions); + + std::vector<std::string> includes; + cmSystemTools::ExpandListArgument(incDirs.c_str(), includes); + for(std::vector<std::string>::const_iterator j = includes.begin(); j != includes.end(); ++j) { @@ -162,7 +174,7 @@ void cmMakeDepend::GenerateDependInformation(cmDependInformation* info) else { //try to guess which include path to use - for(std::vector<std::string>::iterator t = + for(std::vector<std::string>::iterator t = this->IncludeDirectories.begin(); t != this->IncludeDirectories.end(); ++t) { @@ -175,7 +187,7 @@ void cmMakeDepend::GenerateDependInformation(cmDependInformation* info) if (srcFile->GetFullPath() == incpath) { // set the path to the guessed path - info->FullPath = incpath; + info->FullPath = incpath; found=true; } } @@ -243,7 +255,7 @@ void cmMakeDepend::DependWalk(cmDependInformation* info) void cmMakeDepend::AddDependency(cmDependInformation* info, const char* file) { - cmDependInformation* dependInfo = + cmDependInformation* dependInfo = this->GetDependInformation(file, info->PathOnly.c_str()); this->GenerateDependInformation(dependInfo); info->AddDependencies(dependInfo); @@ -288,7 +300,7 @@ std::string cmMakeDepend::FullPath(const char* fname, const char *extraPath) { m = this->DirectoryToFileToPathMap.find(""); } - + if(m != this->DirectoryToFileToPathMap.end()) { FileToPathMapType& map = m->second; @@ -305,7 +317,7 @@ std::string cmMakeDepend::FullPath(const char* fname, const char *extraPath) this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp; return fp; } - + for(std::vector<std::string>::iterator i = this->IncludeDirectories.begin(); i != this->IncludeDirectories.end(); ++i) { diff --git a/Source/cmMakeDepend.h b/Source/cmMakeDepend.h index 185f4e3..b6e3928 100644 --- a/Source/cmMakeDepend.h +++ b/Source/cmMakeDepend.h @@ -48,26 +48,26 @@ public: * to it. */ const cmSourceFile *SourceFile; - + /** * Full path to this file. */ std::string FullPath; - + /** * Full path not including file name. */ std::string PathOnly; - + /** * Name used to #include this file. */ std::string IncludeName; - + /** * This method adds the dependencies of another file to this one. */ - void AddDependencies(cmDependInformation*); + void AddDependencies(cmDependInformation*); }; @@ -85,11 +85,11 @@ public: * Destructor. */ virtual ~cmMakeDepend(); - - /** + + /** * Set the makefile that is used as a source of classes. */ - virtual void SetMakefile(cmMakefile* makefile); + virtual void SetMakefile(cmMakefile* makefile); /** * Add a directory to the search path for include files. @@ -107,26 +107,26 @@ protected: * Compute the depend information for this class. */ virtual void DependWalk(cmDependInformation* info); - + /** * Add a dependency. Possibly walk it for more dependencies. */ virtual void AddDependency(cmDependInformation* info, const char* file); - + /** * Fill in the given object with dependency information. If the * information is already complete, nothing is done. */ void GenerateDependInformation(cmDependInformation* info); - + /** * Get an instance of cmDependInformation corresponding to the given file * name. */ - cmDependInformation* GetDependInformation(const char* file, - const char *extraPath); - - /** + cmDependInformation* GetDependInformation(const char* file, + const char *extraPath); + + /** * Find the full path name for the given file name. * This uses the include directories. * TODO: Cache path conversions to reduce FileExists calls. @@ -139,9 +139,9 @@ protected: cmsys::RegularExpression ComplainFileRegularExpression; std::vector<std::string> IncludeDirectories; typedef std::map<cmStdString, cmStdString> FileToPathMapType; - typedef std::map<cmStdString, FileToPathMapType> + typedef std::map<cmStdString, FileToPathMapType> DirectoryToFileToPathMapType; - typedef std::map<cmStdString, cmDependInformation*> + typedef std::map<cmStdString, cmDependInformation*> DependInformationMapType; DependInformationMapType DependInformationMap; DirectoryToFileToPathMapType DirectoryToFileToPathMap; diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h index 4e6e1d5..a0f866a 100644 --- a/Source/cmMakeDirectoryCommand.h +++ b/Source/cmMakeDirectoryCommand.h @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmMakeDirectoryCommand; } @@ -45,7 +45,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const { return "make_directory";} - + /** * This determines if the command is invoked when in script mode. */ @@ -58,7 +58,7 @@ public: { return "Deprecated. Use the file(MAKE_DIRECTORY ) command instead."; } - + /** * More documentation. */ @@ -70,7 +70,7 @@ public: "parent directories that do not exist will also be created. Use with " "care."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a60896f..f067da4 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -46,6 +46,7 @@ public: std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack; std::stack<std::set<cmStdString> > VarInitStack; std::stack<std::set<cmStdString> > VarUsageStack; + bool IsSourceFileTryCompile; }; // default is not to be building executables @@ -56,6 +57,7 @@ cmMakefile::cmMakefile(): Internal(new Internals) this->Internal->VarStack.push(defs); this->Internal->VarInitStack.push(globalKeys); this->Internal->VarUsageStack.push(globalKeys); + this->Internal->IsSourceFileTryCompile = false; // Initialize these first since AddDefaultDefinitions calls AddDefinition this->WarnUnused = false; @@ -2203,8 +2205,12 @@ bool cmMakefile::PlatformIs64Bit() const const char* cmMakefile::GetSONameFlag(const char* language) const { - std::string name = "CMAKE_SHARED_LIBRARY_SONAME_"; - name += language; + std::string name = "CMAKE_SHARED_LIBRARY_SONAME"; + if(language) + { + name += "_"; + name += language; + } name += "_FLAG"; return GetDefinition(name.c_str()); } @@ -2908,6 +2914,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir, const std::vector<std::string> *cmakeArgs, std::string *output) { + this->Internal->IsSourceFileTryCompile = fast; // does the binary directory exist ? If not create it... if (!cmSystemTools::FileIsDirectory(bindir)) { @@ -2933,6 +2940,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir, "Internal CMake error, TryCompile bad GlobalGenerator"); // return to the original directory cmSystemTools::ChangeDirectory(cwd.c_str()); + this->Internal->IsSourceFileTryCompile = false; return 1; } cm.SetGlobalGenerator(gg); @@ -3005,6 +3013,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir, "Internal CMake error, TryCompile configure of cmake failed"); // return to the original directory cmSystemTools::ChangeDirectory(cwd.c_str()); + this->Internal->IsSourceFileTryCompile = false; return 1; } @@ -3014,6 +3023,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir, "Internal CMake error, TryCompile generation of cmake failed"); // return to the original directory cmSystemTools::ChangeDirectory(cwd.c_str()); + this->Internal->IsSourceFileTryCompile = false; return 1; } @@ -3027,9 +3037,15 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir, this); cmSystemTools::ChangeDirectory(cwd.c_str()); + this->Internal->IsSourceFileTryCompile = false; return ret; } +bool cmMakefile::GetIsSourceFileTryCompile() const +{ + return this->Internal->IsSourceFileTryCompile; +} + cmake *cmMakefile::GetCMakeInstance() const { if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() ) @@ -3968,6 +3984,12 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name) return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name); } +cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name) +{ + cmTarget *t = this->FindTargetToUse(name); + return this->LocalGenerator->GetGlobalGenerator()->GetGeneratorTarget(t); +} + //---------------------------------------------------------------------------- bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg, bool isCustom) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 8a0088b..70cfe54 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -20,6 +20,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmNewLineStyle.h" +#include "cmGeneratorTarget.h" #include "cmake.h" #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -128,6 +129,8 @@ public: const std::vector<std::string> *cmakeArgs, std::string *output); + bool GetIsSourceFileTryCompile() const; + /** * Specify the makefile generator. This is platform/compiler * dependent, although the interface is through a generic @@ -516,12 +519,27 @@ public: * Get the list of targets, const version */ const cmTargets &GetTargets() const { return this->Targets; } + const std::vector<cmTarget*> &GetOwnedImportedTargets() const + { + return this->ImportedTargetsOwned; + } + + const cmGeneratorTargetsType &GetGeneratorTargets() const + { + return this->GeneratorTargets; + } + + void SetGeneratorTargets(const cmGeneratorTargetsType &targets) + { + this->GeneratorTargets = targets; + } cmTarget* FindTarget(const char* name); /** Find a target to use in place of the given name. The target returned may be imported or built within the project. */ cmTarget* FindTargetToUse(const char* name); + cmGeneratorTarget* FindGeneratorTargetToUse(const char* name); /** * Mark include directories as system directories. @@ -863,6 +881,7 @@ protected: // libraries, classes, and executables cmTargets Targets; + cmGeneratorTargetsType GeneratorTargets; std::vector<cmSourceFile*> SourceFiles; // Tests diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 78278cb..b7a454b 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -29,13 +29,19 @@ cmMakefileExecutableTargetGenerator this->TargetNameOut, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsAppBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".app/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileExecutableTargetGenerator +::~cmMakefileExecutableTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -100,7 +106,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpath += "/"; if(this->Target->IsAppBundleOnApple()) { - this->CreateAppBundle(targetName, outpath); + this->OSXBundleGenerator->CreateAppBundle(targetName, outpath); } std::string outpathImp; if(relink) @@ -125,11 +131,16 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp += "/"; } } + + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; std::string targetFullPathReal = outpath + targetNameReal; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; - std::string targetOutPathPDB = + std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), cmLocalGenerator::NONE, cmLocalGenerator::SHELL); @@ -204,7 +215,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Add language feature flags. this->AddFeatureFlags(flags, linkLanguage); - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, linkLanguage, this->ConfigName); // Add target-specific linker flags. @@ -312,9 +323,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->LocalGenerator->SetLinkScriptShell(useLinkScript); // Collect up flags to link in needed libraries. - cmOStringStream linklibs; - this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target, relink); - + std::string linkLibs; + std::string frameworkPath; + std::string linkPath; + this->LocalGenerator->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *this->GeneratorTarget, + relink); + linkLibs = frameworkPath + linkPath + linkLibs; // Construct object file lists that may be needed to expand the // rule. std::string buildObjs; @@ -353,8 +368,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); - std::string linkString = linklibs.str(); - vars.LinkLibraries = linkString.c_str(); + vars.LinkLibraries = linkLibs.c_str(); vars.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); // Expand placeholders in the commands. @@ -440,24 +454,3 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) exeCleanFiles.begin(), exeCleanFiles.end()); } - -//---------------------------------------------------------------------------- -void -cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->LocalGenerator->GenerateAppleInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); -} diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h index 985f207..3b18166 100644 --- a/Source/cmMakefileExecutableTargetGenerator.h +++ b/Source/cmMakefileExecutableTargetGenerator.h @@ -18,14 +18,14 @@ class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileExecutableTargetGenerator(cmTarget* target); + virtual ~cmMakefileExecutableTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ virtual void WriteRuleFiles(); - + protected: virtual void WriteExecutableRule(bool relink); - void CreateAppBundle(std::string& targetName, std::string& outpath); }; #endif diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index db59ffd..e7004d6 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -26,41 +26,26 @@ cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): cmMakefileTargetGenerator(target) { - if(this->Target->IsCFBundleOnApple()) - { - target->SetProperty("PREFIX", ""); - target->SetProperty("SUFFIX", ""); - } + cmOSXBundleGenerator::PrepareTargetProperties(this->Target); this->CustomCommandDriver = OnDepends; this->Target->GetLibraryNames( this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsFrameworkOnApple()) - { - this->FrameworkVersion = this->Target->GetFrameworkVersion(); - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".framework/Versions/"; - this->MacContentDirectory += this->FrameworkVersion; - this->MacContentDirectory += "/"; - } - else if(this->Target->IsCFBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += "."; - const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - this->MacContentDirectory += ext; - this->MacContentDirectory += "/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileLibraryTargetGenerator +::~cmMakefileLibraryTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -199,7 +184,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); this->LocalGenerator->AppendFlags (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str())); - + this->LocalGenerator->AddConfigVariableFlags (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName); this->AddModuleDefinitionFlag(extraFlags); @@ -220,7 +205,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) linkRuleVar += "_CREATE_SHARED_MODULE"; std::string extraFlags; - this->LocalGenerator->AppendFlags(extraFlags, + this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS")); std::string linkFlagsConfig = "LINK_FLAGS_"; linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); @@ -246,7 +231,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) linkRuleVar += "_CREATE_MACOSX_FRAMEWORK"; std::string extraFlags; - this->LocalGenerator->AppendFlags(extraFlags, + this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS")); std::string linkFlagsConfig = "LINK_FLAGS_"; linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); @@ -259,115 +244,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) } //---------------------------------------------------------------------------- -void -cmMakefileLibraryTargetGenerator -::CreateFramework(std::string const& targetName) -{ - // Configure the Info.plist file into the Resources directory. - this->MacContentFolders.insert("Resources"); - std::string plist = this->MacContentDirectory + "Resources/Info.plist"; - this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - - // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to - // drive rules to create these files at build time. - std::string oldName; - std::string newName; - - // Compute the location of the top-level foo.framework directory. - std::string top = this->Target->GetDirectory(this->ConfigName); - top += "/"; - top += this->TargetNameOut; - top += ".framework/"; - - // Make foo.framework/Versions - std::string versions = top; - versions += "Versions"; - cmSystemTools::MakeDirectory(versions.c_str()); - - // Make foo.framework/Versions/version - std::string version = versions; - version += "/"; - version += this->FrameworkVersion; - cmSystemTools::MakeDirectory(version.c_str()); - - // Current -> version - oldName = this->FrameworkVersion; - newName = versions; - newName += "/Current"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - - // foo -> Versions/Current/foo - oldName = "Versions/Current/"; - oldName += this->TargetNameOut; - newName = top; - newName += this->TargetNameOut; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - - // Resources -> Versions/Current/Resources - if(this->MacContentFolders.find("Resources") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/Resources"; - newName = top; - newName += "Resources"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } - - // Headers -> Versions/Current/Headers - if(this->MacContentFolders.find("Headers") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/Headers"; - newName = top; - newName += "Headers"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } - - // PrivateHeaders -> Versions/Current/PrivateHeaders - if(this->MacContentFolders.find("PrivateHeaders") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/PrivateHeaders"; - newName = top; - newName += "PrivateHeaders"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } -} - -//---------------------------------------------------------------------------- -void -cmMakefileLibraryTargetGenerator::CreateCFBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->LocalGenerator->GenerateAppleInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); -} - -//---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteLibraryRules (const char* linkRuleVar, const char* extraFlags, bool relink) { @@ -419,13 +295,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules if(this->Target->IsFrameworkOnApple()) { outpath = this->MacContentDirectory; - this->CreateFramework(targetName); + this->OSXBundleGenerator->CreateFramework(targetName); } else if(this->Target->IsCFBundleOnApple()) { outpath = this->Target->GetDirectory(this->ConfigName); outpath += "/"; - this->CreateCFBundle(targetName, outpath); + this->OSXBundleGenerator->CreateCFBundle(targetName, outpath); } else if(relink) { @@ -452,24 +328,28 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string pdbOutputPath = this->Target->GetPDBDirectory(); + cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); + pdbOutputPath += "/"; + std::string targetFullPath = outpath + targetName; - std::string targetFullPathPDB = outpath + targetNamePDB; + std::string targetFullPathPDB = pdbOutputPath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathImport = outpathImp + targetNameImport; // Construct the output path version of the names for use in command // arguments. - std::string targetOutPathPDB = + std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE, cmLocalGenerator::SHELL); - std::string targetOutPath = + std::string targetOutPath = this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); - std::string targetOutPathSO = + std::string targetOutPathSO = this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); - std::string targetOutPathReal = + std::string targetOutPathReal = this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); std::string targetOutPathImport = @@ -569,7 +449,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::vector<std::string> commands1; // Add a command to remove any existing files for this library. - // for static libs only + // for static libs only if(this->Target->GetType() == cmTarget::STATIC_LIBRARY) { this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles, @@ -666,11 +546,15 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules this->LocalGenerator->SetLinkScriptShell(useLinkScript); // Collect up flags to link in needed libraries. - cmOStringStream linklibs; + std::string linkLibs; if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) { + std::string frameworkPath; + std::string linkPath; this->LocalGenerator - ->OutputLinkLibraries(linklibs, *this->Target, relink); + ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *this->GeneratorTarget, relink); + linkLibs = frameworkPath + linkPath + linkLibs; } // Construct object file lists that may be needed to expand the @@ -711,8 +595,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules cmLocalGenerator::SHELL); vars.ObjectDir = objdir.c_str(); vars.Target = targetOutPathReal.c_str(); - std::string linkString = linklibs.str(); - vars.LinkLibraries = linkString.c_str(); + vars.LinkLibraries = linkLibs.c_str(); vars.ObjectsQuoted = buildObjs.c_str(); if (this->Target->HasSOName(this->ConfigName)) { @@ -749,7 +632,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string langFlags; this->AddFeatureFlags(langFlags, linkLanguage); - this->LocalGenerator->AddArchitectureFlags(langFlags, this->Target, + this->LocalGenerator->AddArchitectureFlags(langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName); // remove any language flags that might not work with the diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index e6a5867..07f828b 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -14,16 +14,17 @@ #include "cmMakefileTargetGenerator.h" -class cmMakefileLibraryTargetGenerator: +class cmMakefileLibraryTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileLibraryTargetGenerator(cmTarget* target); + virtual ~cmMakefileLibraryTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ - virtual void WriteRuleFiles(); - + virtual void WriteRuleFiles(); + protected: void WriteObjectLibraryRules(); void WriteStaticLibraryRules(); @@ -33,8 +34,6 @@ protected: bool relink); // MacOSX Framework support methods void WriteFrameworkRules(bool relink); - void CreateFramework(std::string const& targetName); - void CreateCFBundle(std::string& targetName, std::string& outpath); // Store the computd framework version for OS X Frameworks. std::string FrameworkVersion; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 408f287..3d02d6a 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -28,6 +28,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) + : OSXBundleGenerator(0) + , MacOSXContentGenerator(0) { this->BuildFileStream = 0; this->InfoFileStream = 0; @@ -50,6 +52,12 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) { this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); } + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); +} + +cmMakefileTargetGenerator::~cmMakefileTargetGenerator() +{ + delete MacOSXContentGenerator; } cmMakefileTargetGenerator * @@ -153,8 +161,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } } - this->WriteMacOSXContentRules(this->GeneratorTarget->HeaderSources); - this->WriteMacOSXContentRules(this->GeneratorTarget->ExtraSources); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); for(std::vector<cmSourceFile*>::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -173,7 +185,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects); } - //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::WriteCommonCodeRules() { @@ -245,13 +256,10 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) std::string flags; const char *lang = l.c_str(); - bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || - (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); - // Add language feature flags. this->AddFeatureFlags(flags, lang); - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, lang, this->ConfigName); // Fortran-specific flags computed for this target. @@ -260,8 +268,7 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) this->AddFortranFlags(flags); } - // Add shared-library flags if needed. - this->LocalGenerator->AddSharedFlags(flags, lang, shared); + this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang); // Add include directory flags. this->AddIncludeFlags(flags, lang); @@ -285,28 +292,26 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); if (i == this->DefinesByLanguage.end()) { - std::string defines; + std::set<std::string> defines; const char *lang = l.c_str(); // Add the export symbol definition for shared library objects. if(const char* exportMacro = this->Target->GetExportMacro()) { - this->LocalGenerator->AppendDefines(defines, exportMacro, lang); + this->LocalGenerator->AppendDefines(defines, exportMacro); } // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); + (defines, this->GeneratorTarget->GetCompileDefinitions()); + this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty(defPropName.c_str()), lang); + (defines, this->GeneratorTarget->GetCompileDefinitions( + this->LocalGenerator->ConfigurationName.c_str())); + + std::string definesString; + this->LocalGenerator->JoinDefines(defines, definesString, lang); - ByLanguageMap::value_type entry(l, defines); + ByLanguageMap::value_type entry(l, definesString); i = this->DefinesByLanguage.insert(entry).first; } return i->second; @@ -347,44 +352,20 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() } } -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules( - std::vector<cmSourceFile*> const& sources) -{ - for(std::vector<cmSourceFile*>::const_iterator - si = sources.begin(); si != sources.end(); ++si) - { - cmTarget::SourceFileFlags tsFlags = - this->Target->GetTargetSourceFileFlags(*si); - if(tsFlags.Type != cmTarget::SourceFileTypeNormal) - { - this->WriteMacOSXContentRules(**si, tsFlags.MacFolder); - } - } -} //---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, - const char* pkgloc) +void +cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator() + (cmSourceFile& source, const char* pkgloc) { // Skip OS X content when not building a Framework or Bundle. - if(this->MacContentDirectory.empty()) + if(this->Generator->MacContentDirectory.empty()) { return; } - // Construct the full path to the content subdirectory. - std::string macdir = this->MacContentDirectory; - macdir += pkgloc; - cmSystemTools::MakeDirectory(macdir.c_str()); - - // Record use of this content location. Only the first level - // directory is needed. - { - std::string loc = pkgloc; - loc = loc.substr(0, loc.find('/')); - this->MacContentFolders.insert(loc); - } + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); // Get the input file location. std::string input = source.GetFullPath(); @@ -393,9 +374,11 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, std::string output = macdir; output += "/"; output += cmSystemTools::GetFilenameName(input); - this->CleanFiles.push_back(this->Convert(output.c_str(), - cmLocalGenerator::START_OUTPUT)); - output = this->Convert(output.c_str(), cmLocalGenerator::HOME_OUTPUT); + this->Generator->CleanFiles.push_back( + this->Generator->Convert(output.c_str(), + cmLocalGenerator::START_OUTPUT)); + output = this->Generator->Convert(output.c_str(), + cmLocalGenerator::HOME_OUTPUT); // Create a rule to copy the content into the bundle. std::vector<std::string> depends; @@ -403,21 +386,23 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, depends.push_back(input); std::string copyEcho = "Copying OS X content "; copyEcho += output; - this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(), - cmLocalUnixMakefileGenerator3::EchoBuild); + this->Generator->LocalGenerator->AppendEcho( + commands, copyEcho.c_str(), + cmLocalUnixMakefileGenerator3::EchoBuild); std::string copyCommand = "$(CMAKE_COMMAND) -E copy "; - copyCommand += this->Convert(input.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(input.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); copyCommand += " "; - copyCommand += this->Convert(output.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(output.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); commands.push_back(copyCommand); - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - output.c_str(), - depends, commands, false); - this->ExtraFiles.insert(output); + this->Generator->LocalGenerator->WriteMakeRule( + *this->Generator->BuildFileStream, 0, + output.c_str(), + depends, commands, false); + this->Generator->ExtraFiles.insert(output); } //---------------------------------------------------------------------------- @@ -600,14 +585,12 @@ cmMakefileTargetGenerator } // Add language-specific defines. - std::string defines = "$("; - defines += lang; - defines += "_DEFINES)"; + std::set<std::string> defines; // Add source-sepcific preprocessor definitions. if(const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS")) { - this->LocalGenerator->AppendDefines(defines, compile_defs, lang); + this->LocalGenerator->AppendDefines(defines, compile_defs); *this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES = " << compile_defs << "\n" @@ -620,7 +603,7 @@ cmMakefileTargetGenerator if(const char* config_compile_defs = source.GetProperty(defPropName.c_str())) { - this->LocalGenerator->AppendDefines(defines, config_compile_defs, lang); + this->LocalGenerator->AppendDefines(defines, config_compile_defs); *this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_" << configUpper @@ -664,7 +647,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } @@ -689,7 +672,14 @@ cmMakefileTargetGenerator cmLocalGenerator::SHELL); vars.ObjectDir = objectDir.c_str(); vars.Flags = flags.c_str(); - vars.Defines = defines.c_str(); + + std::string definesString = "$("; + definesString += lang; + definesString += "_DEFINES)"; + + this->LocalGenerator->JoinDefines(defines, definesString, lang); + + vars.Defines = definesString.c_str(); bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) || (strcmp(lang, "CXX") == 0)); @@ -1027,7 +1017,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n"; std::set<cmTarget const*> emitted; const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(cfg)) { cmComputeLinkInformation::ItemVector const& items = cli->GetItems(); for(cmComputeLinkInformation::ItemVector::const_iterator @@ -1066,7 +1057,11 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() *this->InfoFileStream << "SET(CMAKE_C_TARGET_INCLUDE_PATH\n"; std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); for(std::vector<std::string>::iterator i = includes.begin(); i != includes.end(); ++i) { @@ -1420,10 +1415,9 @@ class cmMakefileTargetGeneratorObjectStrings { public: cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings, - cmMakefile* mf, cmLocalUnixMakefileGenerator3* lg, std::string::size_type limit): - Strings(strings), Makefile(mf), LocalGenerator(lg), LengthLimit(limit) + Strings(strings), LocalGenerator(lg), LengthLimit(limit) { this->Space = ""; } @@ -1458,7 +1452,6 @@ public: } private: std::vector<std::string>& Strings; - cmMakefile* Makefile; cmLocalUnixMakefileGenerator3* LocalGenerator; std::string::size_type LengthLimit; std::string CurrentString; @@ -1473,7 +1466,7 @@ cmMakefileTargetGenerator std::string::size_type limit) { cmMakefileTargetGeneratorObjectStrings - helper(objStrings, this->Makefile, this->LocalGenerator, limit); + helper(objStrings, this->LocalGenerator, limit); for(std::vector<std::string>::const_iterator i = this->Objects.begin(); i != this->Objects.end(); ++i) { @@ -1553,7 +1546,11 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() emitted.insert("/System/Library/Frameworks"); #endif std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); std::vector<std::string>::iterator i; // check all include directories for frameworks as this // will already have added a -F for the framework @@ -1597,7 +1594,8 @@ void cmMakefileTargetGenerator // Loop over all library dependencies. const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(cfg)) { std::vector<std::string> const& libDeps = cli->GetDepends(); for(std::vector<std::string>::const_iterator j = libDeps.begin(); @@ -1857,7 +1855,10 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target, lang); + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + lang, config); std::string includeFlags = this->LocalGenerator->GetIncludeFlags(includes, lang, useResponseFile); @@ -1960,7 +1961,10 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); for(std::vector<std::string>::const_iterator idi = includes.begin(); idi != includes.end(); ++idi) { diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 36a1f68..2798e54 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -13,6 +13,7 @@ #define cmMakefileTargetGenerator_h #include "cmLocalUnixMakefileGenerator3.h" +#include "cmOSXBundleGenerator.h" class cmCustomCommand; class cmDependInformation; @@ -34,7 +35,7 @@ class cmMakefileTargetGenerator public: // constructor to set the ivars cmMakefileTargetGenerator(cmTarget* target); - virtual ~cmMakefileTargetGenerator() {}; + virtual ~cmMakefileTargetGenerator(); // construct using this factory call static cmMakefileTargetGenerator *New(cmTarget *tgt); @@ -50,6 +51,7 @@ public: { return this->ProgressFileNameFull; } cmTarget* GetTarget() { return this->Target;} + protected: // create the file and directory etc @@ -73,8 +75,18 @@ protected: void WriteTargetDependRules(); // write rules for Mac OS X Application Bundle content. - void WriteMacOSXContentRules(std::vector<cmSourceFile*> const& sources); - void WriteMacOSXContentRules(cmSourceFile& source, const char* pkgloc); + struct MacOSXContentGeneratorType : + cmOSXBundleGenerator::MacOSXContentGeneratorType + { + MacOSXContentGeneratorType(cmMakefileTargetGenerator* gen) : + Generator(gen) {} + + void operator()(cmSourceFile& source, const char* pkgloc); + + private: + cmMakefileTargetGenerator* Generator; + }; + friend struct MacOSXContentGeneratorType; // write the rules for an object void WriteObjectRuleFiles(cmSourceFile& source); @@ -223,6 +235,8 @@ protected: // Mac OS X content info. std::string MacContentDirectory; std::set<cmStdString> MacContentFolders; + cmOSXBundleGenerator* OSXBundleGenerator; + MacOSXContentGeneratorType* MacOSXContentGenerator; typedef std::map<cmStdString, cmStdString> ByLanguageMap; std::string GetFlags(const std::string &l); diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index a82c503..4456aa7 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -24,6 +24,19 @@ cmMakefileUtilityTargetGenerator cmMakefileTargetGenerator(target) { this->CustomCommandDriver = OnUtility; + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileUtilityTargetGenerator +::~cmMakefileUtilityTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h index 99c16fc..fc47b38 100644 --- a/Source/cmMakefileUtilityTargetGenerator.h +++ b/Source/cmMakefileUtilityTargetGenerator.h @@ -14,16 +14,17 @@ #include "cmMakefileTargetGenerator.h" -class cmMakefileUtilityTargetGenerator: +class cmMakefileUtilityTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileUtilityTargetGenerator(cmTarget* target); + virtual ~cmMakefileUtilityTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ - virtual void WriteRuleFiles(); - + virtual void WriteRuleFiles(); + protected: }; diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx index a80f7ec..4236d10 100644 --- a/Source/cmMarkAsAdvancedCommand.cxx +++ b/Source/cmMarkAsAdvancedCommand.cxx @@ -37,7 +37,7 @@ bool cmMarkAsAdvancedCommand { std::string variable = args[i]; cmCacheManager* manager = this->Makefile->GetCacheManager(); - cmCacheManager::CacheIterator it = + cmCacheManager::CacheIterator it = manager->GetCacheIterator(variable.c_str()); if ( it.IsAtEnd() ) { diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h index 3658dbb..246eb8a 100644 --- a/Source/cmMarkAsAdvancedCommand.h +++ b/Source/cmMarkAsAdvancedCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmMarkAsAdvancedCommand; } @@ -41,7 +41,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "mark_as_advanced";} - + /** * Succinct documentation. */ @@ -49,7 +49,7 @@ public: { return "Mark cmake cached variables as advanced."; } - + /** * More documentation. */ diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx index 3c1129d..9fc4265 100644 --- a/Source/cmMathCommand.cxx +++ b/Source/cmMathCommand.cxx @@ -43,7 +43,7 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) const std::string& outputVariable = args[1]; const std::string& expression = args[2]; - + cmExprParserHelper helper; if ( !helper.ParseString(expression.c_str(), 0) ) { diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h index d622904..27c5b6a 100644 --- a/Source/cmMathCommand.h +++ b/Source/cmMathCommand.h @@ -21,7 +21,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmMathCommand; } @@ -50,7 +50,7 @@ public: { return "Mathematical expressions."; } - + /** * More documentation. */ @@ -64,10 +64,10 @@ public: "+ - * / % | & ^ ~ << >> * / %. They have the same meaning " " as they do in c code."; } - + cmTypeMacro(cmMathCommand, cmCommand); protected: - + bool HandleExprCommand(std::vector<std::string> const& args); }; diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h index 03ab94b..9f01eaf 100644 --- a/Source/cmMessageCommand.h +++ b/Source/cmMessageCommand.h @@ -24,7 +24,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmMessageCommand; } @@ -53,7 +53,7 @@ public: { return "Display a message to the user."; } - + /** * More documentation. */ @@ -83,7 +83,7 @@ public: "Indented text is considered pre-formatted." ; } - + cmTypeMacro(cmMessageCommand, cmCommand); }; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 8b86a98..6c54ced 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -16,8 +16,15 @@ #include "cmSourceFile.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" +#include "cmOSXBundleGenerator.h" #include <assert.h> +#include <algorithm> + +#ifndef _WIN32 +#include <unistd.h> +#endif + cmNinjaNormalTargetGenerator:: cmNinjaNormalTargetGenerator(cmTarget* target) @@ -27,7 +34,10 @@ cmNinjaNormalTargetGenerator(cmTarget* target) , TargetNameReal() , TargetNameImport() , TargetNamePDB() + , TargetLinkLanguage(0) { + cmOSXBundleGenerator::PrepareTargetProperties(target); + this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); if (target->GetType() == cmTarget::EXECUTABLE) target->GetExecutableNames(this->TargetNameOut, @@ -49,27 +59,18 @@ cmNinjaNormalTargetGenerator(cmTarget* target) // ensure the directory exists (OutDir test) EnsureDirectoryExists(target->GetDirectory(this->GetConfigName())); } -} - -cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() -{ -} -void -cmNinjaNormalTargetGenerator -::EnsureDirectoryExists(const std::string& dir) -{ - cmSystemTools::MakeDirectory(dir.c_str()); + this->OSXBundleGenerator = new cmOSXBundleGenerator(target, + this->TargetNameOut, + this->GetConfigName()); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); } -void -cmNinjaNormalTargetGenerator -::EnsureParentDirectoryExists(const std::string& path) +cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() { - EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); + delete this->OSXBundleGenerator; } - void cmNinjaNormalTargetGenerator::Generate() { if (!this->TargetLinkLanguage) { @@ -90,16 +91,15 @@ void cmNinjaNormalTargetGenerator::Generate() } else { - this->WriteLinkRule(); + this->WriteLinkRule(false); // write rule without rspfile support + this->WriteLinkRule(true); // write rule with rspfile support this->WriteLinkStatement(); } - - this->GetBuildFileStream() << "\n"; - this->GetRulesFileStream() << "\n"; } void cmNinjaNormalTargetGenerator::WriteLanguagesRules() { +#ifdef NINJA_GEN_VERBOSE_FILES cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream()); this->GetRulesFileStream() << "# Rules for each languages for " @@ -107,6 +107,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules() << " target " << this->GetTargetName() << "\n\n"; +#endif std::set<cmStdString> languages; this->GetTarget()->GetLanguages(languages); @@ -124,7 +125,10 @@ const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const case cmTarget::SHARED_LIBRARY: return "shared library"; case cmTarget::MODULE_LIBRARY: - return "shared module"; + if (this->GetTarget()->IsCFBundleOnApple()) + return "CFBundle shared module"; + else + return "shared module"; case cmTarget::EXECUTABLE: return "executable"; default: @@ -144,28 +148,62 @@ cmNinjaNormalTargetGenerator void cmNinjaNormalTargetGenerator -::WriteLinkRule() +::WriteLinkRule(bool useResponseFile) { cmTarget::TargetType targetType = this->GetTarget()->GetType(); std::string ruleName = this->LanguageLinkerRule(); + if (useResponseFile) + ruleName += "_RSP_FILE"; + + // Select whether to use a response file for objects. + std::string rspfile; + std::string rspcontent; if (!this->GetGlobalGenerator()->HasRule(ruleName)) { cmLocalGenerator::RuleVariables vars; vars.RuleLauncher = "RULE_LAUNCH_LINK"; vars.CMTarget = this->GetTarget(); vars.Language = this->TargetLinkLanguage; - vars.Objects = "$in"; - std::string objdir = - this->GetLocalGenerator()->GetHomeRelativeOutputPath(); - objdir += objdir.empty() ? "" : "/"; - objdir += cmake::GetCMakeFilesDirectoryPostSlash(); - objdir += this->GetTargetName(); - objdir += ".dir"; - objdir = this->GetLocalGenerator()->Convert(objdir.c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL); - vars.ObjectDir = objdir.c_str(); + + std::string responseFlag; + if (!useResponseFile) { + vars.Objects = "$in"; + vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES"; + } else { + std::string cmakeVarLang = "CMAKE_"; + cmakeVarLang += this->TargetLinkLanguage; + + // build response file name + std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; + const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar.c_str()); + if(flag) { + responseFlag = flag; + } else { + responseFlag = "@"; + } + rspfile = "$RSP_FILE"; + responseFlag += rspfile; + + // build response file content + std::string linkOptionVar = cmakeVarLang; + linkOptionVar += "_COMPILER_LINKER_OPTION_FLAG_"; + linkOptionVar += cmTarget::GetTargetTypeName(targetType); + const std::string linkOption = + GetMakefile()->GetSafeDefinition(linkOptionVar.c_str()); + rspcontent = "$in " + linkOption + " $LINK_PATH $LINK_LIBRARIES"; + vars.Objects = responseFlag.c_str(); + vars.LinkLibraries = ""; + } + + vars.ObjectDir = "$OBJECT_DIR"; + + // TODO: + // Makefile generator expands <TARGET> to the plain target name + // with suffix. $out expands to a relative path. This difference + // could make trouble when switching to Ninja generator. Maybe + // using TARGET_NAME and RuleVariables::TargetName is a fix. vars.Target = "$out"; + vars.SONameFlag = "$SONAME_FLAG"; vars.TargetSOName = "$SONAME"; vars.TargetInstallNameDir = "$INSTALLNAME_DIR"; @@ -188,7 +226,6 @@ cmNinjaNormalTargetGenerator vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); - vars.LinkLibraries = "$LINK_LIBRARIES"; vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; @@ -201,7 +238,7 @@ cmNinjaNormalTargetGenerator vars.LanguageCompileFlags = langFlags.c_str(); } - // Rule for linking library. + // Rule for linking library/executable. std::vector<std::string> linkCmds = this->ComputeLinkCmd(); for(std::vector<std::string>::iterator i = linkCmds.begin(); i != linkCmds.end(); @@ -214,17 +251,20 @@ cmNinjaNormalTargetGenerator std::string linkCmd = this->GetLocalGenerator()->BuildCommandLine(linkCmds); - // Write the linker rule. - std::ostringstream comment; + // Write the linker rule with response file if needed. + cmOStringStream comment; comment << "Rule for linking " << this->TargetLinkLanguage << " " << this->GetVisibleTypeName() << "."; - std::ostringstream description; + cmOStringStream description; description << "Linking " << this->TargetLinkLanguage << " " << this->GetVisibleTypeName() << " $out"; this->GetGlobalGenerator()->AddRule(ruleName, linkCmd, description.str(), - comment.str()); + comment.str(), + /*depfile*/ "", + rspfile, + rspcontent); } if (this->TargetNameOut != this->TargetNameReal) { @@ -330,6 +370,40 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() { cmTarget::TargetType targetType = this->GetTarget()->GetType(); + std::string targetOutput = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); + std::string targetOutputReal = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/false, + /*realpath=*/true).c_str()); + std::string targetOutputImplib = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/true).c_str()); + + if (this->GetTarget()->IsAppBundleOnApple()) + { + // Create the app bundle + std::string outpath; + this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath); + + // Calculate the output path + targetOutput = outpath + this->TargetNameOut; + targetOutput = this->ConvertToNinjaPath(targetOutput.c_str()); + targetOutputReal = outpath + this->TargetNameReal; + targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str()); + } + else if (this->GetTarget()->IsFrameworkOnApple()) + { + // Create the library framework. + this->OSXBundleGenerator->CreateFramework(this->TargetNameOut); + } + else if(this->GetTarget()->IsCFBundleOnApple()) + { + // Create the core foundation bundle. + std::string outpath; + this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath); + } + // Write comments. cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); this->GetBuildFileStream() @@ -342,18 +416,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaDeps emptyDeps; cmNinjaVars vars; - std::string targetOutput = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); - std::string targetOutputReal = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName(), - /*implib=*/false, - /*realpath=*/true).c_str()); - std::string targetOutputImplib = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName(), - /*implib=*/true).c_str()); - // Compute the comment. - std::ostringstream comment; + cmOStringStream comment; comment << "Link the " << this->GetVisibleTypeName() << " " << targetOutputReal; @@ -362,26 +426,36 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() outputs.push_back(targetOutputReal); // Compute specific libraries to link with. - cmNinjaDeps explicitDeps = this->GetObjects(), - implicitDeps = this->ComputeLinkDeps(); + cmNinjaDeps explicitDeps = this->GetObjects(); + cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); + std::string frameworkPath; + std::string linkPath; this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], vars["LINK_FLAGS"], - *this->GetTarget()); + frameworkPath, + linkPath, + this->GetGeneratorTarget()); this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); + vars["LINK_PATH"] = frameworkPath + linkPath; // Compute architecture specific link flags. Yes, these go into a different // variable for executables, probably due to a mistake made when duplicating // code between the Makefile executable and library generators. - this->GetLocalGenerator() - ->AddArchitectureFlags(targetType == cmTarget::EXECUTABLE + std::string flags = (targetType == cmTarget::EXECUTABLE ? vars["FLAGS"] - : vars["ARCH_FLAGS"], - this->GetTarget(), + : vars["ARCH_FLAGS"]); + this->GetLocalGenerator()->AddArchitectureFlags(flags, + this->GetGeneratorTarget(), this->TargetLinkLanguage, this->GetConfigName()); + if (targetType == cmTarget::EXECUTABLE) { + vars["FLAGS"] = flags; + } else { + vars["ARCH_FLAGS"] = flags; + } if (this->GetTarget()->HasSOName(this->GetConfigName())) { vars["SONAME_FLAG"] = this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage); @@ -399,18 +473,39 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } } - std::string path; if (!this->TargetNameImport.empty()) { - path = this->GetLocalGenerator()->ConvertToOutputFormat( - targetOutputImplib.c_str(), cmLocalGenerator::SHELL); - vars["TARGET_IMPLIB"] = path; - EnsureParentDirectoryExists(path); + const std::string impLibPath = this->GetLocalGenerator() + ->ConvertToOutputFormat(targetOutputImplib.c_str(), + cmLocalGenerator::SHELL); + vars["TARGET_IMPLIB"] = impLibPath; + EnsureParentDirectoryExists(impLibPath); } - path = this->GetLocalGenerator()->ConvertToOutputFormat( - this->GetTargetPDB().c_str(), cmLocalGenerator::SHELL); - vars["TARGET_PDB"] = path; - EnsureParentDirectoryExists(path); + cmMakefile* mf = this->GetMakefile(); + if (!this->SetMsvcTargetPdbVariable(vars)) + { + // It is common to place debug symbols at a specific place, + // so we need a plain target name in the rule available. + std::string prefix; + std::string base; + std::string suffix; + this->GetTarget()->GetFullNameComponents(prefix, base, suffix); + std::string dbg_suffix = ".dbg"; + // TODO: Where to document? + if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) + dbg_suffix = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX"); + vars["TARGET_PDB"] = base + suffix + dbg_suffix; + } + + if (mf->IsOn("CMAKE_COMPILER_IS_MINGW")) + { + const std::string objPath = GetTarget()->GetSupportDirectory(); + vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath.c_str()); + EnsureDirectoryExists(objPath); + // ar.exe can't handle backslashes in rsp files (implictly used by gcc) + std::string& linkLibraries = vars["LINK_LIBRARIES"]; + std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/'); + } std::vector<cmCustomCommand> *cmdLists[3] = { &this->GetTarget()->GetPreBuildCommands(), @@ -437,10 +532,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for // the link commands. if (!preLinkCmdLines.empty()) { - path = this->GetLocalGenerator()->ConvertToOutputFormat( - this->GetMakefile()->GetHomeOutputDirectory(), - cmLocalGenerator::SHELL); - preLinkCmdLines.push_back("cd " + path); + const std::string homeOutDir = this->GetLocalGenerator() + ->ConvertToOutputFormat(this->GetMakefile()->GetHomeOutputDirectory(), + cmLocalGenerator::SHELL); + preLinkCmdLines.push_back("cd " + homeOutDir); } vars["PRE_LINK"] = @@ -456,6 +551,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() symlinkVars["POST_BUILD"] = postBuildCmdLine; } + int linkRuleLength = this->GetGlobalGenerator()-> + GetRuleCmdLength(this->LanguageLinkerRule()); + + int commandLineLengthLimit = 1; + const char* forceRspFile = "CMAKE_NINJA_FORCE_RESPONSE_FILE"; + if (!this->GetMakefile()->IsDefinitionSet(forceRspFile) && + cmSystemTools::GetEnv(forceRspFile) == 0) { +#ifdef _WIN32 + commandLineLengthLimit = 8000 - linkRuleLength; +#elif defined(__linux) || defined(__APPLE__) + // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac + commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))-linkRuleLength-1000; +#else + commandLineLengthLimit = -1; +#endif + } + + const std::string rspfile = std::string + (cmake::GetCMakeFilesDirectoryPostSlash()) + + this->GetTarget()->GetName() + ".rsp"; + // Write the build statement for this target. cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), comment.str(), @@ -464,7 +580,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() explicitDeps, implicitDeps, emptyDeps, - vars); + vars, + rspfile, + commandLineLengthLimit); if (targetOutput != targetOutputReal) { if (targetType == cmTarget::EXECUTABLE) { @@ -477,11 +595,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() emptyDeps, symlinkVars); } else { - symlinkVars["SONAME"] = this->GetTargetFilePath(this->TargetNameSO); + cmNinjaDeps symlinks; + const std::string soName = this->GetTargetFilePath(this->TargetNameSO); + // If one link has to be created. + if (targetOutputReal == soName || targetOutput == soName) { + symlinkVars["SONAME"] = soName; + } else { + symlinkVars["SONAME"] = ""; + symlinks.push_back(soName); + } + symlinks.push_back(targetOutput); cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), "Create library symlink " + targetOutput, "CMAKE_SYMLINK_LIBRARY", - cmNinjaDeps(1, targetOutput), + symlinks, cmNinjaDeps(1, targetOutputReal), emptyDeps, emptyDeps, diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index 7acbe8f..284804b 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -15,8 +15,12 @@ # include "cmNinjaTargetGenerator.h" # include "cmNinjaTypes.h" +# include "cmStandardIncludes.h" + +# include <set> class cmSourceFile; +class cmOSXBundleGenerator; class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator { @@ -30,14 +34,11 @@ private: std::string LanguageLinkerRule() const; const char* GetVisibleTypeName() const; void WriteLanguagesRules(); - void WriteLinkRule(); + void WriteLinkRule(bool useResponseFile); void WriteLinkStatement(); void WriteObjectLibStatement(); std::vector<std::string> ComputeLinkCmd(); - void EnsureDirectoryExists(const std::string& dir); - void EnsureParentDirectoryExists(const std::string& path); - private: // Target name info. std::string TargetNameOut; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index e419a4d..0f10152 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -56,7 +56,11 @@ cmNinjaTargetGenerator::New(cmTarget* target) } cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) - : Target(target), + : + MacOSXContentGenerator(0), + OSXBundleGenerator(0), + MacContentFolders(), + Target(target), Makefile(target->GetMakefile()), LocalGenerator( static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())), @@ -64,10 +68,12 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) { this->GeneratorTarget = this->GetGlobalGenerator()->GetGeneratorTarget(target); + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); } cmNinjaTargetGenerator::~cmNinjaTargetGenerator() { + delete this->MacOSXContentGenerator; } cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const @@ -87,7 +93,7 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const const char* cmNinjaTargetGenerator::GetConfigName() const { - return this->LocalGenerator->ConfigName.c_str(); + return this->LocalGenerator->GetConfigName(); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. @@ -128,7 +134,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, this->AddFeatureFlags(flags, language.c_str()); this->GetLocalGenerator()->AddArchitectureFlags(flags, - this->GetTarget(), + this->GeneratorTarget, language.c_str(), this->GetConfigName()); @@ -140,31 +146,64 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, // } // Add shared-library flags if needed. - { - bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || - (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); - this->GetLocalGenerator()->AddSharedFlags(flags, language.c_str(), shared); - } + this->LocalGenerator->AddCMP0018Flags(flags, this->Target, + language.c_str()); - // TODO: Handle response file. // Add include directory flags. { std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target, - language.c_str()); + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + language.c_str(), config); std::string includeFlags = - this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), false); + this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), + language == "RC" ? true : false); // full include paths for RC + // needed by cmcldeps + if(cmGlobalNinjaGenerator::IsMinGW()) + cmSystemTools::ReplaceString(includeFlags, "\\", "/"); + this->LocalGenerator->AppendFlags(flags, includeFlags.c_str()); } // Append old-style preprocessor definition flags. this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags()); - // Add target-specific and source-specific flags. - this->LocalGenerator->AppendFlags(flags, - this->Target->GetProperty("COMPILE_FLAGS")); - this->LocalGenerator->AppendFlags(flags, - source->GetProperty("COMPILE_FLAGS")); + // Add target-specific flags. + if(this->Target->GetProperty("COMPILE_FLAGS")) + { + std::string langIncludeExpr = "CMAKE_"; + langIncludeExpr += language; + langIncludeExpr += "_FLAG_REGEX"; + const char* regex = this->Makefile-> + GetDefinition(langIncludeExpr.c_str()); + if(regex) + { + cmsys::RegularExpression r(regex); + std::vector<std::string> args; + cmSystemTools::ParseWindowsCommandLine( + this->Target->GetProperty("COMPILE_FLAGS"), + args); + for(std::vector<std::string>::iterator i = args.begin(); + i != args.end(); ++i) + { + if(r.find(i->c_str())) + { + this->LocalGenerator->AppendFlags + (flags, i->c_str()); + } + } + } + else + { + this->LocalGenerator->AppendFlags + (flags, this->Target->GetProperty("COMPILE_FLAGS")); + } + } + + // Add source file specific flags. + this->LocalGenerator->AppendFlags(flags, + source->GetProperty("COMPILE_FLAGS")); // TODO: Handle Apple frameworks. @@ -177,46 +216,37 @@ std::string cmNinjaTargetGenerator:: ComputeDefines(cmSourceFile *source, const std::string& language) { - std::string defines; + std::set<std::string> defines; // Add the export symbol definition for shared library objects. if(const char* exportMacro = this->Target->GetExportMacro()) { - this->LocalGenerator->AppendDefines(defines, exportMacro, - language.c_str()); + this->LocalGenerator->AppendDefines(defines, exportMacro); } // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines (defines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS"), - language.c_str()); + this->GeneratorTarget->GetCompileDefinitions()); this->LocalGenerator->AppendDefines (defines, - this->Target->GetProperty("COMPILE_DEFINITIONS"), - language.c_str()); - this->LocalGenerator->AppendDefines - (defines, - source->GetProperty("COMPILE_DEFINITIONS"), - language.c_str()); + source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; defPropName += cmSystemTools::UpperCase(this->GetConfigName()); this->LocalGenerator->AppendDefines (defines, - this->Makefile->GetProperty(defPropName.c_str()), - language.c_str()); - this->LocalGenerator->AppendDefines - (defines, - this->Target->GetProperty(defPropName.c_str()), - language.c_str()); + this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName())); this->LocalGenerator->AppendDefines (defines, - source->GetProperty(defPropName.c_str()), - language.c_str()); + source->GetProperty(defPropName.c_str())); } - return defines; + std::string definesString; + this->LocalGenerator->JoinDefines(defines, definesString, + language.c_str()); + + return definesString; } cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const @@ -227,7 +257,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const return cmNinjaDeps(); cmComputeLinkInformation* cli = - this->Target->GetLinkInformation(this->GetConfigName()); + this->GeneratorTarget->GetLinkInformation(this->GetConfigName()); if(!cli) return cmNinjaDeps(); @@ -288,31 +318,42 @@ std::string cmNinjaTargetGenerator::GetTargetName() const return this->Target->GetName(); } -std::string cmNinjaTargetGenerator::GetTargetPDB() const + +bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const { - std::string targetFullPathPDB; - if(this->Target->GetType() == cmTarget::EXECUTABLE || - this->Target->GetType() == cmTarget::STATIC_LIBRARY || - this->Target->GetType() == cmTarget::SHARED_LIBRARY || - this->Target->GetType() == cmTarget::MODULE_LIBRARY) + cmMakefile* mf = this->GetMakefile(); + if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") || + mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID")) { - targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); - targetFullPathPDB += "/"; - targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); - } + std::string pdbPath; + if(this->Target->GetType() == cmTarget::EXECUTABLE || + this->Target->GetType() == cmTarget::STATIC_LIBRARY || + this->Target->GetType() == cmTarget::SHARED_LIBRARY || + this->Target->GetType() == cmTarget::MODULE_LIBRARY) + { + pdbPath = this->Target->GetPDBDirectory(this->GetConfigName()); + pdbPath += "/"; + pdbPath += this->Target->GetPDBName(this->GetConfigName()); + } - return ConvertToNinjaPath(targetFullPathPDB.c_str()); + vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( + ConvertToNinjaPath(pdbPath.c_str()).c_str(), + cmLocalGenerator::SHELL); + EnsureParentDirectoryExists(pdbPath); + return true; + } + return false; } - void cmNinjaTargetGenerator ::WriteLanguageRules(const std::string& language) { +#ifdef NINJA_GEN_VERBOSE_FILES this->GetRulesFileStream() << "# Rules for language " << language << "\n\n"; +#endif this->WriteCompileRule(language); - this->GetRulesFileStream() << "\n"; } void @@ -329,21 +370,47 @@ cmNinjaTargetGenerator std::string flags = "$FLAGS"; vars.Defines = "$DEFINES"; vars.TargetPDB = "$TARGET_PDB"; + vars.ObjectDir = "$OBJECT_DIR"; + + cmMakefile* mf = this->GetMakefile(); + + bool useClDeps = false; + std::string clBinary; + std::string clDepsBinary; + std::string clShowPrefix; + if (lang == "C" || lang == "CXX" || lang == "RC") + { + clDepsBinary = mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); + if (!clDepsBinary.empty() && !mf->GetIsSourceFileTryCompile()) + { + clShowPrefix = mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX"); + clBinary = mf->GetDefinition("CMAKE_C_COMPILER") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); + if (!clBinary.empty() && !clShowPrefix.empty()) + { + useClDeps = true; + const std::string quote = " \""; + clBinary = quote + clBinary + "\" "; + clDepsBinary = quote + clDepsBinary + "\" "; + clShowPrefix = quote + clShowPrefix + "\" "; + vars.DependencyFile = "$DEP_FILE"; + } + } + } + std::string depfile; std::string depfileFlagsName = "CMAKE_DEPFILE_FLAGS_" + language; - const char *depfileFlags = - this->GetMakefile()->GetDefinition(depfileFlagsName.c_str()); - if (depfileFlags) { - std::string depfileFlagsStr = depfileFlags; - depfile = "$out.d"; - cmSystemTools::ReplaceString(depfileFlagsStr, "<DEPFILE>", - depfile.c_str()); - cmSystemTools::ReplaceString(depfileFlagsStr, "<OBJECT>", - "$out"); - cmSystemTools::ReplaceString(depfileFlagsStr, "<CMAKE_C_COMPILER>", - this->GetMakefile()->GetDefinition("CMAKE_C_COMPILER")); - flags += " " + depfileFlagsStr; + const char *depfileFlags = mf->GetDefinition(depfileFlagsName.c_str()); + if (depfileFlags || useClDeps) { + std::string depFlagsStr = depfileFlags ? depfileFlags : ""; + depfile = "$DEP_FILE"; + cmSystemTools::ReplaceString(depFlagsStr, "<DEPFILE>", "\"$DEP_FILE\""); + cmSystemTools::ReplaceString(depFlagsStr, "<OBJECT>", "$out"); + cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>", + mf->GetDefinition("CMAKE_C_COMPILER")); + flags += " " + depFlagsStr; } vars.Flags = flags.c_str(); @@ -352,8 +419,7 @@ cmNinjaTargetGenerator std::string compileCmdVar = "CMAKE_"; compileCmdVar += language; compileCmdVar += "_COMPILE_OBJECT"; - std::string compileCmd = - this->GetMakefile()->GetRequiredDefinition(compileCmdVar.c_str()); + std::string compileCmd = mf->GetRequiredDefinition(compileCmdVar.c_str()); std::vector<std::string> compileCmds; cmSystemTools::ExpandListArgument(compileCmd, compileCmds); @@ -361,13 +427,19 @@ cmNinjaTargetGenerator i != compileCmds.end(); ++i) this->GetLocalGenerator()->ExpandRuleVariables(*i, vars); - std::string cmdLine = - this->GetLocalGenerator()->BuildCommandLine(compileCmds); + std::string cmdLine; + if(useClDeps) + { + cmdLine = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " + + clShowPrefix + clBinary; + } + cmdLine += this->GetLocalGenerator()->BuildCommandLine(compileCmds); + // Write the rule for compiling file of the given language. - std::ostringstream comment; + cmOStringStream comment; comment << "Rule for compiling " << language << " files."; - std::ostringstream description; + cmOStringStream description; description << "Building " << language << " object $out"; this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(language), cmdLine, @@ -396,6 +468,12 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); } + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); for(std::vector<cmSourceFile*>::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -432,10 +510,8 @@ void cmNinjaTargetGenerator ::WriteObjectBuildStatement(cmSourceFile* source) { - cmNinjaDeps emptyDeps; - std::string comment; - const char* language = source->GetLanguage(); + const std::string language = source->GetLanguage(); std::string rule = this->LanguageCompilerRule(language); cmNinjaDeps outputs; @@ -445,7 +521,11 @@ cmNinjaTargetGenerator this->Objects.push_back(objectFileName); cmNinjaDeps explicitDeps; - std::string sourceFileName = this->GetSourceFilePath(source); + std::string sourceFileName; + if (language == "RC") + sourceFileName = source->GetFullPath(); + else + sourceFileName = this->GetSourceFilePath(source); explicitDeps.push_back(sourceFileName); // Ensure that the target dependencies are built before any source file in @@ -453,11 +533,12 @@ cmNinjaTargetGenerator cmNinjaDeps orderOnlyDeps; this->GetLocalGenerator()->AppendTargetDepends(this->Target, orderOnlyDeps); + cmNinjaDeps implicitDeps; if(const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) { std::vector<std::string> depList; cmSystemTools::ExpandListArgument(objectDeps, depList); std::transform(depList.begin(), depList.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::back_inserter(implicitDeps), MapToNinjaPath()); } // Add order-only dependencies on custom command outputs. @@ -468,7 +549,7 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); const std::vector<std::string>& ccoutputs = cc->GetOutputs(); std::transform(ccoutputs.begin(), ccoutputs.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::back_inserter(implicitDeps), MapToNinjaPath()); } // If the source file is GENERATED and does not have a custom command @@ -484,19 +565,41 @@ cmNinjaTargetGenerator cmNinjaVars vars; vars["FLAGS"] = this->ComputeFlagsForObject(source, language); vars["DEFINES"] = this->ComputeDefines(source, language); - vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( - this->GetTargetPDB().c_str(), cmLocalGenerator::SHELL); + vars["DEP_FILE"] = objectFileName + ".d";; + EnsureParentDirectoryExists(objectFileName); + + std::string objectDir = cmSystemTools::GetFilenamePath(objectFileName); + objectDir = this->GetLocalGenerator()->Convert(objectDir.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + vars["OBJECT_DIR"] = objectDir; + + + this->SetMsvcTargetPdbVariable(vars); if(this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS")) { cmLocalGenerator::RuleVariables compileObjectVars; std::string lang = language; compileObjectVars.Language = lang.c_str(); - std::string escapedSourceFileName = + + std::string escapedSourceFileName = sourceFileName; + + if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str())) + { + escapedSourceFileName = cmSystemTools::CollapseFullPath( + escapedSourceFileName.c_str(), + this->GetGlobalGenerator()->GetCMakeInstance()-> + GetHomeOutputDirectory()); + } + + escapedSourceFileName = this->LocalGenerator->ConvertToOutputFormat( - sourceFileName.c_str(), cmLocalGenerator::SHELL); + escapedSourceFileName.c_str(), cmLocalGenerator::SHELL); + compileObjectVars.Source = escapedSourceFileName.c_str(); compileObjectVars.Object = objectFileName.c_str(); + compileObjectVars.ObjectDir = objectDir.c_str(); compileObjectVars.Flags = vars["FLAGS"].c_str(); compileObjectVars.Defines = vars["DEFINES"].c_str(); @@ -525,7 +628,7 @@ cmNinjaTargetGenerator rule, outputs, explicitDeps, - emptyDeps, + implicitDeps, orderOnlyDeps, vars); @@ -566,3 +669,62 @@ cmNinjaTargetGenerator this->ModuleDefinitionFile.c_str())); this->LocalGenerator->AppendFlags(flags, flag.c_str()); } + +void +cmNinjaTargetGenerator +::EnsureDirectoryExists(const std::string& path) const +{ + if (cmSystemTools::FileIsFullPath(path.c_str())) + { + cmSystemTools::MakeDirectory(path.c_str()); + } + else + { + const std::string fullPath = std::string(this->GetGlobalGenerator()-> + GetCMakeInstance()->GetHomeOutputDirectory()) + + "/" + path; + cmSystemTools::MakeDirectory(fullPath.c_str()); + } +} + +void +cmNinjaTargetGenerator +::EnsureParentDirectoryExists(const std::string& path) const +{ + EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); +} + + +//---------------------------------------------------------------------------- +void +cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()( + cmSourceFile& source, const char* pkgloc) +{ + // Skip OS X content when not building a Framework or Bundle. + if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty()) + { + return; + } + + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); + + // Get the input file location. + std::string input = source.GetFullPath(); + input = + this->Generator->GetLocalGenerator()->ConvertToNinjaPath(input.c_str()); + + // Get the output file location. + std::string output = macdir; + output += "/"; + output += cmSystemTools::GetFilenameName(input); + output = + this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output.c_str()); + + // Write a build statement to copy the content into the bundle. + this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input, + output); + + // Add as a dependency of all target so that it gets called. + this->Generator->GetGlobalGenerator()->AddDependencyToAll(output); +} diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index b64ce1e..cf06bfd 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -16,6 +16,7 @@ #include "cmStandardIncludes.h" #include "cmNinjaTypes.h" #include "cmLocalNinjaGenerator.h" +#include "cmOSXBundleGenerator.h" class cmTarget; class cmGlobalNinjaGenerator; @@ -39,16 +40,21 @@ public: virtual void Generate() = 0; - std::string GetTargetPDB() const; std::string GetTargetName() const; protected: + + bool SetMsvcTargetPdbVariable(cmNinjaVars&) const; + cmGeneratedFileStream& GetBuildFileStream() const; cmGeneratedFileStream& GetRulesFileStream() const; cmTarget* GetTarget() const { return this->Target; } + cmGeneratorTarget* GetGeneratorTarget() const + { return this->GeneratorTarget; } + cmLocalNinjaGenerator* GetLocalGenerator() const { return this->LocalGenerator; } @@ -111,6 +117,30 @@ protected: // Helper to add flag for windows .def file. void AddModuleDefinitionFlag(std::string& flags); + void EnsureDirectoryExists(const std::string& dir) const; + void EnsureParentDirectoryExists(const std::string& path) const; + + // write rules for Mac OS X Application Bundle content. + struct MacOSXContentGeneratorType : + cmOSXBundleGenerator::MacOSXContentGeneratorType + { + MacOSXContentGeneratorType(cmNinjaTargetGenerator* g) : + Generator(g) {} + + void operator()(cmSourceFile& source, const char* pkgloc); + + private: + cmNinjaTargetGenerator* Generator; + }; + friend struct MacOSXContentGeneratorType; + +protected: + MacOSXContentGeneratorType* MacOSXContentGenerator; + // Properly initialized by sub-classes. + cmOSXBundleGenerator* OSXBundleGenerator; + std::set<cmStdString> MacContentFolders; + + private: cmTarget* Target; cmGeneratorTarget* GeneratorTarget; diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx new file mode 100644 index 0000000..42fad07 --- /dev/null +++ b/Source/cmOSXBundleGenerator.cxx @@ -0,0 +1,236 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmOSXBundleGenerator.h" +#include "cmMakefile.h" +#include "cmTarget.h" +#include "cmLocalGenerator.h" + +#include <cassert> + +void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target) +{ + if(target->IsCFBundleOnApple()) + { + target->SetProperty("PREFIX", ""); + target->SetProperty("SUFFIX", ""); + } +} + +//---------------------------------------------------------------------------- +cmOSXBundleGenerator:: +cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName) + : Target(target) + , Makefile(target->GetMakefile()) + , LocalGenerator(Makefile->GetLocalGenerator()) + , TargetNameOut(targetNameOut) + , ConfigName(configName) + , MacContentDirectory() + , FrameworkVersion() + , MacContentFolders(0) +{ + if (this->MustSkip()) + return; + + this->MacContentDirectory = + this->Target->GetMacContentDirectory(this->ConfigName, + /*implib*/ false, + /*includeMacOS*/ false); + if(this->Target->IsFrameworkOnApple()) + this->FrameworkVersion = this->Target->GetFrameworkVersion(); +} + +//---------------------------------------------------------------------------- +bool cmOSXBundleGenerator::MustSkip() +{ + return !this->Target->HaveWellDefinedOutputFiles(); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory + "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) +{ + if (this->MustSkip()) + return; + + assert(this->MacContentFolders); + + // Configure the Info.plist file into the Resources directory. + this->MacContentFolders->insert("Resources"); + std::string plist = this->MacContentDirectory + "Resources/Info.plist"; + this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + + // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to + // drive rules to create these files at build time. + std::string oldName; + std::string newName; + + // Compute the location of the top-level foo.framework directory. + std::string top = this->Target->GetDirectory(this->ConfigName); + top += "/"; + top += this->TargetNameOut; + top += ".framework/"; + + // Make foo.framework/Versions + std::string versions = top; + versions += "Versions"; + cmSystemTools::MakeDirectory(versions.c_str()); + + // Make foo.framework/Versions/version + std::string version = versions; + version += "/"; + version += this->FrameworkVersion; + cmSystemTools::MakeDirectory(version.c_str()); + + // Current -> version + oldName = this->FrameworkVersion; + newName = versions; + newName += "/Current"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // foo -> Versions/Current/foo + oldName = "Versions/Current/"; + oldName += this->TargetNameOut; + newName = top; + newName += this->TargetNameOut; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // Resources -> Versions/Current/Resources + if(this->MacContentFolders->find("Resources") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/Resources"; + newName = top; + newName += "Resources"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + + // Headers -> Versions/Current/Headers + if(this->MacContentFolders->find("Headers") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/Headers"; + newName = top; + newName += "Headers"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + + // PrivateHeaders -> Versions/Current/PrivateHeaders + if(this->MacContentFolders->find("PrivateHeaders") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/PrivateHeaders"; + newName = top; + newName += "PrivateHeaders"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory; + plist += "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void +cmOSXBundleGenerator:: +GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources, + MacOSXContentGeneratorType* generator) +{ + if (this->MustSkip()) + return; + + for(std::vector<cmSourceFile*>::const_iterator + si = sources.begin(); si != sources.end(); ++si) + { + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(*si); + if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + { + (*generator)(**si, tsFlags.MacFolder); + } + } +} + +//---------------------------------------------------------------------------- +std::string +cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc) +{ + // Construct the full path to the content subdirectory. + std::string macdir = this->MacContentDirectory; + macdir += pkgloc; + cmSystemTools::MakeDirectory(macdir.c_str()); + + // Record use of this content location. Only the first level + // directory is needed. + { + std::string loc = pkgloc; + loc = loc.substr(0, loc.find('/')); + this->MacContentFolders->insert(loc); + } + + return macdir; +} diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h new file mode 100644 index 0000000..01e3cbe --- /dev/null +++ b/Source/cmOSXBundleGenerator.h @@ -0,0 +1,71 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmOSXBundleGenerator_h +#define cmOSXBundleGenerator_h + +#include "cmStandardIncludes.h" +#include "cmSourceFile.h" + +#include <string> +#include <set> + +class cmTarget; +class cmMakefile; +class cmLocalGenerator; + +class cmOSXBundleGenerator +{ +public: + static void PrepareTargetProperties(cmTarget* target); + + cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName); + + void CreateAppBundle(std::string& targetName, std::string& outpath); + void CreateFramework(std::string const& targetName); + void CreateCFBundle(std::string& targetName, std::string& outpath); + + struct MacOSXContentGeneratorType + { + virtual ~MacOSXContentGeneratorType() {} + virtual void operator()(cmSourceFile& source, const char* pkgloc) = 0; + }; + + void GenerateMacOSXContentStatements( + std::vector<cmSourceFile*> const& sources, + MacOSXContentGeneratorType* generator); + std::string InitMacOSXContentDirectory(const char* pkgloc); + + std::string GetMacContentDirectory() const + { return this->MacContentDirectory; } + std::string GetFrameworkVersion() const + { return this->FrameworkVersion; } + void SetMacContentFolders(std::set<cmStdString>* macContentFolders) + { this->MacContentFolders = macContentFolders; } + +private: + bool MustSkip(); + +private: + cmTarget* Target; + cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; + std::string TargetNameOut; + const char* ConfigName; + std::string MacContentDirectory; + std::string FrameworkVersion; + std::set<cmStdString>* MacContentFolders; +}; + + +#endif diff --git a/Source/cmObject.h b/Source/cmObject.h index 1a39aa7..ca6a54f 100644 --- a/Source/cmObject.h +++ b/Source/cmObject.h @@ -27,7 +27,7 @@ public: * Need virtual destructor to destroy real command type. */ virtual ~cmObject() {} - + /** * The class name of the command. */ @@ -38,7 +38,7 @@ public: */ static bool IsTypeOf(const char *type) { return !strcmp("cmObject", type); } - + /** * Returns true if this object is an instance of the given class or * a subclass of it. diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index af9d94b..776a3a4 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -42,11 +42,11 @@ bool cmOptionCommand this->SetError(m.c_str()); return false; } - + std::string initialValue = "Off"; // Now check and see if the value has been stored in the cache // already, if so use that value and don't look for the program - cmCacheManager::CacheIterator it = + cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->GetCacheIterator(args[0].c_str()); if(!it.IsAtEnd()) { diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h index da31332..7d02400 100644 --- a/Source/cmOptionCommand.h +++ b/Source/cmOptionCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmOptionCommand; } @@ -41,7 +41,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "option";} - + /** * Succinct documentation. */ @@ -49,7 +49,7 @@ public: { return "Provides an option that the user can optionally select."; } - + /** * More documentation. */ diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 775a4eb..96a75de 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -48,7 +48,6 @@ private: std::vector<std::string> OrderedDirectories; - bool OrderedDirectoriesComputed; std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries; std::vector<cmOrderDirectoriesConstraint*> ImplicitDirEntries; std::vector<std::string> UserDirectories; diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index be079c0..01fc2cf 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -28,7 +28,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) cmSystemTools::Error("error can not open ", info->FullPath.c_str()); return; } - + std::string line; while(cmSystemTools::GetLineFromStream(fin, line)) { @@ -45,7 +45,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) // if a < is not found then move on if(qstart == std::string::npos) { - cmSystemTools::Error("unknown include directive ", + cmSystemTools::Error("unknown include directive ", currentline.c_str() ); continue; } @@ -73,7 +73,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) } continue; } - + // Add this file and all its dependencies. this->AddDependency(info, includeFile.c_str()); /// add the cxx file if it exists @@ -89,7 +89,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) { found = true; } - for(std::vector<std::string>::iterator i = + for(std::vector<std::string>::iterator i = this->IncludeDirectories.begin(); i != this->IncludeDirectories.end(); ++i) { @@ -108,7 +108,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) { found = true; } - for(std::vector<std::string>::iterator i = + for(std::vector<std::string>::iterator i = this->IncludeDirectories.begin(); i != this->IncludeDirectories.end(); ++i) { @@ -128,7 +128,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) { found = true; } - for(std::vector<std::string>::iterator i = + for(std::vector<std::string>::iterator i = this->IncludeDirectories.begin(); i != this->IncludeDirectories.end(); ++i) { @@ -148,7 +148,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) { found = true; } - for(std::vector<std::string>::iterator i = + for(std::vector<std::string>::iterator i = this->IncludeDirectories.begin(); i != this->IncludeDirectories.end(); ++i) { @@ -183,7 +183,7 @@ bool cmOutputRequiredFilesCommand // store the arg for final pass this->File = args[0]; this->OutputFile = args[1]; - + // compute the list of files cmLBDepend md; md.SetMakefile(this->Makefile); @@ -217,7 +217,7 @@ ListDependencies(cmDependInformation const *info, // add info to the visited set visited->insert(info); // now recurse with info's dependencies - for(cmDependInformation::DependencySetType::const_iterator d = + for(cmDependInformation::DependencySetType::const_iterator d = info->DependencySet.begin(); d != info->DependencySet.end(); ++d) { diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h index 85d9095..1d7e394 100644 --- a/Source/cmOutputRequiredFilesCommand.h +++ b/Source/cmOutputRequiredFilesCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmOutputRequiredFilesCommand; } @@ -49,7 +49,7 @@ public: { return "Deprecated. Approximate C preprocessor dependency scanning."; } - + /** * More documentation. */ @@ -72,7 +72,7 @@ public: return true; } - + cmTypeMacro(cmOutputRequiredFilesCommand, cmCommand); void ListDependencies(cmDependInformation const *info, FILE *fout, diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 37070b6..79af4d7 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -463,6 +463,34 @@ cmPolicies::cmPolicies() "The OLD behaviour is to always prefer files from CMAKE_MODULE_PATH over " "files from the CMake modules directory.", 2,8,4,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0018, "CMP0018", + "Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.", + "CMake 2.8.8 and lower compiled sources in SHARED and MODULE libraries " + "using the value of the undocumented CMAKE_SHARED_LIBRARY_<Lang>_FLAGS " + "platform variable. The variable contained platform-specific flags " + "needed to compile objects for shared libraries. Typically it included " + "a flag such as -fPIC for position independent code but also included " + "other flags needed on certain platforms. CMake 2.8.9 and higher " + "prefer instead to use the POSITION_INDEPENDENT_CODE target property to " + "determine what targets should be position independent, and new " + "undocumented platform variables to select flags while ignoring " + "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS completely." + "\n" + "The default for either approach produces identical compilation flags, " + "but if a project modifies CMAKE_SHARED_LIBRARY_<Lang>_FLAGS from its " + "original value this policy determines which approach to use." + "\n" + "The OLD behavior for this policy is to ignore the " + "POSITION_INDEPENDENT_CODE property for all targets and use the modified " + "value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS for SHARED and MODULE " + "libraries." + "\n" + "The NEW behavior for this policy is to ignore " + "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and " + "honor the POSITION_INDEPENDENT_CODE target property.", + 2,8,9,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 3106248..6932565 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -65,6 +65,9 @@ public: /// target_link_libraries() fails if only argument is not a target CMP0016, CMP0017, ///< Prefer files in CMAKE_ROOT when including from CMAKE_ROOT + CMP0018, ///< Ignore language flags for shared libs, and adhere to + /// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C} + /// instead. /** \brief Always the last entry. * diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index fcf0a49..11f9a76 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -19,14 +19,14 @@ bool cmProjectCommand { this->SetError("PROJECT called with incorrect number of arguments"); return false; - } + } this->Makefile->SetProjectName(args[0].c_str()); std::string bindir = args[0]; bindir += "_BINARY_DIR"; std::string srcdir = args[0]; srcdir += "_SOURCE_DIR"; - + this->Makefile->AddCacheDefinition (bindir.c_str(), this->Makefile->GetCurrentOutputDirectory(), @@ -35,7 +35,7 @@ bool cmProjectCommand (srcdir.c_str(), this->Makefile->GetCurrentDirectory(), "Value Computed by CMake", cmCacheManager::STATIC); - + bindir = "PROJECT_BINARY_DIR"; srcdir = "PROJECT_SOURCE_DIR"; diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h index 4b051af..a53cb3f 100644 --- a/Source/cmProjectCommand.h +++ b/Source/cmProjectCommand.h @@ -28,7 +28,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmProjectCommand; } @@ -39,7 +39,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -52,7 +52,7 @@ public: { return "Set a name for the entire project."; } - + /** * More documentation. */ @@ -69,11 +69,11 @@ public: "C++ compiler, you can disable the check for it by explicitly listing " "the languages you want to support, e.g. C. By using the special " "language \"NONE\" all checks for any language can be disabled. " - "If a variable exists called CMAKE_PROJECT_<projectName>_INCLUDE_FILE, " + "If a variable exists called CMAKE_PROJECT_<projectName>_INCLUDE, " "the file pointed to by that variable will be included as the last step " "of the project command."; } - + cmTypeMacro(cmProjectCommand, cmCommand); }; diff --git a/Source/cmProperty.h b/Source/cmProperty.h index e0fcd63..bb75bb0 100644 --- a/Source/cmProperty.h +++ b/Source/cmProperty.h @@ -14,7 +14,7 @@ #include "cmStandardIncludes.h" -class cmProperty +class cmProperty { public: enum ScopeType { TARGET, SOURCE_FILE, DIRECTORY, GLOBAL, CACHE, diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h index 16bd148..296366d 100644 --- a/Source/cmPropertyDefinition.h +++ b/Source/cmPropertyDefinition.h @@ -29,7 +29,7 @@ public: /// Define this property void DefineProperty(const char *name, cmProperty::ScopeType scope, const char *ShortDescription, - const char *FullDescription, + const char *FullDescription, const char *DocumentationSection, bool chained); @@ -44,7 +44,7 @@ public: /// Get the section if any const std::string &GetDocumentationSection() const { - return this->DocumentationSection; }; + return this->DocumentationSection; }; /// Get the scope cmProperty::ScopeType GetScope() const { @@ -56,7 +56,7 @@ public: /// Get the documentation (full version) const std::string &GetFullDescription() const { - return this->FullDescription; }; + return this->FullDescription; }; protected: std::string Name; diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx index fcdb937..20fa07c 100644 --- a/Source/cmPropertyDefinitionMap.cxx +++ b/Source/cmPropertyDefinitionMap.cxx @@ -30,7 +30,7 @@ void cmPropertyDefinitionMap if (it == this->end()) { prop = &(*this)[name]; - prop->DefineProperty(name,scope,ShortDescription, FullDescription, + prop->DefineProperty(name,scope,ShortDescription, FullDescription, DocumentationSection, chain); } } @@ -49,10 +49,10 @@ void cmPropertyDefinitionMap { switch (j->second.GetScope()) { - case cmProperty::GLOBAL: + case cmProperty::GLOBAL: secName = "Properties of Global Scope"; break; - case cmProperty::TARGET: + case cmProperty::TARGET: secName = "Properties on Targets"; break; case cmProperty::SOURCE_FILE: @@ -80,7 +80,7 @@ void cmPropertyDefinitionMap } if (!v[secName]) { - v[secName] = new + v[secName] = new cmDocumentationSection(secName.c_str(), cmSystemTools::UpperCase(secName).c_str()); } diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h index c6f9d59..007e265 100644 --- a/Source/cmPropertyDefinitionMap.h +++ b/Source/cmPropertyDefinitionMap.h @@ -16,7 +16,7 @@ class cmDocumentationSection; -class cmPropertyDefinitionMap : +class cmPropertyDefinitionMap : public std::map<cmStdString,cmPropertyDefinition> { public: diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index a4d0bf3..78f378a 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -43,7 +43,7 @@ void cmPropertyMap::SetProperty(const char *name, const char *value, #ifdef CMAKE_STRICT if (!this->CMakeInstance) { - cmSystemTools::Error("CMakeInstance not set on a property map!"); + cmSystemTools::Error("CMakeInstance not set on a property map!"); abort(); } else @@ -85,10 +85,10 @@ void cmPropertyMap::AppendProperty(const char* name, const char* value, } const char *cmPropertyMap -::GetPropertyValue(const char *name, - cmProperty::ScopeType scope, +::GetPropertyValue(const char *name, + cmProperty::ScopeType scope, bool &chain) const -{ +{ chain = false; if (!name) { @@ -99,7 +99,7 @@ const char *cmPropertyMap #ifdef CMAKE_STRICT if (!this->CMakeInstance) { - cmSystemTools::Error("CMakeInstance not set on a property map!"); + cmSystemTools::Error("CMakeInstance not set on a property map!"); abort(); } else diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h index 94275e2..0c3aad4 100644 --- a/Source/cmPropertyMap.h +++ b/Source/cmPropertyMap.h @@ -21,13 +21,13 @@ class cmPropertyMap : public std::map<cmStdString,cmProperty> public: cmProperty *GetOrCreateProperty(const char *name); - void SetProperty(const char *name, const char *value, + void SetProperty(const char *name, const char *value, cmProperty::ScopeType scope); void AppendProperty(const char* name, const char* value, cmProperty::ScopeType scope, bool asString=false); - const char *GetPropertyValue(const char *name, + const char *GetPropertyValue(const char *name, cmProperty::ScopeType scope, bool &chain) const; diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx index 1f1aed7..0d3c994 100644 --- a/Source/cmQTWrapCPPCommand.cxx +++ b/Source/cmQTWrapCPPCommand.cxx @@ -12,7 +12,7 @@ #include "cmQTWrapCPPCommand.h" // cmQTWrapCPPCommand -bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn, +bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &) { if(argsIn.size() < 3 ) diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h index 0184927..4863402 100644 --- a/Source/cmQTWrapCPPCommand.h +++ b/Source/cmQTWrapCPPCommand.h @@ -17,9 +17,9 @@ #include "cmSourceFile.h" /** \class cmQTWrapCPPCommand - * \brief Create moc file rules for QT classes + * \brief Create moc file rules for Qt classes * - * cmQTWrapCPPCommand is used to create wrappers for QT classes into + * cmQTWrapCPPCommand is used to create wrappers for Qt classes into * normal C++ */ class cmQTWrapCPPCommand : public cmCommand @@ -30,7 +30,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmQTWrapCPPCommand; } @@ -54,7 +54,7 @@ public: { return "Create Qt Wrappers."; } - + /** * More documentation. */ diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx index bbecd8d..a6a4b51 100644 --- a/Source/cmQTWrapUICommand.cxx +++ b/Source/cmQTWrapUICommand.cxx @@ -12,7 +12,7 @@ #include "cmQTWrapUICommand.h" // cmQTWrapUICommand -bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn, +bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &) { if(argsIn.size() < 4 ) diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h index 744ae98..b15c5cd 100644 --- a/Source/cmQTWrapUICommand.h +++ b/Source/cmQTWrapUICommand.h @@ -17,9 +17,9 @@ #include "cmSourceFile.h" /** \class cmQTWrapUICommand - * \brief Create .h and .cxx files rules for QT user interfaces files + * \brief Create .h and .cxx files rules for Qt user interfaces files * - * cmQTWrapUICommand is used to create wrappers for QT classes into normal C++ + * cmQTWrapUICommand is used to create wrappers for Qt classes into normal C++ */ class cmQTWrapUICommand : public cmCommand { @@ -28,7 +28,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmQTWrapUICommand; } @@ -52,7 +52,7 @@ public: { return "Create Qt user interfaces Wrappers."; } - + /** * More documentation. */ diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index ca27530..942c7ab 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -18,6 +18,7 @@ #include "cmSystemTools.h" #include <cmsys/Terminal.h> +#include <cmsys/ios/sstream> #include <string.h> #if defined(__APPLE__) @@ -110,6 +111,7 @@ cmQtAutomoc::cmQtAutomoc() void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) { cmMakefile* makefile = target->GetMakefile(); + cmLocalGenerator* localGen = makefile->GetLocalGenerator(); const char* targetName = target->GetName(); // don't do anything if there is no Qt4 or Qt5Core (which contains moc): std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); @@ -168,7 +170,8 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) ++fileIt) { cmSourceFile* sf = *fileIt; - std::string absFile = sf->GetFullPath(); + std::string absFile = cmsys::SystemTools::GetRealPath( + sf->GetFullPath().c_str()); bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")); @@ -192,12 +195,28 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } } - const char* tmp = makefile->GetProperty("INCLUDE_DIRECTORIES"); - std::string _moc_incs = (tmp!=0 ? tmp : ""); - tmp = makefile->GetProperty("DEFINITIONS"); - std::string _moc_defs = (tmp!=0 ? tmp : ""); - tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); + std::vector<std::string> includeDirs; + cmGeneratorTarget gtgt(target); + localGen->GetIncludeDirectories(includeDirs, >gt, "CXX"); + std::string _moc_incs = ""; + const char* sep = ""; + for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin(); + incDirIt != includeDirs.end(); + ++incDirIt) + { + _moc_incs += sep; + sep = ";"; + _moc_incs += *incDirIt; + } + + const char* tmp = target->GetProperty("COMPILE_DEFINITIONS"); std::string _moc_compile_defs = (tmp!=0 ? tmp : ""); + tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); + if (tmp) + { + _moc_compile_defs += ";"; + _moc_compile_defs += tmp; + } tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); std::string _moc_options = (tmp!=0 ? tmp : ""); @@ -209,8 +228,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) cmLocalGenerator::EscapeForCMake(automocTargetName.c_str()).c_str()); makefile->AddDefinition("_moc_incs", cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str()); - makefile->AddDefinition("_moc_defs", - cmLocalGenerator::EscapeForCMake(_moc_defs.c_str()).c_str()); makefile->AddDefinition("_moc_compile_defs", cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str()); makefile->AddDefinition("_moc_options", @@ -244,6 +261,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) bool cmQtAutomoc::Run(const char* targetDirectory) { + bool success = true; cmake cm; cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory); cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile(); @@ -255,7 +273,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - this->RunAutomoc(); + success = this->RunAutomoc(); } this->WriteOldMocDefinitionsFile(targetDirectory); @@ -263,7 +281,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) delete gg; gg = NULL; makefile = NULL; - return true; + return success; } @@ -312,19 +330,37 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); this->MocCompileDefinitionsStr = makefile->GetSafeDefinition( "AM_MOC_COMPILE_DEFINITIONS"); - this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS"); this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES"); this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS"); this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); + this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile); + this->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE"); return true; } +std::string cmQtAutomoc::MakeCompileSettingsString(cmMakefile* makefile) +{ + std::string s; + s += makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS"); + s += " ~~~ "; + s += makefile->GetSafeDefinition("AM_MOC_INCLUDES"); + s += " ~~~ "; + s += makefile->GetSafeDefinition("AM_MOC_OPTIONS"); + s += " ~~~ "; + s += makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE") ? "TRUE" + : "FALSE"; + s += " ~~~ "; + + return s; +} + + bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, const char* targetDirectory) { @@ -334,8 +370,8 @@ bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, if (makefile->ReadListFile(0, filename.c_str())) { - this->OldMocDefinitionsStr = - makefile->GetSafeDefinition("AM_OLD_MOC_DEFINITIONS"); + this->OldCompileSettingsStr = + makefile->GetSafeDefinition("AM_OLD_COMPILE_SETTINGS"); } return true; } @@ -350,9 +386,9 @@ void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) std::fstream outfile; outfile.open(filename.c_str(), std::ios::out | std::ios::trunc); - outfile << "set(AM_OLD_MOC_DEFINITIONS " + outfile << "set(AM_OLD_COMPILE_SETTINGS " << cmLocalGenerator::EscapeForCMake( - this->Join(this->MocDefinitions, ' ').c_str()) << ")\n"; + this->CurrentCompileSettingsStr.c_str()) << ")\n"; outfile.close(); } @@ -366,32 +402,11 @@ void cmQtAutomoc::Init() std::vector<std::string> cdefList; cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList); - if (!cdefList.empty()) - { - for(std::vector<std::string>::const_iterator it = cdefList.begin(); - it != cdefList.end(); - ++it) - { - this->MocDefinitions.push_back("-D" + (*it)); - } - } - else + for(std::vector<std::string>::const_iterator it = cdefList.begin(); + it != cdefList.end(); + ++it) { - std::string tmpMocDefs = this->MocDefinitionsStr; - cmSystemTools::ReplaceString(tmpMocDefs, " ", ";"); - - std::vector<std::string> defList; - cmSystemTools::ExpandListArgument(tmpMocDefs, defList); - - for(std::vector<std::string>::const_iterator it = defList.begin(); - it != defList.end(); - ++it) - { - if (this->StartsWith(*it, "-D")) - { - this->MocDefinitions.push_back(*it); - } - } + this->MocDefinitions.push_back("-D" + (*it)); } cmSystemTools::ExpandListArgument(this->MocOptionsStr, this->MocOptions); @@ -469,7 +484,7 @@ void cmQtAutomoc::Init() bool cmQtAutomoc::RunAutomoc() { if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) - || (this->OldMocDefinitionsStr != this->Join(this->MocDefinitions, ' '))) + || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr)) { this->GenerateAll = true; } @@ -549,7 +564,7 @@ bool cmQtAutomoc::RunAutomoc() this->GenerateMoc(it->first, it->second); } - std::stringstream outStream(std::stringstream::out); + cmsys_ios::stringstream outStream; outStream << "/* This file is autogenerated, do not edit*/\n"; bool automocCppChanged = false; @@ -577,7 +592,7 @@ bool cmQtAutomoc::RunAutomoc() if (this->RunMocFailed) { - std::cerr << "returning failed.."<< std::endl; + std::cerr << "moc failed..."<< std::endl; return false; } outStream.flush(); @@ -1077,7 +1092,7 @@ bool cmQtAutomoc::EndsWith(const std::string& str, const std::string& with) std::string cmQtAutomoc::ReadAll(const std::string& filename) { std::ifstream file(filename.c_str()); - std::stringstream stream; + cmsys_ios::stringstream stream; stream << file.rdbuf(); file.close(); return stream.str(); diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 8cbbac1..a737477 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -35,6 +35,8 @@ private: const char* targetDirectory); void WriteOldMocDefinitionsFile(const char* targetDirectory); + std::string MakeCompileSettingsString(cmMakefile* makefile); + bool RunAutomoc(); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); @@ -67,14 +69,14 @@ private: std::string Builddir; std::string MocExecutable; std::string MocCompileDefinitionsStr; - std::string MocDefinitionsStr; std::string MocIncludesStr; std::string MocOptionsStr; std::string ProjectBinaryDir; std::string ProjectSourceDir; std::string TargetName; - std::string OldMocDefinitionsStr; + std::string CurrentCompileSettingsStr; + std::string OldCompileSettingsStr; std::string OutMocCppFilename; std::list<std::string> MocIncludes; diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index d80b3fe..bcb8564 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -30,13 +30,13 @@ bool cmRemoveCommand { return true; } - + // expand the variable std::vector<std::string> varArgsExpanded; cmSystemTools::ExpandListArgument(cacheValue, varArgsExpanded); - + // expand the args - // check for REMOVE(VAR v1 v2 ... vn) + // check for REMOVE(VAR v1 v2 ... vn) std::vector<std::string> argsExpanded; std::vector<std::string> temp; for(unsigned int j = 1; j < args.size(); ++j) @@ -44,7 +44,7 @@ bool cmRemoveCommand temp.push_back(args[j]); } cmSystemTools::ExpandList(temp, argsExpanded); - + // now create the new value std::string value; for(unsigned int j = 0; j < varArgsExpanded.size(); ++j) @@ -67,7 +67,7 @@ bool cmRemoveCommand value += varArgsExpanded[j]; } } - + // add the definition this->Makefile->AddDefinition(variable, value.c_str()); diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h index c62d58f..5aedc26 100644 --- a/Source/cmRemoveCommand.h +++ b/Source/cmRemoveCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmRemoveCommand; } @@ -46,7 +46,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "remove";} - + /** * Succinct documentation. */ @@ -54,7 +54,7 @@ public: { return "Deprecated. Use the list(REMOVE_ITEM ) command instead."; } - + /** * More documentation. */ @@ -66,13 +66,13 @@ public: "This is typically used to remove entries from a vector " "(e.g. semicolon separated list). VALUE is expanded."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { return true; } - + cmTypeMacro(cmRemoveCommand, cmCommand); }; diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h index f0e906d..18f6171 100644 --- a/Source/cmRemoveDefinitionsCommand.h +++ b/Source/cmRemoveDefinitionsCommand.h @@ -17,9 +17,9 @@ /** \class cmRemoveDefinitionsCommand * \brief Specify a list of compiler defines * - * cmRemoveDefinitionsCommand specifies a list of compiler defines. + * cmRemoveDefinitionsCommand specifies a list of compiler defines. * These defines will - * be removed from the compile command. + * be removed from the compile command. */ class cmRemoveDefinitionsCommand : public cmCommand { @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmRemoveDefinitionsCommand; } @@ -43,7 +43,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "remove_definitions";} - + /** * Succinct documentation. */ @@ -51,7 +51,7 @@ public: { return "Removes -D define flags added by add_definitions."; } - + /** * More documentation. */ @@ -62,7 +62,7 @@ public: "Removes flags (added by add_definitions) from the compiler command " "line for sources in the current directory and below."; } - + cmTypeMacro(cmRemoveDefinitionsCommand, cmCommand); }; diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h index 690ab79..a6e87ef 100644 --- a/Source/cmReturnCommand.h +++ b/Source/cmReturnCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmReturnCommand; } @@ -46,7 +46,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "return";} - + /** * Succinct documentation. */ @@ -54,7 +54,7 @@ public: { return "Return from a file, directory or function."; } - + /** * More documentation. */ @@ -72,7 +72,7 @@ public: "of the function. Note that a macro " "is not a function and does not handle return like a function does."; } - + cmTypeMacro(cmReturnCommand, cmCommand); }; diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h index 6a51a92..d62baf7 100644 --- a/Source/cmSeparateArgumentsCommand.h +++ b/Source/cmSeparateArgumentsCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSeparateArgumentsCommand; } @@ -46,16 +46,16 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "separate_arguments";} - + /** * Succinct documentation. */ virtual const char* GetTerseDocumentation() const { - return + return "Parse space-separated arguments into a semicolon-separated list."; } - + /** * More documentation. */ @@ -83,7 +83,7 @@ public: "All spaces are replaced with ';'. This helps with generating " "command lines."; } - + cmTypeMacro(cmSeparateArgumentsCommand, cmCommand); }; diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index d00fc86..20f38be 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -20,7 +20,7 @@ bool cmSetCommand this->SetError("called with incorrect number of arguments"); return false; } - + // watch for ENV signatures const char* variable = args[0].c_str(); // VAR is always first if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5) @@ -31,7 +31,7 @@ bool cmSetCommand varName[strlen(variable)-5] = '\0'; std::string putEnvArg = varName; putEnvArg += "="; - + // what is the current value if any const char *currValue = getenv(varName); delete [] varName; @@ -47,7 +47,7 @@ bool cmSetCommand } return true; } - + // if it will be cleared, then clear it if it isn;t already clear if (currValue) { @@ -55,7 +55,7 @@ bool cmSetCommand } return true; } - + // SET (VAR) // Removes the definition of VAR. if (args.size() == 1) { @@ -63,7 +63,7 @@ bool cmSetCommand return true; } - // here are the remaining options + // here are the remaining options // SET (VAR value ) // SET (VAR CACHE TYPE "doc String" [FORCE]) // SET (VAR value CACHE TYPE "doc string" [FORCE]) @@ -71,10 +71,10 @@ bool cmSetCommand bool cache = false; // optional bool force = false; // optional bool parentScope = false; - cmCacheManager::CacheEntryType type + cmCacheManager::CacheEntryType type = cmCacheManager::STRING; // required if cache const char* docstring = 0; // required if cache - + unsigned int ignoreLastArgs = 0; // look for PARENT_SCOPE argument if (args.size() > 1 && args[args.size()-1] == "PARENT_SCOPE") @@ -136,7 +136,7 @@ bool cmSetCommand this->SetError("given invalid arguments for CACHE mode."); return false; } - + if(cache) { std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0); @@ -145,7 +145,7 @@ bool cmSetCommand } // see if this is already in the cache - cmCacheManager::CacheIterator it = + cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->GetCacheIterator(variable); if(!it.IsAtEnd() && (it.GetType() != cmCacheManager::UNINITIALIZED)) { @@ -158,7 +158,7 @@ bool cmSetCommand return true; } } - + // if it is meant to be in the cache then define it in the cache if(cache) { diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h index 66b129e..fe1d58d 100644 --- a/Source/cmSetCommand.h +++ b/Source/cmSetCommand.h @@ -17,7 +17,7 @@ /** \class cmSetCommand * \brief Set a CMAKE variable * - * cmSetCommand sets a variable to a value with expansion. + * cmSetCommand sets a variable to a value with expansion. */ class cmSetCommand : public cmCommand { @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSetCommand; } @@ -46,15 +46,15 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "set";} - + /** * Succinct documentation. */ virtual const char* GetTerseDocumentation() const { - return "Set a CMAKE variable to a given value."; + return "Set a CMake, cache or environment variable to a given value."; } - + /** * More documentation. */ @@ -63,26 +63,37 @@ public: return " set(<variable> <value>\n" " [[CACHE <type> <docstring> [FORCE]] | PARENT_SCOPE])\n" - "Within CMake sets <variable> to the value <value>. <value> is expanded" - " before <variable> is set to it. If CACHE is present, then the " - "<variable> is put in the cache. <type> and <docstring> are then " - "required. <type> is used by the CMake GUI to choose a widget with " - "which the user sets a value. The value for <type> may be one of\n" + "Within CMake sets <variable> to the value <value>. " + "<value> is expanded before <variable> is set to it. " + "Normally, set will set a regular CMake variable. " + "If CACHE is present, then the <variable> is put in the cache " + "instead, unless it is already in the cache. " + "See section 'Variable types in CMake' below for details of " + "regular and cache variables and their interactions. " + "If CACHE is used, <type> and <docstring> are required. <type> is used " + "by the CMake GUI to choose a widget with which the user sets a value. " + "The value for <type> may be one of\n" " FILEPATH = File chooser dialog.\n" " PATH = Directory chooser dialog.\n" " STRING = Arbitrary string.\n" " BOOL = Boolean ON/OFF checkbox.\n" " INTERNAL = No GUI entry (used for persistent variables).\n" - "If <type> is INTERNAL, then the <value> is always written into the " - "cache, replacing any values existing in the cache. If it is not a " - "cache variable, then this always writes into the current makefile. The " - "FORCE option will overwrite the cache value removing any changes by " - "the user.\n" + "If <type> is INTERNAL, the cache variable is marked as internal, " + "and will not be shown to the user in tools like cmake-gui. " + "This is intended for values that should be persisted in the cache, " + "but which users should not normally change. INTERNAL implies FORCE." + "\n" + "Normally, set(...CACHE...) creates cache variables, but does not " + "modify them. " + "If FORCE is specified, the value of the cache variable is set, even " + "if the variable is already in the cache. This should normally be " + "avoided, as it will remove any changes to the cache variable's value " + "by the user.\n" "If PARENT_SCOPE is present, the variable will be set in the scope " "above the current scope. Each new directory or function creates a new " "scope. This command will set the value of a variable into the parent " "directory or calling function (whichever is applicable to the case at " - "hand).\n" + "hand). PARENT_SCOPE cannot be combined with CACHE.\n" "If <value> is not specified then the variable is removed " "instead of set. See also: the unset() command.\n" " set(<variable> <value1> ... <valueN>)\n" @@ -90,9 +101,60 @@ public: "values.\n" "<variable> can be an environment variable such as:\n" " set( ENV{PATH} /home/martink )\n" - "in which case the environment variable will be set."; + "in which case the environment variable will be set.\n" + "*** Variable types in CMake ***\n" + "In CMake there are two types of variables: normal variables and cache " + "variables. Normal variables are meant for the internal use of the " + "script (just like variables in most programming languages); they are " + "not persisted across CMake runs. " + "Cache variables (unless set with INTERNAL) are mostly intended for " + "configuration settings where the first CMake run determines a " + "suitable default value, which the user can then override, by editing " + "the cache with tools such as ccmake or cmake-gui. " + "Cache variables are stored in the CMake cache file, and " + "are persisted across CMake runs. \n" + "Both types can exist at the same time with the same name " + "but different values. " + "When ${FOO} is evaluated, CMake first looks for " + "a normal variable 'FOO' in scope and uses it if set. " + "If and only if no normal variable exists then it falls back to the " + "cache variable 'FOO'.\n" + "Some examples:\n" + "The code 'set(FOO \"x\")' sets the normal variable 'FOO'. It does not " + "touch the cache, but it will hide any existing cache value 'FOO'.\n" + "The code 'set(FOO \"x\" CACHE ...)' checks for 'FOO' in the cache, " + "ignoring any normal variable of the same name. If 'FOO' is in the " + "cache then nothing happens to either the normal variable or the cache " + "variable. If 'FOO' is not in the cache, then it is added to the " + "cache.\n" + "Finally, whenever a cache variable is added or modified by a command, " + "CMake also *removes* the normal variable of the same name from the " + "current scope so that an immediately following evaluation of " + "it will expose the newly cached value.\n" + "Normally projects should avoid using normal and cache variables of " + "the same name, as this interaction can be hard to follow. " + "However, in some situations it can be useful. " + "One example (used by some projects):" + "\n" + "A project has a subproject in its source tree. The child project has " + "its own CMakeLists.txt, which is included from the parent " + "CMakeLists.txt using add_subdirectory(). " + "Now, if the parent and the child project provide the same option " + "(for example a compiler option), the parent gets the first chance " + "to add a user-editable option to the cache. " + "Normally, the child would then use the same value " + "that the parent uses. " + "However, it may be necessary to hard-code the value for the child " + "project's option while still allowing the user to edit the value used " + "by the parent project. The parent project can achieve this simply by " + "setting a normal variable with the same name as the option in a scope " + "sufficient to hide the option's cache variable from the child " + "completely. The parent has already set the cache variable, so the " + "child's set(...CACHE...) will do nothing, and evaluating the option " + "variable will use the value from the normal variable, which hides the " + "cache variable."; } - + cmTypeMacro(cmSetCommand, cmCommand); }; diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx index b956313..62c9b87 100644 --- a/Source/cmSetDirectoryPropertiesCommand.cxx +++ b/Source/cmSetDirectoryPropertiesCommand.cxx @@ -22,11 +22,11 @@ bool cmSetDirectoryPropertiesCommand this->SetError("called with incorrect number of arguments"); return false; } - + std::string errors; - bool ret = - cmSetDirectoryPropertiesCommand::RunCommand(this->Makefile, - args.begin() + 1, + bool ret = + cmSetDirectoryPropertiesCommand::RunCommand(this->Makefile, + args.begin() + 1, args.end(), errors); if (!ret) { @@ -52,19 +52,19 @@ bool cmSetDirectoryPropertiesCommand const std::string& value = *(ait+1); if ( prop == "VARIABLES" ) { - errors = + errors = "Variables and cache variables should be set using SET command"; return false; } else if ( prop == "MACROS" ) { - errors = + errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES"; return false; } mf->SetProperty(prop.c_str(), value.c_str()); } - + return true; } diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h index ee40158..8a50c60 100644 --- a/Source/cmSetDirectoryPropertiesCommand.h +++ b/Source/cmSetDirectoryPropertiesCommand.h @@ -17,7 +17,7 @@ class cmSetDirectoryPropertiesCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSetDirectoryPropertiesCommand; } @@ -46,7 +46,7 @@ public: { return "Set a property of the directory."; } - + /** * Static entry point for use by other commands */ @@ -69,7 +69,7 @@ public: "ADDITIONAL_MAKE_CLEAN_FILES is a list of files that will be cleaned " "as a part of \"make clean\" stage."; } - + cmTypeMacro(cmSetDirectoryPropertiesCommand, cmCommand); }; diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx index 89ff4b1..619dfc5 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.cxx +++ b/Source/cmSetSourceFilesPropertiesCommand.cxx @@ -40,14 +40,14 @@ bool cmSetSourceFilesPropertiesCommand ++j; } - // now call the worker function + // now call the worker function std::string errors; - bool ret = + bool ret = cmSetSourceFilesPropertiesCommand - ::RunCommand(this->Makefile, + ::RunCommand(this->Makefile, args.begin(), args.begin() + numFiles, - args.begin() + numFiles, + args.begin() + numFiles, args.end(), errors); if (!ret) { diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h index 2a67bc0..f7009e7 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.h +++ b/Source/cmSetSourceFilesPropertiesCommand.h @@ -17,7 +17,7 @@ class cmSetSourceFilesPropertiesCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSetSourceFilesPropertiesCommand; } @@ -41,7 +41,7 @@ public: { return "Source files can have properties that affect how they are built."; } - + /** * Longer documentation. */ @@ -58,7 +58,7 @@ public: "Source file properties are visible only to targets " "added in the same directory (CMakeLists.txt)."; } - + cmTypeMacro(cmSetSourceFilesPropertiesCommand, cmCommand); static bool RunCommand(cmMakefile *mf, diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index 45a305e..a2b50a8 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -67,11 +67,11 @@ bool cmSetTargetPropertiesCommand "a PROPERTIES specifier?"); return false; } - + // now loop over all the targets int i; for(i = 0; i < numFiles; ++i) - { + { bool ret = cmSetTargetPropertiesCommand::SetOneTarget (args[i].c_str(),propertyPairs,this->Makefile); if (!ret) @@ -86,7 +86,7 @@ bool cmSetTargetPropertiesCommand } bool cmSetTargetPropertiesCommand -::SetOneTarget(const char *tname, +::SetOneTarget(const char *tname, std::vector<std::string> &propertyPairs, cmMakefile *mf) { @@ -103,7 +103,7 @@ bool cmSetTargetPropertiesCommand } // if file is not already in the makefile, then add it else - { + { return false; } return true; diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index 1bc429c..65c89fa 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -17,7 +17,7 @@ class cmSetTargetPropertiesCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSetTargetPropertiesCommand; } @@ -41,12 +41,12 @@ public: { return "Targets can have properties that affect how they are built."; } - + /** * Used by this command and cmSetPropertiesCommand */ - static bool SetOneTarget(const char *tname, - std::vector<std::string> &propertyPairs, + static bool SetOneTarget(const char *tname, + std::vector<std::string> &propertyPairs, cmMakefile *mf); /** @@ -138,7 +138,7 @@ public: "are used to initialize these properties.\n" "PROJECT_LABEL can be used to change the name of " "the target in an IDE like visual studio. VS_KEYWORD can be set " - "to change the visual studio keyword, for example QT integration " + "to change the visual studio keyword, for example Qt integration " "works better if this is set to Qt4VSv1.0.\n" "VS_SCC_PROJECTNAME, VS_SCC_LOCALPATH, VS_SCC_PROVIDER and " "VS_SCC_AUXPATH can be set " @@ -159,7 +159,7 @@ public: "part of the default build when you select \"Build Solution\"." ; } - + cmTypeMacro(cmSetTargetPropertiesCommand, cmCommand); }; diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index e4fee18..3d52cf2 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -73,10 +73,10 @@ bool cmSetTestsPropertiesCommand // now loop over all the targets int i; for(i = 0; i < numFiles; ++i) - { + { std::string errors; - bool ret = - cmSetTestsPropertiesCommand::SetOneTest(args[i].c_str(), + bool ret = + cmSetTestsPropertiesCommand::SetOneTest(args[i].c_str(), propertyPairs, this->Makefile, errors); if (!ret) @@ -91,7 +91,7 @@ bool cmSetTestsPropertiesCommand bool cmSetTestsPropertiesCommand -::SetOneTest(const char *tname, +::SetOneTest(const char *tname, std::vector<std::string> &propertyPairs, cmMakefile *mf, std::string &errors) { @@ -106,11 +106,11 @@ bool cmSetTestsPropertiesCommand } } else - { + { errors = "Can not find test to add properties to: "; errors += tname; return false; - } + } return true; } diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h index 10df17d..3a59218 100644 --- a/Source/cmSetTestsPropertiesCommand.h +++ b/Source/cmSetTestsPropertiesCommand.h @@ -17,7 +17,7 @@ class cmSetTestsPropertiesCommand : public cmCommand { public: - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSetTestsPropertiesCommand; } @@ -70,7 +70,7 @@ public: cmTypeMacro(cmSetTestsPropertiesCommand, cmCommand); - static bool SetOneTest(const char *tname, + static bool SetOneTest(const char *tname, std::vector<std::string> &propertyPairs, cmMakefile *mf, std::string &errors); diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx index 04e357c..2bdd1ad 100644 --- a/Source/cmSiteNameCommand.cxx +++ b/Source/cmSiteNameCommand.cxx @@ -29,25 +29,25 @@ bool cmSiteNameCommand paths.push_back("/bin"); paths.push_back("/sbin"); paths.push_back("/usr/local/bin"); - + const char* cacheValue = this->Makefile->GetDefinition(args[0].c_str()); if(cacheValue) { return true; } - + const char *temp = this->Makefile->GetDefinition("HOSTNAME"); std::string hostname_cmd; if(temp) { hostname_cmd = temp; } - else + else { hostname_cmd = cmSystemTools::FindProgram("hostname", paths); } - + std::string siteName = "unknown"; #if defined(_WIN32) && !defined(__CYGWIN__) std::string host; @@ -64,7 +64,7 @@ bool cmSiteNameCommand std::string host; cmSystemTools::RunSingleCommand(hostname_cmd.c_str(), &host, 0, 0, cmSystemTools::OUTPUT_NONE); - + // got the hostname if (host.length()) { diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h index 532710c..52a63bc 100644 --- a/Source/cmSiteNameCommand.h +++ b/Source/cmSiteNameCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSiteNameCommand; } @@ -46,7 +46,7 @@ public: * The name of the command as specified in CMakeList.txt. */ virtual const char* GetName() const {return "site_name";} - + /** * Succinct documentation. */ @@ -54,7 +54,7 @@ public: { return "Set the given variable to the name of the computer."; } - + /** * More documentation. */ @@ -63,7 +63,7 @@ public: return " site_name(variable)\n"; } - + cmTypeMacro(cmSiteNameCommand, cmCommand); }; diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index cd94753..cc3b6d6 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -346,7 +346,7 @@ const char* cmSourceFile::GetProperty(const char* prop) const } bool chain = false; - const char *retVal = + const char *retVal = this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain); if (chain) { @@ -354,7 +354,7 @@ const char* cmSourceFile::GetProperty(const char* prop) const return mf->GetProperty(prop,cmProperty::SOURCE_FILE); } - return retVal; + return retVal; } //---------------------------------------------------------------------------- @@ -388,7 +388,7 @@ void cmSourceFile::DefineProperties(cmake *cm) { // define properties cm->DefineProperty - ("ABSTRACT", cmProperty::SOURCE_FILE, + ("ABSTRACT", cmProperty::SOURCE_FILE, "Is this source file an abstract class.", "A property on a source file that indicates if the source file " "represents a class that is abstract. This only makes sense for " @@ -396,7 +396,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "only used by some tools that wrap classes into other languages."); cm->DefineProperty - ("COMPILE_FLAGS", cmProperty::SOURCE_FILE, + ("COMPILE_FLAGS", cmProperty::SOURCE_FILE, "Additional flags to be added when compiling this source file.", "These flags will be added to the list of compile flags when " "this source file builds. Use COMPILE_DEFINITIONS to pass additional " @@ -430,7 +430,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "be ignored by the Xcode generator."); cm->DefineProperty - ("EXTERNAL_OBJECT", cmProperty::SOURCE_FILE, + ("EXTERNAL_OBJECT", cmProperty::SOURCE_FILE, "If set to true then this is an object file.", "If this property is set to true then the source file " "is really an object file and should not be compiled. " @@ -446,14 +446,14 @@ void cmSourceFile::DefineProperties(cmake *cm) "source files in a target share the same format."); cm->DefineProperty - ("GENERATED", cmProperty::SOURCE_FILE, + ("GENERATED", cmProperty::SOURCE_FILE, "Is this source file generated as part of the build process.", "If a source file is generated by the build process CMake will " "handle it differently in terms of dependency checking etc. " "Otherwise having a non-existent source file could create problems."); cm->DefineProperty - ("HEADER_FILE_ONLY", cmProperty::SOURCE_FILE, + ("HEADER_FILE_ONLY", cmProperty::SOURCE_FILE, "Is this source file only a header file.", "A property on a source file that indicates if the source file " "is a header file with no associated implementation. This is " @@ -462,7 +462,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "computed."); cm->DefineProperty - ("KEEP_EXTENSION", cmProperty::SOURCE_FILE, + ("KEEP_EXTENSION", cmProperty::SOURCE_FILE, "Make the output file have the same extension as the source file.", "If this property is set then the file extension of the output " "file will be the same as that of the source file. Normally " @@ -477,7 +477,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "No other semantics are currently specified."); cm->DefineProperty - ("LANGUAGE", cmProperty::SOURCE_FILE, + ("LANGUAGE", cmProperty::SOURCE_FILE, "What programming language is the file.", "A property that can be set to indicate what programming language " "the source file is. If it is not set the language is determined " @@ -486,13 +486,13 @@ void cmSourceFile::DefineProperties(cmake *cm) "Do not set this for header or files that should not be compiled."); cm->DefineProperty - ("LOCATION", cmProperty::SOURCE_FILE, + ("LOCATION", cmProperty::SOURCE_FILE, "The full path to a source file.", "A read only property on a SOURCE FILE that contains the full path " "to the source file."); cm->DefineProperty - ("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE, + ("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE, "Place a source file inside a Mac OS X bundle, CFBundle, or framework.", "Executable targets with the MACOSX_BUNDLE property set are built " "as Mac OS X application bundles on Apple platforms. " @@ -531,7 +531,7 @@ void cmSourceFile::DefineProperties(cmake *cm) "command (if one does not already exist due to linking relationships)."); cm->DefineProperty - ("OBJECT_OUTPUTS", cmProperty::SOURCE_FILE, + ("OBJECT_OUTPUTS", cmProperty::SOURCE_FILE, "Additional outputs for a Makefile rule.", "Additional outputs created by compilation of this source file. " "If any of these outputs is missing the object will be recompiled. " @@ -539,14 +539,14 @@ void cmSourceFile::DefineProperties(cmake *cm) "on other generators."); cm->DefineProperty - ("SYMBOLIC", cmProperty::SOURCE_FILE, + ("SYMBOLIC", cmProperty::SOURCE_FILE, "Is this just a name for a rule.", "If SYMBOLIC (boolean) is set to true the build system will be " "informed that the source file is not actually created on disk but " "instead used as a symbolic name for a build rule."); - + cm->DefineProperty - ("WRAP_EXCLUDE", cmProperty::SOURCE_FILE, + ("WRAP_EXCLUDE", cmProperty::SOURCE_FILE, "Exclude this source file from any code wrapping techniques.", "Some packages can wrap source files into alternate languages " "to provide additional functionality. For example, C++ code " diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index ae01274..6c68b87 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -21,7 +21,7 @@ class cmake; /** \class cmSourceFile * \brief Represent a class loaded from a makefile. * - * cmSourceFile is represents a class loaded from + * cmSourceFile is represents a class loaded from * a makefile. */ class cmSourceFile diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 2b34f2b..4fd9851 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -71,13 +71,13 @@ void cmSourceGroup::SetGroupRegex(const char* regex) this->GroupRegex.compile("^$"); } } - + //---------------------------------------------------------------------------- void cmSourceGroup::AddGroupFile(const char* name) { this->GroupFiles.insert(name); } - + //---------------------------------------------------------------------------- const char* cmSourceGroup::GetName() const { @@ -89,7 +89,7 @@ const char* cmSourceGroup::GetFullName() const { return this->FullName.c_str(); } - + //---------------------------------------------------------------------------- bool cmSourceGroup::MatchesRegex(const char* name) { @@ -137,12 +137,12 @@ cmSourceGroup *cmSourceGroup::lookupChild(const char* name) // st for(;iter!=end; ++iter) { - std::string sgName = iter->GetName(); + std::string sgName = iter->GetName(); // look if descenened is the one were looking for if(sgName == name) { - return &(*iter); // if it so return it + return &(*iter); // if it so return it } } diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 641dcbd..11a0c74 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h @@ -37,12 +37,12 @@ public: cmSourceGroup(cmSourceGroup const& r); ~cmSourceGroup(); cmSourceGroup& operator=(cmSourceGroup const&); - + /** * Set the regular expression for this group. */ void SetGroupRegex(const char* regex); - + /** * Add a file name to the explicit list of files for this group. */ @@ -57,7 +57,7 @@ public: * Looks up child and returns it */ cmSourceGroup *lookupChild(const char *name); - + /** * Get the name of this group. */ @@ -67,12 +67,12 @@ public: * Get the full path name for group. */ const char* GetFullName() const; - + /** * Check if the given name matches this group's regex. */ bool MatchesRegex(const char* name); - + /** * Check if the given name matches this group's explicit file list. */ @@ -88,8 +88,8 @@ public: * Check if the given name matches this group's regex in children. */ cmSourceGroup *MatchChildrenRegex(const char *name); - - /** + + /** * Assign the given source file to this group. Used only by * generators. */ @@ -100,7 +100,7 @@ public: * source group. */ const std::vector<const cmSourceFile*>& GetSourceFiles() const; - + std::vector<cmSourceGroup> const& GetGroupChildren() const; private: /** @@ -109,17 +109,17 @@ private: std::string Name; // Full path to group std::string FullName; - + /** * The regular expression matching the files in the group. */ cmsys::RegularExpression GroupRegex; - + /** * Set of file names explicitly added to this group. */ std::set<cmStdString> GroupFiles; - + /** * Vector of all source files that have been assigned to * this group. diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 8e61d0a..9cb80f6 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -19,7 +19,7 @@ bool cmSourceGroupCommand { this->SetError("called with incorrect number of arguments"); return false; - } + } std::string delimiter = "\\"; if(this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER")) @@ -29,7 +29,7 @@ bool cmSourceGroupCommand std::vector<std::string> folders = cmSystemTools::tokenize(args[0], delimiter); - + cmSourceGroup* sg = 0; sg = this->Makefile->GetSourceGroup(folders); if(!sg) @@ -50,7 +50,7 @@ bool cmSourceGroupCommand sg->SetGroupRegex(args[1].c_str()); return true; } - + // Process arguments. bool doingFiles = false; for(unsigned int i=1; i < args.size(); ++i) @@ -97,6 +97,6 @@ bool cmSourceGroupCommand return false; } } - + return true; } diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index 6a29fc8..6c87b71 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -26,7 +26,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSourceGroupCommand; } @@ -37,7 +37,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -50,7 +50,7 @@ public: { return "Define a grouping for sources in the makefile."; } - + /** * More documentation. */ @@ -72,7 +72,7 @@ public: "format:\n" " source_group(name regex)"; } - + cmTypeMacro(cmSourceGroupCommand, cmCommand); }; diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index ea299ca..a4aec2e 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -152,10 +152,10 @@ extern int putenv (char *__string) __THROW; // if std:: is not supported, then just #define it away #ifdef CMAKE_NO_STD_NAMESPACE -#define std +#define std #endif -// if the compiler does not support ansi for scoping of vars use a +// if the compiler does not support ansi for scoping of vars use a // #define hack #ifdef CMAKE_NO_ANSI_FOR_SCOPE #define for if(false) {} else for @@ -178,7 +178,7 @@ namespace std { typedef ios ios_base; } #endif #ifdef __DECCXX_VER -# if __DECCXX_VER <= 60390008 +# if __DECCXX_VER <= 60390008 # define CM_HAS_STD_BUT_NOT_FOR_IOSTREAM # endif #endif @@ -200,7 +200,7 @@ using ::cerr; using ::cin; using ::ifstream; using ::ofstream; - + #if !defined(CMAKE_NO_ANSI_STRING_STREAM) using ::ostringstream; using ::istringstream; @@ -208,7 +208,7 @@ using ::ofstream; using ::ostrstream; using ::istrstream; #endif - + using ::endl; using ::ends; using ::flush; @@ -324,8 +324,8 @@ struct cmDocumentationEntry std::string Full; cmDocumentationEntry(){}; cmDocumentationEntry(const char *doc[3]) - { if (doc[0]) this->Name = doc[0]; - if (doc[1]) this->Brief = doc[1]; + { if (doc[0]) this->Name = doc[0]; + if (doc[1]) this->Brief = doc[1]; if (doc[2]) this->Full = doc[2]; }; cmDocumentationEntry(const char *n, const char *b, const char *f) { if (n) this->Name = n; if (b) this->Brief = b; if (f) this->Full = f; }; @@ -353,7 +353,7 @@ public: # pragma reset woff 1375 /* base class destructor not virtual */ #endif -// All subclasses of cmCommand or cmCTestGenericHandler should +// All subclasses of cmCommand or cmCTestGenericHandler should // invoke this macro. #define cmTypeMacro(thisClass,superclass) \ virtual const char* GetNameOfClass() { return #thisClass; } \ diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index ec10d57..0193dc9 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -28,7 +28,7 @@ bool cmStringCommand this->SetError("must be called with at least one argument."); return false; } - + const std::string &subCommand = args[0]; if(subCommand == "REGEX") { @@ -134,11 +134,11 @@ bool cmStringCommand::HandleToUpperLowerCommand( std::string outvar = args[2]; std::string output; - if (toUpper) + if (toUpper) { output = cmSystemTools::UpperCase(args[1]); - } - else + } + else { output = cmSystemTools::LowerCase(args[1]); } @@ -266,7 +266,7 @@ bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args) } return this->RegexReplace(args); } - + std::string e = "sub-command REGEX does not recognize mode "+mode; this->SetError(e.c_str()); return false; @@ -279,25 +279,25 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) // <input> [<input>...])\n"; std::string regex = args[2]; std::string outvar = args[3]; - + // Concatenate all the last arguments together. std::string input = args[4]; for(unsigned int i=5; i < args.size(); ++i) { input += args[i]; } - + this->ClearMatches(this->Makefile); // Compile the regular expression. cmsys::RegularExpression re; if(!re.compile(regex.c_str())) { - std::string e = + std::string e = "sub-command REGEX, mode MATCH failed to compile regex \""+regex+"\"."; this->SetError(e.c_str()); return false; } - + // Scan through the input for all matches. std::string output; if(re.find(input.c_str())) @@ -307,7 +307,7 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) std::string::size_type r = re.end(); if(r-l == 0) { - std::string e = + std::string e = "sub-command REGEX, mode MATCH regex \""+regex+ "\" matched an empty string."; this->SetError(e.c_str()); @@ -315,7 +315,7 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) } output = input.substr(l, r-l); } - + // Store the output in the provided variable. this->Makefile->AddDefinition(outvar.c_str(), output.c_str()); return true; @@ -324,18 +324,18 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) //---------------------------------------------------------------------------- bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) { - //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input> + //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input> // [<input>...])\n"; std::string regex = args[2]; std::string outvar = args[3]; - + // Concatenate all the last arguments together. std::string input = args[4]; for(unsigned int i=5; i < args.size(); ++i) { input += args[i]; } - + this->ClearMatches(this->Makefile); // Compile the regular expression. cmsys::RegularExpression re; @@ -347,7 +347,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) this->SetError(e.c_str()); return false; } - + // Scan through the input for all matches. std::string output; const char* p = input.c_str(); @@ -370,7 +370,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) output += std::string(p+l, r-l); p += r; } - + // Store the output in the provided variable. this->Makefile->AddDefinition(outvar.c_str(), output.c_str()); return true; @@ -379,12 +379,12 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) //---------------------------------------------------------------------------- bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) { - //"STRING(REGEX REPLACE <regular_expression> <replace_expression> + //"STRING(REGEX REPLACE <regular_expression> <replace_expression> // <output variable> <input> [<input>...])\n" std::string regex = args[2]; - std::string replace = args[3]; + std::string replace = args[3]; std::string outvar = args[4]; - + // Pull apart the replace expression to find the escaped [0-9] values. std::vector<RegexReplacement> replacement; std::string::size_type l = 0; @@ -432,26 +432,26 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) } l = r; } - + // Concatenate all the last arguments together. std::string input = args[5]; for(unsigned int i=6; i < args.size(); ++i) { input += args[i]; } - + this->ClearMatches(this->Makefile); // Compile the regular expression. cmsys::RegularExpression re; if(!re.compile(regex.c_str())) { - std::string e = + std::string e = "sub-command REGEX, mode REPLACE failed to compile regex \""+ regex+"\"."; this->SetError(e.c_str()); return false; } - + // Scan through the input for all matches. std::string output; std::string::size_type base = 0; @@ -460,10 +460,10 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) this->StoreMatches(this->Makefile, re); std::string::size_type l2 = re.start(); std::string::size_type r = re.end(); - + // Concatenate the part of the input that was not matched. output += input.substr(base, l2); - + // Make sure the match had some text. if(r-l2 == 0) { @@ -472,7 +472,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) this->SetError(e.c_str()); return false; } - + // Concatenate the replacement for the match. for(unsigned int i=0; i < replacement.size(); ++i) { @@ -504,14 +504,14 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) } } } - + // Move past the match. base += r; } - + // Concatenate the text after the last match. output += input.substr(base, input.length()-base); - + // Store the output in the provided variable. this->Makefile->AddDefinition(outvar.c_str(), output.c_str()); return true; @@ -624,9 +624,9 @@ bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const& this->SetError(e.c_str()); return false; } - + const std::string& left = args[2]; - const std::string& right = args[3]; + const std::string& right = args[3]; const std::string& outvar = args[4]; bool result; if(mode == "LESS") @@ -654,7 +654,7 @@ bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const& this->Makefile->AddDefinition(outvar.c_str(), "0"); } return true; - } + } std::string e = "sub-command COMPARE does not recognize mode "+mode; this->SetError(e.c_str()); return false; @@ -680,7 +680,7 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const& input += args[i]; } - cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(), + cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(), replaceExpression.c_str()); this->Makefile->AddDefinition(variableName.c_str(), input.c_str()); @@ -688,7 +688,7 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const& } //---------------------------------------------------------------------------- -bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const& +bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const& args) { if(args.size() != 5) @@ -722,7 +722,7 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const& return false; } - this->Makefile->AddDefinition(variableName.c_str(), + this->Makefile->AddDefinition(variableName.c_str(), stringValue.substr(begin, end).c_str()); return true; } @@ -780,7 +780,7 @@ bool cmStringCommand::HandleStripCommand( size_t outLength = 0; - // if the input string didn't contain any non-space characters, return + // if the input string didn't contain any non-space characters, return // an empty string if (startPos > inStringLength) { diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 3e585a5..728b1bc 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -30,7 +30,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmStringCommand; } @@ -59,7 +59,7 @@ public: { return "String operations."; } - + /** * More documentation. */ @@ -133,7 +133,8 @@ public: " . Matches any single character\n" " [ ] Matches any character(s) inside the brackets\n" " [^ ] Matches any character(s) not inside the brackets\n" - " - Matches any character in range on either side of a dash\n" + " - Inside brackets, specifies an inclusive range between\n" + " characters on either side e.g. [a-f] is [abcdef]\n" " * Matches preceding pattern zero or more times\n" " + Matches preceding pattern one or more times\n" " ? Matches preceding pattern zero or once only\n" @@ -143,7 +144,7 @@ public: " by all regular expression-related commands, including \n" " e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9)."; } - + cmTypeMacro(cmStringCommand, cmCommand); static void ClearMatches(cmMakefile* mf); static void StoreMatches(cmMakefile* mf, cmsys::RegularExpression& re); diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx index 9fcbe77..0cfe772 100644 --- a/Source/cmSubdirCommand.cxx +++ b/Source/cmSubdirCommand.cxx @@ -39,13 +39,13 @@ bool cmSubdirCommand } // if they specified a relative path then compute the full - std::string srcPath = - std::string(this->Makefile->GetCurrentDirectory()) + + std::string srcPath = + std::string(this->Makefile->GetCurrentDirectory()) + "/" + i->c_str(); if (cmSystemTools::FileIsDirectory(srcPath.c_str())) { - std::string binPath = - std::string(this->Makefile->GetCurrentOutputDirectory()) + + std::string binPath = + std::string(this->Makefile->GetCurrentOutputDirectory()) + "/" + i->c_str(); this->Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(), excludeFromAll, preorder, false); @@ -55,8 +55,8 @@ bool cmSubdirCommand { // we must compute the binPath from the srcPath, we just take the last // element from the source path and use that - std::string binPath = - std::string(this->Makefile->GetCurrentOutputDirectory()) + + std::string binPath = + std::string(this->Makefile->GetCurrentOutputDirectory()) + "/" + cmSystemTools::GetFilenameName(i->c_str()); this->Makefile->AddSubDirectory(i->c_str(), binPath.c_str(), excludeFromAll, preorder, false); @@ -65,7 +65,7 @@ bool cmSubdirCommand { std::string error = "Incorrect SUBDIRS command. Directory: "; error += *i + " does not exists."; - this->SetError(error.c_str()); + this->SetError(error.c_str()); res = false; } } diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h index eedbfff..618d5ff 100644 --- a/Source/cmSubdirCommand.h +++ b/Source/cmSubdirCommand.h @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSubdirCommand; } @@ -51,7 +51,7 @@ public: { return "Deprecated. Use the add_subdirectory() command instead."; } - + /** * More documentation. */ @@ -68,7 +68,7 @@ public: "This will cause any CMakeLists.txt files in the sub directories " "to be processed by CMake. Any directories after the PREORDER flag " "are traversed first by makefile builds, the PREORDER flag has no " - "effect on IDE projects. " + "effect on IDE projects. " " Any directories after the EXCLUDE_FROM_ALL marker " "will not be included in the top level makefile or project file. " "This is useful for having CMake create makefiles or projects for " @@ -77,7 +77,7 @@ public: "the same time, but you would not want them to show up in the " "top level project or be built each time make is run from the top."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h index daf97cd..b274d01 100644 --- a/Source/cmSubdirDependsCommand.h +++ b/Source/cmSubdirDependsCommand.h @@ -27,7 +27,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmSubdirDependsCommand; } @@ -51,7 +51,7 @@ public: { return "Deprecated. Does nothing."; } - + /** * More documentation. */ @@ -62,7 +62,7 @@ public: "Does not do anything. This command used to help projects order " "parallel builds correctly. This functionality is now automatic."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 69673c9..0b2def2 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -92,7 +92,8 @@ public: static bool GetErrorOccuredFlag() { return cmSystemTools::s_ErrorOccured || - cmSystemTools::s_FatalErrorOccured; + cmSystemTools::s_FatalErrorOccured || + GetInterruptFlag(); } ///! If this is set to true, cmake stops processing commands. static void SetFatalErrorOccured() diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c5ef9ff..f3eb52b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -15,8 +15,8 @@ #include "cmSourceFile.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" -#include "cmComputeLinkInformation.h" #include "cmDocumentCompileDefinitions.h" +#include "cmDocumentGeneratorExpressions.h" #include "cmDocumentLocationUndefined.h" #include "cmListFileCache.h" #include "cmGeneratorExpression.h" @@ -57,6 +57,7 @@ struct cmTarget::OutputInfo { std::string OutDir; std::string ImpDir; + std::string PdbDir; }; //---------------------------------------------------------------------------- @@ -205,6 +206,9 @@ void cmTarget::DefineProperties(cmake *cm) "are not supported by the native build tool. " "The VS6 IDE does not support definition values with spaces " "(but NMake does).\n" + "Contents of COMPILE_DEFINITIONS may use \"generator expressions\" with " + "the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER); cm->DefineProperty @@ -498,8 +502,11 @@ void cmTarget::DefineProperties(cmake *cm) "to the include_directories command." "\n" "The target property values are used by the generators to set " - "the include paths for the compiler. " - "See also the include_directories command."); + "the include paths for the compiler. " + "See also the include_directories command.\n" + "Contents of INCLUDE_DIRECTORIES may use \"generator expressions\" with " + "the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); cm->DefineProperty ("INSTALL_NAME_DIR", cmProperty::TARGET, @@ -741,6 +748,22 @@ void cmTarget::DefineProperties(cmake *cm) "Use OUTPUT_NAME_<CONFIG> instead."); cm->DefineProperty + ("PDB_NAME", cmProperty::TARGET, + "Output name for MS debug symbols .pdb file.", + "Set the base name for debug symbols file created for an " + "executable or library target. " + "If not set, the logical target name is used by default. " + "\n" + "This property is not implemented by the Visual Studio 6 generator."); + + cm->DefineProperty + ("PDB_NAME_<CONFIG>", cmProperty::TARGET, + "Per-configuration name for MS debug symbols .pdb file. ", + "This is the configuration-specific version of PDB_NAME. " + "\n" + "This property is not implemented by the Visual Studio 6 generator."); + + cm->DefineProperty ("PRE_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -756,6 +779,17 @@ void cmTarget::DefineProperties(cmake *cm) "(such as \"lib\") on a library name."); cm->DefineProperty + ("POSITION_INDEPENDENT_CODE", cmProperty::TARGET, + "Whether to create a position-independent target", + "The POSITION_INDEPENDENT_CODE property determines whether position " + "independent executables or shared libraries will be created. " + "This property is true by default for SHARED and MODULE library " + "targets and false otherwise. " + "This property is initialized by the value of the variable " + "CMAKE_POSITION_INDEPENDENT_CODE if it is set when a target is " + "created."); + + cm->DefineProperty ("POST_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -895,7 +929,7 @@ void cmTarget::DefineProperties(cmake *cm) "Build an executable with a WinMain entry point on windows.", "When this property is set to true the executable when linked " "on Windows will be created with a WinMain() entry point instead " - "of of just main()." + "of just main(). " "This makes it a GUI executable instead of a console application. " "See the CMAKE_MFC_FLAG variable documentation to configure use " "of MFC for WinMain executables. " @@ -1060,7 +1094,7 @@ void cmTarget::DefineProperties(cmake *cm) ("VS_KEYWORD", cmProperty::TARGET, "Visual Studio project keyword.", "Can be set to change the visual studio keyword, for example " - "QT integration works better if this is set to Qt4VSv1.0. "); + "Qt integration works better if this is set to Qt4VSv1.0. "); cm->DefineProperty ("VS_SCC_PROVIDER", cmProperty::TARGET, "Visual Studio Source Code Control Provider.", @@ -1179,6 +1213,27 @@ void cmTarget::DefineProperties(cmake *cm) CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME)); cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET, + "Output directory for MS debug symbols .pdb files.", + "This property specifies the directory into which the MS debug symbols " + "will be placed. " + "This property is initialized by the value of the variable " + "CMAKE_PDB_OUTPUT_DIRECTORY if it is set when a target is created." + "\n" + "This property is not implemented by the Visual Studio 6 generator."); + cm->DefineProperty + ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET, + "Per-configuration output directory for MS debug symbols .pdb files.", + "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, " + "but multi-configuration generators (VS, Xcode) do NOT append " + "a per-configuration subdirectory to the specified directory. " + "This property is initialized by the value of the variable " + "CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG> " + "if it is set when a target is created." + "\n" + "This property is not implemented by the Visual Studio 6 generator."); + + cm->DefineProperty ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET, "Output name for ARCHIVE target files.", "This property specifies the base name for archive target files. " @@ -1252,6 +1307,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("GNUtoMS", 0); @@ -1271,6 +1327,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_", "RUNTIME_OUTPUT_DIRECTORY_", + "PDB_OUTPUT_DIRECTORY_", 0}; for(std::vector<std::string>::iterator ci = configNames.begin(); ci != configNames.end(); ++ci) @@ -1305,6 +1362,13 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetProperty("INCLUDE_DIRECTORIES", this->Makefile->GetProperty("INCLUDE_DIRECTORIES")); + if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY + || this->TargetTypeValue == cmTarget::MODULE_LIBRARY) + { + this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); + } + this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0); + // Record current policies for later use. this->PolicyStatusCMP0003 = this->Makefile->GetPolicyStatus(cmPolicies::CMP0003); @@ -1605,7 +1669,11 @@ cmTargetTraceDependencies { // Transform command names that reference targets built in this // project to corresponding target-level dependencies. - cmGeneratorExpression ge(this->Makefile, 0, cc.GetBacktrace(), true); + cmGeneratorExpression ge(cc.GetBacktrace()); + + // Add target-level dependencies referenced by generator expressions. + std::set<cmTarget*> targets; + for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin(); cit != cc.GetCommandLines().end(); ++cit) { @@ -1627,12 +1695,17 @@ cmTargetTraceDependencies for(cmCustomCommandLine::const_iterator cli = cit->begin(); cli != cit->end(); ++cli) { - ge.Process(*cli); + const cmCompiledGeneratorExpression &cge = ge.Parse(*cli); + cge.Evaluate(this->Makefile, 0, true); + std::set<cmTarget*> geTargets = cge.GetTargets(); + for(std::set<cmTarget*>::const_iterator it = geTargets.begin(); + it != geTargets.end(); ++it) + { + targets.insert(*it); + } } } - // Add target-level dependencies referenced by generator expressions. - std::set<cmTarget*> targets = ge.GetTargets(); for(std::set<cmTarget*>::iterator ti = targets.begin(); ti != targets.end(); ++ti) { @@ -1987,9 +2060,8 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) } //---------------------------------------------------------------------------- -bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType llt) +bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType) { - (void)llt; // TODO: What is this? if(this->NameResolvesToFramework(libname.c_str())) { std::string frameworkDir = libname; @@ -2269,7 +2341,7 @@ void cmTarget::Emit(const LibraryID lib, // be preserved. // This variable will keep track of the libraries that were - // emitted directory from the current node, and not from a + // emitted directly from the current node, and not from a // recursive call. This way, if we come across a library that // has already been emitted, we repeat it iff it has been // emitted here. @@ -2387,7 +2459,7 @@ void cmTarget::AppendProperty(const char* prop, const char* value, //---------------------------------------------------------------------------- void cmTarget::MaybeInvalidatePropertyCache(const char* prop) { - // Wipe wipe out maps caching information affected by this property. + // Wipe out maps caching information affected by this property. if(this->IsImported() && strncmp(prop, "IMPORTED", 8) == 0) { this->Internal->ImportInfoMap.clear(); @@ -2468,6 +2540,16 @@ void cmTarget::MarkAsImported() } //---------------------------------------------------------------------------- +bool cmTarget::HaveWellDefinedOutputFiles() +{ + return + this->GetType() == cmTarget::STATIC_LIBRARY || + this->GetType() == cmTarget::SHARED_LIBRARY || + this->GetType() == cmTarget::MODULE_LIBRARY || + this->GetType() == cmTarget::EXECUTABLE; +} + +//---------------------------------------------------------------------------- cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) { // There is no output information for imported targets. @@ -2477,10 +2559,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) } // Only libraries and executables have well-defined output files. - if(this->GetType() != cmTarget::STATIC_LIBRARY && - this->GetType() != cmTarget::SHARED_LIBRARY && - this->GetType() != cmTarget::MODULE_LIBRARY && - this->GetType() != cmTarget::EXECUTABLE) + if(!this->HaveWellDefinedOutputFiles()) { std::string msg = "cmTarget::GetOutputInfo called for "; msg += this->GetName(); @@ -2505,6 +2584,10 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) OutputInfo info; this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); + if(!this->ComputePDBOutputDir(config, info.PdbDir)) + { + info.PdbDir = info.OutDir; + } OutputInfoMapType::value_type entry(config_upper, info); i = this->Internal->OutputInfoMap.insert(entry).first; } @@ -2530,6 +2613,17 @@ std::string cmTarget::GetDirectory(const char* config, bool implib) } //---------------------------------------------------------------------------- +std::string cmTarget::GetPDBDirectory(const char* config) +{ + if(OutputInfo const* info = this->GetOutputInfo(config)) + { + // Return the directory in which the target will be built. + return info->PdbDir; + } + return ""; +} + +//---------------------------------------------------------------------------- const char* cmTarget::GetLocation(const char* config) { if (this->IsImported()) @@ -2571,18 +2665,7 @@ const char* cmTarget::NormalGetLocation(const char* config) this->Location += cfgid; this->Location += "/"; } - if(this->IsAppBundleOnApple()) - { - this->Location += this->GetFullName(config, false); - this->Location += ".app/Contents/MacOS/"; - } - if(this->IsFrameworkOnApple()) - { - this->Location += this->GetFullName(config, false); - this->Location += ".framework/Versions/"; - this->Location += this->GetFrameworkVersion(); - this->Location += "/"; - } + this->Location = this->BuildMacContentDirectory(this->Location, config); this->Location += this->GetFullName(config, false); return this->Location.c_str(); } @@ -2931,25 +3014,6 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc) } //---------------------------------------------------------------------------- -const char* cmTarget::GetCreateRuleVariable() -{ - switch(this->GetType()) - { - case cmTarget::STATIC_LIBRARY: - return "_CREATE_STATIC_LIBRARY"; - case cmTarget::SHARED_LIBRARY: - return "_CREATE_SHARED_LIBRARY"; - case cmTarget::MODULE_LIBRARY: - return "_CREATE_SHARED_MODULE"; - case cmTarget::EXECUTABLE: - return "_LINK_EXECUTABLE"; - default: - break; - } - return ""; -} - -//---------------------------------------------------------------------------- const char* cmTarget::GetSuffixVariableInternal(bool implib) { switch(this->GetType()) @@ -3005,6 +3069,28 @@ std::string cmTarget::GetPDBName(const char* config) std::string base; std::string suffix; this->GetFullNameInternal(config, false, prefix, base, suffix); + + std::vector<std::string> props; + std::string configUpper = + cmSystemTools::UpperCase(config? config : ""); + if(!configUpper.empty()) + { + // PDB_NAME_<CONFIG> + props.push_back("PDB_NAME_" + configUpper); + } + + // PDB_NAME + props.push_back("PDB_NAME"); + + for(std::vector<std::string>::const_iterator i = props.begin(); + i != props.end(); ++i) + { + if(const char* outName = this->GetProperty(i->c_str())) + { + base = outName; + break; + } + } return prefix+base+".pdb"; } @@ -3154,22 +3240,7 @@ std::string cmTarget::GetFullPath(const char* config, bool implib, std::string cmTarget::NormalGetFullPath(const char* config, bool implib, bool realname) { - // Start with the output directory for the target. - std::string fpath = this->GetDirectory(config, implib); - fpath += "/"; - - if(this->IsAppBundleOnApple()) - { - fpath += this->GetFullName(config, false); - fpath += ".app/Contents/MacOS/"; - } - if(this->IsFrameworkOnApple()) - { - fpath += this->GetFullName(config, false); - fpath += ".framework/Versions/"; - fpath += this->GetFrameworkVersion(); - fpath += "/"; - } + std::string fpath = this->GetMacContentDirectory(config, implib); // Add the full name of the target. if(implib) @@ -3404,7 +3475,7 @@ void cmTarget::GetLibraryNames(std::string& name, } // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3483,7 +3554,7 @@ void cmTarget::GetExecutableNames(std::string& name, impName = this->GetFullNameInternal(config, true); // The program database file name. - pdbName = prefix+base+".pdb"; + pdbName = this->GetPDBName(config); } //---------------------------------------------------------------------------- @@ -3562,7 +3633,7 @@ void cmTarget::GenerateTargetManifest(const char* config) } if(!pdbName.empty()) { - f = dir; + f = this->GetPDBDirectory(config); f += "/"; f += pdbName; gg->AddToManifest(config? config:"", f); @@ -3692,10 +3763,7 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, dir += "/"; if(this->IsFrameworkOnApple() && !for_xcode) { - dir += this->GetFullName(config, false); - dir += ".framework/Versions/"; - dir += this->GetFrameworkVersion(); - dir += "/"; + dir += this->GetFrameworkDirectory(config); } return dir; } @@ -3726,10 +3794,7 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, if(this->IsFrameworkOnApple() && !for_xcode) { - dir += this->GetFullName(config, false); - dir += ".framework/Versions/"; - dir += this->GetFrameworkVersion(); - dir += "/"; + dir += this->GetFrameworkDirectory(config); } return dir; @@ -3878,6 +3943,65 @@ bool cmTarget::ComputeOutputDir(const char* config, } //---------------------------------------------------------------------------- +bool cmTarget::ComputePDBOutputDir(const char* config, std::string& out) +{ + // Look for a target property defining the target output directory + // based on the target type. + std::string targetTypeName = "PDB"; + const char* propertyName = 0; + std::string propertyNameStr = targetTypeName; + if(!propertyNameStr.empty()) + { + propertyNameStr += "_OUTPUT_DIRECTORY"; + propertyName = propertyNameStr.c_str(); + } + + // Check for a per-configuration output directory target property. + std::string configUpper = cmSystemTools::UpperCase(config? config : ""); + const char* configProp = 0; + std::string configPropStr = targetTypeName; + if(!configPropStr.empty()) + { + configPropStr += "_OUTPUT_DIRECTORY_"; + configPropStr += configUpper; + configProp = configPropStr.c_str(); + } + + // Select an output directory. + if(const char* config_outdir = this->GetProperty(configProp)) + { + // Use the user-specified per-configuration output directory. + out = config_outdir; + + // Skip per-configuration subdirectory. + config = 0; + } + else if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + if(out.empty()) + { + return false; + } + + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + + // The generator may add the configuration's subdirectory. + if(config && *config) + { + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", out); + } + return true; +} + +//---------------------------------------------------------------------------- bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib) { std::string dir; @@ -3978,27 +4102,6 @@ void cmTarget::GetLanguages(std::set<cmStdString>& languages) const } //---------------------------------------------------------------------------- -void cmTarget::GetAppleArchs(const char* config, - std::vector<std::string>& archVec) -{ - const char* archs = 0; - if(config && *config) - { - std::string defVarName = "OSX_ARCHITECTURES_"; - defVarName += cmSystemTools::UpperCase(config); - archs = this->GetProperty(defVarName.c_str()); - } - if(!archs) - { - archs = this->GetProperty("OSX_ARCHITECTURES"); - } - if(archs) - { - cmSystemTools::ExpandListArgument(std::string(archs), archVec); - } -} - -//---------------------------------------------------------------------------- bool cmTarget::IsChrpathUsed(const char* config) { #if defined(CMAKE_USE_ELF_PARSER) @@ -4669,76 +4772,60 @@ std::string cmTarget::CheckCMP0004(std::string const& item) } //---------------------------------------------------------------------------- -cmComputeLinkInformation* -cmTarget::GetLinkInformation(const char* config) +std::string cmTarget::GetFrameworkDirectory(const char* config) { - // Lookup any existing information for this configuration. - std::map<cmStdString, cmComputeLinkInformation*>::iterator - i = this->LinkInformation.find(config?config:""); - if(i == this->LinkInformation.end()) - { - // Compute information for this configuration. - cmComputeLinkInformation* info = - new cmComputeLinkInformation(this, config); - if(!info || !info->Compute()) - { - delete info; - info = 0; - } - - // Store the information for this configuration. - std::map<cmStdString, cmComputeLinkInformation*>::value_type - entry(config?config:"", info); - i = this->LinkInformation.insert(entry).first; - } - return i->second; + std::string fpath; + fpath += this->GetFullName(config, false); + fpath += ".framework/Versions/"; + fpath += this->GetFrameworkVersion(); + fpath += "/"; + return fpath; } //---------------------------------------------------------------------------- -std::vector<std::string> cmTarget::GetIncludeDirectories() +std::string cmTarget::BuildMacContentDirectory(const std::string& base, + const char* config, + bool includeMacOS) { - std::vector<std::string> includes; - const char *prop = this->GetProperty("INCLUDE_DIRECTORIES"); - if(prop) + std::string fpath = base; + if(this->IsAppBundleOnApple()) { - cmSystemTools::ExpandListArgument(prop, includes); + fpath += this->GetFullName(config, false); + fpath += ".app/Contents/"; + if(includeMacOS) + fpath += "MacOS/"; } - - std::set<std::string> uniqueIncludes; - std::vector<std::string> orderedAndUniqueIncludes; - for(std::vector<std::string>::const_iterator - li = includes.begin(); li != includes.end(); ++li) + if(this->IsFrameworkOnApple()) { - if(uniqueIncludes.insert(*li).second) + fpath += this->GetFrameworkDirectory(config); + } + if(this->IsCFBundleOnApple()) + { + fpath += this->GetFullName(config, false); + fpath += "."; + const char *ext = this->GetProperty("BUNDLE_EXTENSION"); + if (!ext) { - orderedAndUniqueIncludes.push_back(*li); + ext = "bundle"; } + fpath += ext; + fpath += "/Contents/"; + if(includeMacOS) + fpath += "MacOS/"; } - - return orderedAndUniqueIncludes; -} - -//---------------------------------------------------------------------------- -cmTargetLinkInformationMap -::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() -{ - // Ideally cmTarget instances should never be copied. However until - // we can make a sweep to remove that, this copy constructor avoids - // allowing the resources (LinkInformation) from getting copied. In - // the worst case this will lead to extra cmComputeLinkInformation - // instances. We also enforce in debug mode that the map be emptied - // when copied. - static_cast<void>(r); - assert(r.empty()); + return fpath; } //---------------------------------------------------------------------------- -cmTargetLinkInformationMap::~cmTargetLinkInformationMap() +std::string cmTarget::GetMacContentDirectory(const char* config, + bool implib, + bool includeMacOS) { - for(derived::iterator i = this->begin(); i != this->end(); ++i) - { - delete i->second; - } + // Start with the output directory for the target. + std::string fpath = this->GetDirectory(config, implib); + fpath += "/"; + fpath = this->BuildMacContentDirectory(fpath, config, includeMacOS); + return fpath; } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index d70cacd..e442d25 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -22,18 +22,8 @@ class cmake; class cmMakefile; class cmSourceFile; class cmGlobalGenerator; -class cmComputeLinkInformation; class cmListFileBacktrace; -struct cmTargetLinkInformationMap: - public std::map<cmStdString, cmComputeLinkInformation*> -{ - typedef std::map<cmStdString, cmComputeLinkInformation*> derived; - cmTargetLinkInformationMap() {} - cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r); - ~cmTargetLinkInformationMap(); -}; - class cmTargetInternals; class cmTargetInternalPointer { @@ -158,9 +148,6 @@ public: void AddSources(std::vector<std::string> const& srcs); cmSourceFile* AddSource(const char* src); - /** - * Get the list of the source files used by this target - */ enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED}; //* how we identify a library, by name and type @@ -304,6 +291,12 @@ public: output directory is given. */ std::string GetDirectory(const char* config = 0, bool implib = false); + /** Get the directory in which this targets .pdb files will be placed. + If the configuration name is given then the generator will add its + subdirectory for that configuration. Otherwise just the canonical + pdb output directory is given. */ + std::string GetPDBDirectory(const char* config = 0); + /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION target property. */ @@ -333,10 +326,6 @@ public: ///! Return the preferred linker language for this target const char* GetLinkerLanguage(const char* config = 0); - ///! Return the rule variable used to create this type of target, - // need to add CMAKE_(LANG) for full name. - const char* GetCreateRuleVariable(); - /** Get the full name of the target according to the settings in its makefile. */ std::string GetFullName(const char* config=0, bool implib = false); @@ -403,8 +392,6 @@ public: std::string GetInstallNameDirForInstallTree(const char* config, bool for_xcode = false); - cmComputeLinkInformation* GetLinkInformation(const char* config); - // Get the properties cmPropertyMap &GetProperties() { return this->Properties; }; @@ -422,9 +409,6 @@ public: // until we have per-target object file properties. void GetLanguages(std::set<cmStdString>& languages) const; - /** Get the list of OS X target architectures to be built. */ - void GetAppleArchs(const char* config, std::vector<std::string>& archVec); - /** Return whether this target is an executable with symbol exports enabled. */ bool IsExecutableWithExports(); @@ -462,8 +446,21 @@ public: directory. */ bool UsesDefaultOutputDir(const char* config, bool implib); - /** Get the include directories for this target. */ - std::vector<std::string> GetIncludeDirectories(); + /** Append to @a base the mac content directory and return it. */ + std::string BuildMacContentDirectory(const std::string& base, + const char* config = 0, + bool includeMacOS = true); + + /** @return the mac content directory for this target. */ + std::string GetMacContentDirectory(const char* config = 0, + bool implib = false, + bool includeMacOS = true); + + /** @return whether this target have a well defined output file name. */ + bool HaveWellDefinedOutputFiles(); + + /** @return the Mac framework directory without the base. */ + std::string GetFrameworkDirectory(const char* config = 0); private: /** @@ -580,14 +577,13 @@ private: struct OutputInfo; OutputInfo const* GetOutputInfo(const char* config); bool ComputeOutputDir(const char* config, bool implib, std::string& out); + bool ComputePDBOutputDir(const char* config, std::string& out); // Cache import information from properties for each configuration. struct ImportInfo; ImportInfo const* GetImportInfo(const char* config); void ComputeImportInfo(std::string const& desired_config, ImportInfo& info); - cmTargetLinkInformationMap LinkInformation; - bool ComputeLinkInterface(const char* config, LinkInterface& iface); void ComputeLinkImplementation(const char* config, diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h new file mode 100644 index 0000000..c9d87fb --- /dev/null +++ b/Source/cmTargetExport.h @@ -0,0 +1,39 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmTargetExport_h +#define cmTargetExport_h + +class cmTarget; +class cmInstallTargetGenerator; +class cmInstallFilesGenerator; + +/** \brief A member of an ExportSet + * + * This struct holds pointers to target and all relevant generators. + */ +class cmTargetExport +{ +public: + cmTarget* Target; ///< The target + + ///@name Generators + ///@{ + cmInstallTargetGenerator* ArchiveGenerator; + cmInstallTargetGenerator* RuntimeGenerator; + cmInstallTargetGenerator* LibraryGenerator; + cmInstallTargetGenerator* FrameworkGenerator; + cmInstallTargetGenerator* BundleGenerator; + cmInstallFilesGenerator* HeaderGenerator; + ///@} +}; + +#endif diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index dbea1c3..f42b0f6 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -108,8 +108,8 @@ bool cmTargetLinkLibrariesCommand // specification if the keyword is encountered as the first argument. this->CurrentProcessingState = ProcessingLinkLibraries; - // add libraries, nothe that there is an optional prefix - // of debug and optimized than can be used + // add libraries, note that there is an optional prefix + // of debug and optimized that can be used for(unsigned int i=1; i < args.size(); ++i) { if(args[i] == "LINK_INTERFACE_LIBRARIES") diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index 502c174..912ec76 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -57,7 +57,7 @@ void cmTest::SetCommand(std::vector<std::string> const& command) const char *cmTest::GetProperty(const char* prop) const { bool chain = false; - const char *retVal = + const char *retVal = this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain); if (chain) { @@ -149,14 +149,14 @@ void cmTest::DefineProperties(cmake *cm) "not to run concurrently."); cm->DefineProperty - ("MEASUREMENT", cmProperty::TEST, + ("MEASUREMENT", cmProperty::TEST, "Specify a CDASH measurement and value to be reported for a test.", "If set to a name then that name will be reported to CDASH as a " "named measurement with a value of 1. You may also specify a value " "by setting MEASUREMENT to \"measurement=value\"."); cm->DefineProperty - ("PASS_REGULAR_EXPRESSION", cmProperty::TEST, + ("PASS_REGULAR_EXPRESSION", cmProperty::TEST, "The output must match this regular expression for the test to pass.", "If set, the test output will be checked " "against the specified regular expressions and at least one of the" @@ -183,7 +183,7 @@ void cmTest::DefineProperties(cmake *cm) "any other tests."); cm->DefineProperty - ("TIMEOUT", cmProperty::TEST, + ("TIMEOUT", cmProperty::TEST, "How many seconds to allow for this test.", "This property if set will limit a test to not take more than " "the specified number of seconds to run. If it exceeds that the " @@ -192,7 +192,7 @@ void cmTest::DefineProperties(cmake *cm) "CTEST_TESTING_TIMEOUT."); cm->DefineProperty - ("WILL_FAIL", cmProperty::TEST, + ("WILL_FAIL", cmProperty::TEST, "If set to true, this will invert the pass/fail flag of the test.", "This property can be used for tests that are expected to fail and " "return a non zero return code."); diff --git a/Source/cmTest.h b/Source/cmTest.h index 6223a01..73ac133 100644 --- a/Source/cmTest.h +++ b/Source/cmTest.h @@ -51,7 +51,7 @@ public: const char *GetProperty(const char *prop) const; bool GetPropertyAsBool(const char *prop) const; cmPropertyMap &GetProperties() { return this->Properties; }; - + // Define the properties static void DefineProperties(cmake *cm); diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index e0892b2..2f650e7 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -91,8 +91,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, this->TestGenerated = true; // Set up generator expression evaluation context. - cmMakefile* mf = this->Test->GetMakefile(); - cmGeneratorExpression ge(mf, config, this->Test->GetBacktrace()); + cmGeneratorExpression ge(this->Test->GetBacktrace()); // Start the test command. os << indent << "ADD_TEST(" << this->Test->GetName() << " "; @@ -103,6 +102,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // Check whether the command executable is a target whose name is to // be translated. std::string exe = command[0]; + cmMakefile* mf = this->Test->GetMakefile(); cmTarget* target = mf->FindTargetToUse(exe.c_str()); if(target && target->GetType() == cmTarget::EXECUTABLE) { @@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, else { // Use the command name given. - exe = ge.Process(exe.c_str()); + exe = ge.Parse(exe.c_str()).Evaluate(mf, config); cmSystemTools::ConvertToUnixSlashes(exe); } @@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, for(std::vector<std::string>::const_iterator ci = command.begin()+1; ci != command.end(); ++ci) { - os << " " << lg->EscapeForCMake(ge.Process(*ci)); + os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config)); } // Finish the test command. diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h index 06a9118..7878729 100644 --- a/Source/cmTryRunCommand.h +++ b/Source/cmTryRunCommand.h @@ -25,7 +25,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmTryRunCommand; } @@ -49,7 +49,7 @@ public: { return "Try compiling and then running some code."; } - + /** * More documentation. */ @@ -101,10 +101,10 @@ public: cmTypeMacro(cmTryRunCommand, cmCoreTryCompile); private: - void RunExecutable(const std::string& runArgs, + void RunExecutable(const std::string& runArgs, std::string* runOutputContents); - void DoNotRunExecutable(const std::string& runArgs, - const std::string& srcFile, + void DoNotRunExecutable(const std::string& runArgs, + const std::string& srcFile, std::string* runOutputContents); std::string CompileResultVariable; diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index 0e6f28a..4c189e6 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -17,7 +17,7 @@ // cmUseMangledMesaCommand bool cmUseMangledMesaCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) -{ +{ // expected two arguments: // arguement one: the full path to gl_mangle.h // arguement two : directory for output of edited headers @@ -55,11 +55,11 @@ bool cmUseMangledMesaCommand path += *i; this->CopyAndFullPathMesaHeader(path.c_str(), destDir); } - + return true; } -void +void cmUseMangledMesaCommand:: CopyAndFullPathMesaHeader(const char* source, const char* outdir) @@ -74,7 +74,7 @@ CopyAndFullPathMesaHeader(const char* source, std::ofstream fout(tempOutputFile.c_str()); if(!fout) { - cmSystemTools::Error("Could not open file for write in copy operation: ", + cmSystemTools::Error("Could not open file for write in copy operation: ", tempOutputFile.c_str(), outdir); cmSystemTools::ReportLastSystemError(""); return; @@ -88,7 +88,7 @@ CopyAndFullPathMesaHeader(const char* source, } // now copy input to output and expand variables in the // input file at the same time - std::string inLine; + std::string inLine; // regular expression for any #include line cmsys::RegularExpression includeLine( "^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]"); @@ -108,7 +108,7 @@ CopyAndFullPathMesaHeader(const char* source, } else if(glLine.find(includeFile.c_str())) { - fout << "#include \"" << outdir << "/" << + fout << "#include \"" << outdir << "/" << includeLine.match(1).c_str() << "\"\n"; } else diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index 41c82c2..6ea3dfa 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -22,7 +22,7 @@ bool cmUtilitySourceCommand } std::vector<std::string>::const_iterator arg = args.begin(); - + // The first argument is the cache entry name. std::string cacheEntry = *arg++; const char* cacheValue = @@ -30,7 +30,7 @@ bool cmUtilitySourceCommand // If it exists already and appears up to date then we are done. If // the string contains "(IntDir)" but that is not the // CMAKE_CFG_INTDIR setting then the value is out of date. - const char* intDir = + const char* intDir = this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR"); bool haveCacheValue = false; @@ -60,21 +60,21 @@ bool cmUtilitySourceCommand { return true; } - + // The second argument is the utility's executable name, which will be // needed later. std::string utilityName = *arg++; - + // The third argument specifies the relative directory of the source // of the utility. std::string relativeSource = *arg++; std::string utilitySource = this->Makefile->GetCurrentDirectory(); utilitySource = utilitySource+"/"+relativeSource; - + // If the directory doesn't exist, the source has not been included. if(!cmSystemTools::FileExists(utilitySource.c_str())) { return true; } - + // Make sure all the files exist in the source directory. while(arg != args.end()) { @@ -82,9 +82,9 @@ bool cmUtilitySourceCommand if(!cmSystemTools::FileExists(file.c_str())) { return true; } } - + // The source exists. - std::string cmakeCFGout = + std::string cmakeCFGout = this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR"); std::string utilityDirectory = this->Makefile->GetCurrentOutputDirectory(); std::string exePath; @@ -100,7 +100,7 @@ bool cmUtilitySourceCommand { utilityDirectory += "/"+relativeSource; } - + // Construct the cache entry for the executable's location. std::string utilityExecutable = utilityDirectory+"/"+cmakeCFGout+"/" @@ -108,7 +108,7 @@ bool cmUtilitySourceCommand // make sure we remove any /./ in the name cmSystemTools::ReplaceString(utilityExecutable, "/./", "/"); - + // Enter the value into the cache. this->Makefile->AddCacheDefinition(cacheEntry.c_str(), utilityExecutable.c_str(), @@ -121,7 +121,7 @@ bool cmUtilitySourceCommand utilityName.c_str(), "Executable to project name.", cmCacheManager::INTERNAL); - + return true; } diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h index 32afdda..195f605 100644 --- a/Source/cmUtilitySourceCommand.h +++ b/Source/cmUtilitySourceCommand.h @@ -29,7 +29,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmUtilitySourceCommand; } @@ -53,7 +53,7 @@ public: { return "Specify the source tree of a third-party utility."; } - + /** * More documentation. */ diff --git a/Source/cmVS10LinkFlagTable.h b/Source/cmVS10LinkFlagTable.h index c60e8eb..64febbb 100644 --- a/Source/cmVS10LinkFlagTable.h +++ b/Source/cmVS10LinkFlagTable.h @@ -182,8 +182,8 @@ static cmVS7FlagTable cmVS10LinkFlagTable[] = {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0}, {"SupportNobindOfDelayLoadedDLL", "DELAY:NOBIND", "", "true", 0}, {"Profile", "PROFILE", "", "true", 0}, - {"DelaySign", "DELAYSIGN:NO", "", "false", 0}, - {"DelaySign", "DELAYSIGN", "", "true", 0}, + {"LinkDelaySign", "DELAYSIGN:NO", "", "false", 0}, + {"LinkDelaySign", "DELAYSIGN", "", "true", 0}, {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0}, {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0}, {"ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0}, @@ -294,7 +294,7 @@ static cmVS7FlagTable cmVS10LinkFlagTable[] = {"MergeSections", "MERGE:", "Merge Sections", "", cmVS7FlagTable::UserValue}, - {"KeyFile", "KEYFILE:", + {"LinkKeyFile", "KEYFILE:", "Key File", "", cmVS7FlagTable::UserValue}, {"KeyContainer", "KEYCONTAINER:", diff --git a/Source/cmVS11CLFlagTable.h b/Source/cmVS11CLFlagTable.h new file mode 100644 index 0000000..5ab8ebb --- /dev/null +++ b/Source/cmVS11CLFlagTable.h @@ -0,0 +1,291 @@ +static cmVS7FlagTable cmVS11CLFlagTable[] = +{ + + //Enum Properties + {"DebugInformationFormat", "", + "None", "None", 0}, + {"DebugInformationFormat", "Z7", + "C7 compatible", "OldStyle", 0}, + {"DebugInformationFormat", "Zi", + "Program Database", "ProgramDatabase", 0}, + {"DebugInformationFormat", "ZI", + "Program Database for Edit And Continue", "EditAndContinue", 0}, + + {"WarningLevel", "W0", + "Turn Off All Warnings", "TurnOffAllWarnings", 0}, + {"WarningLevel", "W1", + "Level1", "Level1", 0}, + {"WarningLevel", "W2", + "Level2", "Level2", 0}, + {"WarningLevel", "W3", + "Level3", "Level3", 0}, + {"WarningLevel", "W4", + "Level4", "Level4", 0}, + {"WarningLevel", "Wall", + "EnableAllWarnings", "EnableAllWarnings", 0}, + + {"Optimization", "Od", + "Disabled", "Disabled", 0}, + {"Optimization", "O1", + "Minimize Size", "MinSpace", 0}, + {"Optimization", "O2", + "Maximize Speed", "MaxSpeed", 0}, + {"Optimization", "Ox", + "Full Optimization", "Full", 0}, + + {"InlineFunctionExpansion", "", + "Default", "Default", 0}, + {"InlineFunctionExpansion", "Ob0", + "Disabled", "Disabled", 0}, + {"InlineFunctionExpansion", "Ob1", + "Only __inline", "OnlyExplicitInline", 0}, + {"InlineFunctionExpansion", "Ob2", + "Any Suitable", "AnySuitable", 0}, + + {"FavorSizeOrSpeed", "Os", + "Favor small code", "Size", 0}, + {"FavorSizeOrSpeed", "Ot", + "Favor fast code", "Speed", 0}, + {"FavorSizeOrSpeed", "", + "Neither", "Neither", 0}, + + {"ExceptionHandling", "EHa", + "Yes with SEH Exceptions", "Async", 0}, + {"ExceptionHandling", "EHsc", + "Yes", "Sync", 0}, + {"ExceptionHandling", "EHs", + "Yes with Extern C functions", "SyncCThrow", 0}, + {"ExceptionHandling", "", + "No", "false", 0}, + + {"BasicRuntimeChecks", "RTCs", + "Stack Frames", "StackFrameRuntimeCheck", 0}, + {"BasicRuntimeChecks", "RTCu", + "Uninitialized variables", "UninitializedLocalUsageCheck", 0}, + {"BasicRuntimeChecks", "RTC1", + "Both (/RTC1, equiv. to /RTCsu)", "EnableFastChecks", 0}, + {"BasicRuntimeChecks", "", + "Default", "Default", 0}, + + {"RuntimeLibrary", "MT", + "Multi-threaded", "MultiThreaded", 0}, + {"RuntimeLibrary", "MTd", + "Multi-threaded Debug", "MultiThreadedDebug", 0}, + {"RuntimeLibrary", "MD", + "Multi-threaded DLL", "MultiThreadedDLL", 0}, + {"RuntimeLibrary", "MDd", + "Multi-threaded Debug DLL", "MultiThreadedDebugDLL", 0}, + + {"StructMemberAlignment", "Zp1", + "1 Byte", "1Byte", 0}, + {"StructMemberAlignment", "Zp2", + "2 Bytes", "2Bytes", 0}, + {"StructMemberAlignment", "Zp4", + "4 Byte", "4Bytes", 0}, + {"StructMemberAlignment", "Zp8", + "8 Bytes", "8Bytes", 0}, + {"StructMemberAlignment", "Zp16", + "16 Bytes", "16Bytes", 0}, + {"StructMemberAlignment", "", + "Default", "Default", 0}, + + {"EnableEnhancedInstructionSet", "arch:SSE", + "Streaming SIMD Extensions", "StreamingSIMDExtensions", 0}, + {"EnableEnhancedInstructionSet", "arch:SSE2", + "Streaming SIMD Extensions 2", "StreamingSIMDExtensions2", 0}, + {"EnableEnhancedInstructionSet", "arch:AVX", + "Advanced Vector Extensions", "AdvancedVectorExtensions", 0}, + {"EnableEnhancedInstructionSet", "arch:IA32", + "No Enhanced Instructions", "NoExtensions", 0}, + {"EnableEnhancedInstructionSet", "", + "Not Set", "NotSet", 0}, + + {"FloatingPointModel", "fp:precise", + "Precise", "Precise", 0}, + {"FloatingPointModel", "fp:strict", + "Strict", "Strict", 0}, + {"FloatingPointModel", "fp:fast", + "Fast", "Fast", 0}, + + {"PrecompiledHeader", "Yc", + "Create", "Create", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"PrecompiledHeader", "Yu", + "Use", "Use", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"PrecompiledHeader", "", + "Not Using Precompiled Headers", "NotUsing", 0}, + + {"AssemblerOutput", "", + "No Listing", "NoListing", 0}, + {"AssemblerOutput", "FA", + "Assembly-Only Listing", "AssemblyCode", 0}, + {"AssemblerOutput", "FAc", + "Assembly With Machine Code", "AssemblyAndMachineCode", 0}, + {"AssemblerOutput", "FAs", + "Assembly With Source Code", "AssemblyAndSourceCode", 0}, + {"AssemblerOutput", "FAcs", + "Assembly, Machine Code and Source", "All", 0}, + + {"CallingConvention", "Gd", + "__cdecl", "Cdecl", 0}, + {"CallingConvention", "Gr", + "__fastcall", "FastCall", 0}, + {"CallingConvention", "Gz", + "__stdcall", "StdCall", 0}, + + {"CompileAs", "", + "Default", "Default", 0}, + {"CompileAs", "TC", + "Compile as C Code", "CompileAsC", 0}, + {"CompileAs", "TP", + "Compile as C++ Code", "CompileAsCpp", 0}, + + {"ErrorReporting", "errorReport:none", + "Do Not Send Report", "None", 0}, + {"ErrorReporting", "errorReport:prompt", + "Prompt Immediately", "Prompt", 0}, + {"ErrorReporting", "errorReport:queue", + "Queue For Next Login", "Queue", 0}, + {"ErrorReporting", "errorReport:send", + "Send Automatically", "Send", 0}, + + {"CompileAsManaged", "", + "No Common Language RunTime Support", "false", 0}, + {"CompileAsManaged", "clr", + "Common Language RunTime Support", "true", 0}, + {"CompileAsManaged", "clr:pure", + "Pure MSIL Common Language RunTime Support", "Pure", 0}, + {"CompileAsManaged", "clr:safe", + "Safe MSIL Common Language RunTime Support", "Safe", 0}, + {"CompileAsManaged", "clr:oldSyntax", + "Common Language RunTime Support, Old Syntax", "OldSyntax", 0}, + + + //Bool Properties + {"CompileAsWinRT", "ZW", "", "true", 0}, + {"WinRTNoStdLib", "ZW:nostdlib", "", "true", 0}, + {"SuppressStartupBanner", "nologo-", "", "false", 0}, + {"SuppressStartupBanner", "nologo", "", "true", 0}, + {"TreatWarningAsError", "WX-", "", "false", 0}, + {"TreatWarningAsError", "WX", "", "true", 0}, + {"SDLCheck", "sdl-", "", "false", 0}, + {"SDLCheck", "sdl", "", "true", 0}, + {"IntrinsicFunctions", "Oi", "", "true", 0}, + {"OmitFramePointers", "Oy-", "", "false", 0}, + {"OmitFramePointers", "Oy", "", "true", 0}, + {"EnableFiberSafeOptimizations", "GT", "", "true", 0}, + {"WholeProgramOptimization", "GL", "", "true", 0}, + {"UndefineAllPreprocessorDefinitions", "u", "", "true", 0}, + {"IgnoreStandardIncludePath", "X", "", "true", 0}, + {"PreprocessToFile", "P", "", "true", 0}, + {"PreprocessSuppressLineNumbers", "EP", "", "true", 0}, + {"PreprocessKeepComments", "C", "", "true", 0}, + {"StringPooling", "GF-", "", "false", 0}, + {"StringPooling", "GF", "", "true", 0}, + {"MinimalRebuild", "Gm-", "", "false", 0}, + {"MinimalRebuild", "Gm", "", "true", 0}, + {"SmallerTypeCheck", "RTCc", "", "true", 0}, + {"BufferSecurityCheck", "GS-", "", "false", 0}, + {"BufferSecurityCheck", "GS", "", "true", 0}, + {"FunctionLevelLinking", "Gy-", "", "false", 0}, + {"FunctionLevelLinking", "Gy", "", "true", 0}, + {"EnableParallelCodeGeneration", "Qpar-", "", "false", 0}, + {"EnableParallelCodeGeneration", "Qpar", "", "true", 0}, + {"FloatingPointExceptions", "fp:except-", "", "false", 0}, + {"FloatingPointExceptions", "fp:except", "", "true", 0}, + {"CreateHotpatchableImage", "hotpatch", "", "true", 0}, + {"DisableLanguageExtensions", "Za", "", "true", 0}, + {"TreatWChar_tAsBuiltInType", "Zc:wchar_t-", "", "false", 0}, + {"TreatWChar_tAsBuiltInType", "Zc:wchar_t", "", "true", 0}, + {"ForceConformanceInForLoopScope", "Zc:forScope-", "", "false", 0}, + {"ForceConformanceInForLoopScope", "Zc:forScope", "", "true", 0}, + {"RuntimeTypeInfo", "GR-", "", "false", 0}, + {"RuntimeTypeInfo", "GR", "", "true", 0}, + {"OpenMPSupport", "openmp-", "", "false", 0}, + {"OpenMPSupport", "openmp", "", "true", 0}, + {"ExpandAttributedSource", "Fx", "", "true", 0}, + {"UseUnicodeForAssemblerListing", "FAu", "", "true", 0}, + {"ShowIncludes", "showIncludes", "", "true", 0}, + {"EnablePREfast", "analyze-", "", "false", 0}, + {"EnablePREfast", "analyze", "", "true", 0}, + {"UseFullPaths", "FC", "", "true", 0}, + {"OmitDefaultLibName", "Zl", "", "true", 0}, + + //Bool Properties With Argument + {"MultiProcessorCompilation", "MP", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"ProcessorNumber", "MP", "Multi-processor Compilation", "", + cmVS7FlagTable::UserValueRequired}, + {"GenerateXMLDocumentationFiles", "doc", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"XMLDocumentationFileName", "doc", "Generate XML Documentation Files", "", + cmVS7FlagTable::UserValueRequired}, + {"BrowseInformation", "FR", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"BrowseInformationFile", "FR", "Enable Browse Information", "", + cmVS7FlagTable::UserValueRequired}, + + //String List Properties + {"AdditionalIncludeDirectories", "I", + "Additional Include Directories", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"AdditionalUsingDirectories", "AI", + "Additional #using Directories", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"PreprocessorDefinitions", "D ", + "Preprocessor Definitions", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"UndefinePreprocessorDefinitions", "U", + "Undefine Preprocessor Definitions", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"DisableSpecificWarnings", "wd", + "Disable Specific Warnings", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"ForcedIncludeFiles", "FI", + "Forced Include File", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"ForcedUsingFiles", "FU", + "Forced #using File", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"PREfastAdditionalOptions", "analyze:", + "Additional Code Analysis Native options", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"PREfastAdditionalPlugins", "analyze:plugin", + "Additional Code Analysis Native plugins", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"TreatSpecificWarningsAsErrors", "we", + "Treat Specific Warnings As Errors", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + + //String Properties + // Skip [TrackerLogDirectory] - no command line Switch. + {"PreprocessOutputPath", "Fi", + "Preprocess Output Path", + "", cmVS7FlagTable::UserValue}, + {"PrecompiledHeaderFile", "Yc", + "Precompiled Header Name", + "", cmVS7FlagTable::UserValueRequired}, + {"PrecompiledHeaderFile", "Yu", + "Precompiled Header Name", + "", cmVS7FlagTable::UserValueRequired}, + {"PrecompiledHeaderOutputFile", "Fp", + "Precompiled Header Output File", + "", cmVS7FlagTable::UserValue}, + {"AssemblerListingLocation", "Fa", + "ASM List Location", + "", cmVS7FlagTable::UserValue}, + {"ObjectFileName", "Fo", + "Object File Name", + "", cmVS7FlagTable::UserValue}, + {"ProgramDataBaseFileName", "Fd", + "Program Database File Name", + "", cmVS7FlagTable::UserValue}, + // Skip [XMLDocumentationFileName] - no command line Switch. + // Skip [BrowseInformationFile] - no command line Switch. + {"PREfastLog", "analyze:log ", + "Code Analysis Log", + "", cmVS7FlagTable::UserValue}, + // Skip [AdditionalOptions] - no command line Switch. + {0,0,0,0,0} +}; diff --git a/Source/cmVS11LibFlagTable.h b/Source/cmVS11LibFlagTable.h new file mode 100644 index 0000000..9429442 --- /dev/null +++ b/Source/cmVS11LibFlagTable.h @@ -0,0 +1,102 @@ +static cmVS7FlagTable cmVS11LibFlagTable[] = +{ + + //Enum Properties + {"ErrorReporting", "ERRORREPORT:PROMPT", + "PromptImmediately", "PromptImmediately", 0}, + {"ErrorReporting", "ERRORREPORT:QUEUE", + "Queue For Next Login", "QueueForNextLogin", 0}, + {"ErrorReporting", "ERRORREPORT:SEND", + "Send Error Report", "SendErrorReport", 0}, + {"ErrorReporting", "ERRORREPORT:NONE", + "No Error Report", "NoErrorReport", 0}, + + {"TargetMachine", "MACHINE:ARM", + "MachineARM", "MachineARM", 0}, + {"TargetMachine", "MACHINE:EBC", + "MachineEBC", "MachineEBC", 0}, + {"TargetMachine", "MACHINE:IA64", + "MachineIA64", "MachineIA64", 0}, + {"TargetMachine", "MACHINE:MIPS", + "MachineMIPS", "MachineMIPS", 0}, + {"TargetMachine", "MACHINE:MIPS16", + "MachineMIPS16", "MachineMIPS16", 0}, + {"TargetMachine", "MACHINE:MIPSFPU", + "MachineMIPSFPU", "MachineMIPSFPU", 0}, + {"TargetMachine", "MACHINE:MIPSFPU16", + "MachineMIPSFPU16", "MachineMIPSFPU16", 0}, + {"TargetMachine", "MACHINE:SH4", + "MachineSH4", "MachineSH4", 0}, + {"TargetMachine", "MACHINE:THUMB", + "MachineTHUMB", "MachineTHUMB", 0}, + {"TargetMachine", "MACHINE:X64", + "MachineX64", "MachineX64", 0}, + {"TargetMachine", "MACHINE:X86", + "MachineX86", "MachineX86", 0}, + + {"SubSystem", "SUBSYSTEM:CONSOLE", + "Console", "Console", 0}, + {"SubSystem", "SUBSYSTEM:WINDOWS", + "Windows", "Windows", 0}, + {"SubSystem", "SUBSYSTEM:NATIVE", + "Native", "Native", 0}, + {"SubSystem", "SUBSYSTEM:EFI_APPLICATION", + "EFI Application", "EFI Application", 0}, + {"SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER", + "EFI Boot Service Driver", "EFI Boot Service Driver", 0}, + {"SubSystem", "SUBSYSTEM:EFI_ROM", + "EFI ROM", "EFI ROM", 0}, + {"SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER", + "EFI Runtime", "EFI Runtime", 0}, + {"SubSystem", "SUBSYSTEM:WINDOWSCE", + "WindowsCE", "WindowsCE", 0}, + {"SubSystem", "SUBSYSTEM:POSIX", + "POSIX", "POSIX", 0}, + + + //Bool Properties + {"SuppressStartupBanner", "NOLOGO", "", "true", 0}, + {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0}, + {"TreatLibWarningAsErrors", "WX:NO", "", "false", 0}, + {"TreatLibWarningAsErrors", "WX", "", "true", 0}, + {"Verbose", "VERBOSE", "", "true", 0}, + {"LinkTimeCodeGeneration", "LTCG", "", "true", 0}, + + //Bool Properties With Argument + + //String List Properties + // Skip [AdditionalDependencies] - no command line Switch. + {"AdditionalLibraryDirectories", "LIBPATH:", + "Additional Library Directories", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:", + "Ignore Specific Default Libraries", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"ExportNamedFunctions", "EXPORT:", + "Export Named Functions", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"RemoveObjects", "REMOVE:", + "Remove Objects", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + + //String Properties + {"OutputFile", "OUT:", + "Output File", + "", cmVS7FlagTable::UserValue}, + {"ModuleDefinitionFile", "DEF:", + "Module Definition File Name", + "", cmVS7FlagTable::UserValue}, + {"ForceSymbolReferences", "INCLUDE:", + "Force Symbol References", + "", cmVS7FlagTable::UserValue}, + {"DisplayLibrary", "LIST:", + "Display Library to standard output", + "", cmVS7FlagTable::UserValue}, + // Skip [MinimumRequiredVersion] - no command line Switch. + {"Name", "NAME:", + "Name", + "", cmVS7FlagTable::UserValue}, + // Skip [AdditionalOptions] - no command line Switch. + // Skip [TrackerLogDirectory] - no command line Switch. + {0,0,0,0,0} +}; diff --git a/Source/cmVS11LinkFlagTable.h b/Source/cmVS11LinkFlagTable.h new file mode 100644 index 0000000..ea0d0f0 --- /dev/null +++ b/Source/cmVS11LinkFlagTable.h @@ -0,0 +1,343 @@ +static cmVS7FlagTable cmVS11LinkFlagTable[] = +{ + + //Enum Properties + {"ShowProgress", "", + "Not Set", "NotSet", 0}, + {"ShowProgress", "VERBOSE", + "Display all progress messages", "LinkVerbose", 0}, + {"ShowProgress", "VERBOSE:Lib", + "For Libraries Searched", "LinkVerboseLib", 0}, + {"ShowProgress", "VERBOSE:ICF", + "About COMDAT folding during optimized linking", "LinkVerboseICF", 0}, + {"ShowProgress", "VERBOSE:REF", + "About data removed during optimized linking", "LinkVerboseREF", 0}, + {"ShowProgress", "VERBOSE:SAFESEH", + "About Modules incompatible with SEH", "LinkVerboseSAFESEH", 0}, + {"ShowProgress", "VERBOSE:CLR", + "About linker activity related to managed code", "LinkVerboseCLR", 0}, + + {"ForceFileOutput", "FORCE", + "Enabled", "Enabled", 0}, + {"ForceFileOutput", "FORCE:MULTIPLE", + "Multiply Defined Symbol Only", "MultiplyDefinedSymbolOnly", 0}, + {"ForceFileOutput", "FORCE:UNRESOLVED", + "Undefined Symbol Only", "UndefinedSymbolOnly", 0}, + + {"CreateHotPatchableImage", "FUNCTIONPADMIN", + "Enabled", "Enabled", 0}, + {"CreateHotPatchableImage", "FUNCTIONPADMIN:5", + "X86 Image Only", "X86Image", 0}, + {"CreateHotPatchableImage", "FUNCTIONPADMIN:6", + "X64 Image Only", "X64Image", 0}, + {"CreateHotPatchableImage", "FUNCTIONPADMIN:16", + "Itanium Image Only", "ItaniumImage", 0}, + + {"UACExecutionLevel", "level='asInvoker'", + "asInvoker", "AsInvoker", 0}, + {"UACExecutionLevel", "level='highestAvailable'", + "highestAvailable", "HighestAvailable", 0}, + {"UACExecutionLevel", "level='requireAdministrator'", + "requireAdministrator", "RequireAdministrator", 0}, + + {"SubSystem", "", + "Not Set", "NotSet", 0}, + {"SubSystem", "SUBSYSTEM:CONSOLE", + "Console", "Console", 0}, + {"SubSystem", "SUBSYSTEM:WINDOWS", + "Windows", "Windows", 0}, + {"SubSystem", "SUBSYSTEM:NATIVE", + "Native", "Native", 0}, + {"SubSystem", "SUBSYSTEM:EFI_APPLICATION", + "EFI Application", "EFI Application", 0}, + {"SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER", + "EFI Boot Service Driver", "EFI Boot Service Driver", 0}, + {"SubSystem", "SUBSYSTEM:EFI_ROM", + "EFI ROM", "EFI ROM", 0}, + {"SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER", + "EFI Runtime", "EFI Runtime", 0}, + {"SubSystem", "SUBSYSTEM:POSIX", + "POSIX", "POSIX", 0}, + + {"Driver", "", + "Not Set", "NotSet", 0}, + {"Driver", "Driver", + "Driver", "Driver", 0}, + {"Driver", "DRIVER:UPONLY", + "UP Only", "UpOnly", 0}, + {"Driver", "DRIVER:WDM", + "WDM", "WDM", 0}, + + {"LinkTimeCodeGeneration", "", + "Default", "Default", 0}, + {"LinkTimeCodeGeneration", "LTCG", + "Use Link Time Code Generation", "UseLinkTimeCodeGeneration", 0}, + {"LinkTimeCodeGeneration", "LTCG:PGInstrument", + "Profile Guided Optimization - Instrument", "PGInstrument", 0}, + {"LinkTimeCodeGeneration", "LTCG:PGOptimize", + "Profile Guided Optimization - Optimization", "PGOptimization", 0}, + {"LinkTimeCodeGeneration", "LTCG:PGUpdate", + "Profile Guided Optimization - Update", "PGUpdate", 0}, + + {"GenerateWindowsMetadata", "WINMD", + "Yes", "true", 0}, + {"GenerateWindowsMetadata", "WINMD:NO", + "No", "false", 0}, + + {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA1", + "SHA1", "SHA1", 0}, + {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA256", + "SHA256", "SHA256", 0}, + {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA384", + "SHA384", "SHA384", 0}, + {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA512", + "SHA512", "SHA512", 0}, + + {"TargetMachine", "", + "Not Set", "NotSet", 0}, + {"TargetMachine", "MACHINE:ARM", + "MachineARM", "MachineARM", 0}, + {"TargetMachine", "MACHINE:EBC", + "MachineEBC", "MachineEBC", 0}, + {"TargetMachine", "MACHINE:IA64", + "MachineIA64", "MachineIA64", 0}, + {"TargetMachine", "MACHINE:MIPS", + "MachineMIPS", "MachineMIPS", 0}, + {"TargetMachine", "MACHINE:MIPS16", + "MachineMIPS16", "MachineMIPS16", 0}, + {"TargetMachine", "MACHINE:MIPSFPU", + "MachineMIPSFPU", "MachineMIPSFPU", 0}, + {"TargetMachine", "MACHINE:MIPSFPU16", + "MachineMIPSFPU16", "MachineMIPSFPU16", 0}, + {"TargetMachine", "MACHINE:SH4", + "MachineSH4", "MachineSH4", 0}, + {"TargetMachine", "MACHINE:THUMB", + "MachineTHUMB", "MachineTHUMB", 0}, + {"TargetMachine", "MACHINE:X64", + "MachineX64", "MachineX64", 0}, + {"TargetMachine", "MACHINE:X86", + "MachineX86", "MachineX86", 0}, + + {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:MTA", + "MTA threading attribute", "MTAThreadingAttribute", 0}, + {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:STA", + "STA threading attribute", "STAThreadingAttribute", 0}, + {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:NONE", + "Default threading attribute", "DefaultThreadingAttribute", 0}, + + {"CLRImageType", "CLRIMAGETYPE:IJW", + "Force IJW image", "ForceIJWImage", 0}, + {"CLRImageType", "CLRIMAGETYPE:PURE", + "Force Pure IL Image", "ForcePureILImage", 0}, + {"CLRImageType", "CLRIMAGETYPE:SAFE", + "Force Safe IL Image", "ForceSafeILImage", 0}, + {"CLRImageType", "", + "Default image type", "Default", 0}, + + {"SignHash", "CLRSIGNHASH:SHA1", + "SHA1", "SHA1", 0}, + {"SignHash", "CLRSIGNHASH:SHA256", + "SHA256", "SHA256", 0}, + {"SignHash", "CLRSIGNHASH:SHA384", + "SHA384", "SHA384", 0}, + {"SignHash", "CLRSIGNHASH:SHA512", + "SHA512", "SHA512", 0}, + + {"LinkErrorReporting", "ERRORREPORT:PROMPT", + "PromptImmediately", "PromptImmediately", 0}, + {"LinkErrorReporting", "ERRORREPORT:QUEUE", + "Queue For Next Login", "QueueForNextLogin", 0}, + {"LinkErrorReporting", "ERRORREPORT:SEND", + "Send Error Report", "SendErrorReport", 0}, + {"LinkErrorReporting", "ERRORREPORT:NONE", + "No Error Report", "NoErrorReport", 0}, + + {"CLRSupportLastError", "CLRSupportLastError", + "Enabled", "Enabled", 0}, + {"CLRSupportLastError", "CLRSupportLastError:NO", + "Disabled", "Disabled", 0}, + {"CLRSupportLastError", "CLRSupportLastError:SYSTEMDLL", + "System Dlls Only", "SystemDlls", 0}, + + + //Bool Properties + {"LinkIncremental", "INCREMENTAL:NO", "", "false", 0}, + {"LinkIncremental", "INCREMENTAL", "", "true", 0}, + {"SuppressStartupBanner", "NOLOGO", "", "true", 0}, + {"LinkStatus", "LTCG:NOSTATUS", "", "false", 0}, + {"LinkStatus", "LTCG:STATUS", "", "true", 0}, + {"PreventDllBinding", "ALLOWBIND:NO", "", "false", 0}, + {"PreventDllBinding", "ALLOWBIND", "", "true", 0}, + {"TreatLinkerWarningAsErrors", "WX:NO", "", "false", 0}, + {"TreatLinkerWarningAsErrors", "WX", "", "true", 0}, + {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0}, + {"GenerateManifest", "MANIFEST:NO", "", "false", 0}, + {"GenerateManifest", "MANIFEST", "", "true", 0}, + {"AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0}, + {"UACUIAccess", "uiAccess='false'", "", "false", 0}, + {"UACUIAccess", "uiAccess='true'", "", "true", 0}, + {"ManifestEmbed", "manifest:embed", "", "true", 0}, + {"GenerateDebugInformation", "DEBUG", "", "true", 0}, + {"MapExports", "MAPINFO:EXPORTS", "", "true", 0}, + {"AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0}, + {"AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0}, + {"LargeAddressAware", "LARGEADDRESSAWARE:NO", "", "false", 0}, + {"LargeAddressAware", "LARGEADDRESSAWARE", "", "true", 0}, + {"TerminalServerAware", "TSAWARE:NO", "", "false", 0}, + {"TerminalServerAware", "TSAWARE", "", "true", 0}, + {"SwapRunFromCD", "SWAPRUN:CD", "", "true", 0}, + {"SwapRunFromNET", "SWAPRUN:NET", "", "true", 0}, + {"OptimizeReferences", "OPT:NOREF", "", "false", 0}, + {"OptimizeReferences", "OPT:REF", "", "true", 0}, + {"EnableCOMDATFolding", "OPT:NOICF", "", "false", 0}, + {"EnableCOMDATFolding", "OPT:ICF", "", "true", 0}, + {"IgnoreEmbeddedIDL", "IGNOREIDL", "", "true", 0}, + {"AppContainer", "APPCONTAINER", "", "true", 0}, + {"WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN:NO", "", "false", 0}, + {"WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN", "", "true", 0}, + {"NoEntryPoint", "NOENTRY", "", "true", 0}, + {"SetChecksum", "RELEASE", "", "true", 0}, + {"RandomizedBaseAddress", "DYNAMICBASE:NO", "", "false", 0}, + {"RandomizedBaseAddress", "DYNAMICBASE", "", "true", 0}, + {"FixedBaseAddress", "FIXED:NO", "", "false", 0}, + {"FixedBaseAddress", "FIXED", "", "true", 0}, + {"DataExecutionPrevention", "NXCOMPAT:NO", "", "false", 0}, + {"DataExecutionPrevention", "NXCOMPAT", "", "true", 0}, + {"TurnOffAssemblyGeneration", "NOASSEMBLY", "", "true", 0}, + {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0}, + {"SupportNobindOfDelayLoadedDLL", "DELAY:NOBIND", "", "true", 0}, + {"Profile", "PROFILE", "", "true", 0}, + {"LinkDelaySign", "DELAYSIGN:NO", "", "false", 0}, + {"LinkDelaySign", "DELAYSIGN", "", "true", 0}, + {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0}, + {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0}, + {"DetectOneDefinitionRule", "ODR", "", "true", 0}, + {"ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0}, + {"ImageHasSafeExceptionHandlers", "SAFESEH", "", "true", 0}, + {"LinkDLL", "DLL", "", "true", 0}, + + //Bool Properties With Argument + {"EnableUAC", "MANIFESTUAC:NO", "", "false", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"EnableUAC", "MANIFESTUAC:NO", "Enable User Account Control (UAC)", "", + cmVS7FlagTable::UserValueRequired}, + {"EnableUAC", "MANIFESTUAC:", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "", + cmVS7FlagTable::UserValueRequired}, + {"GenerateMapFile", "MAP", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue}, + {"MapFileName", "MAP", "Generate Map File", "", + cmVS7FlagTable::UserValueRequired}, + + //String List Properties + {"AdditionalLibraryDirectories", "LIBPATH:", + "Additional Library Directories", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + // Skip [AdditionalDependencies] - no command line Switch. + {"IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:", + "Ignore Specific Default Libraries", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"AddModuleNamesToAssembly", "ASSEMBLYMODULE:", + "Add Module to Assembly", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"EmbedManagedResourceFile", "ASSEMBLYRESOURCE:", + "Embed Managed Resource File", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"ForceSymbolReferences", "INCLUDE:", + "Force Symbol References", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"DelayLoadDLLs", "DELAYLOAD:", + "Delay Loaded Dlls", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"AssemblyLinkResource", "ASSEMBLYLINKRESOURCE:", + "Assembly Link Resource", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"AdditionalManifestDependencies", "MANIFESTDEPENDENCY:", + "Additional Manifest Dependencies", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + {"ManifestInput", "manifestinput:", + "Manifest Input", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, + + //String Properties + {"OutputFile", "OUT:", + "Output File", + "", cmVS7FlagTable::UserValue}, + {"Version", "VERSION:", + "Version", + "", cmVS7FlagTable::UserValue}, + {"SpecifySectionAttributes", "SECTION:", + "Specify Section Attributes", + "", cmVS7FlagTable::UserValue}, + {"MSDOSStubFileName", "STUB:", + "MS-DOS Stub File Name", + "", cmVS7FlagTable::UserValue}, + // Skip [TrackerLogDirectory] - no command line Switch. + {"ModuleDefinitionFile", "DEF:", + "Module Definition File", + "", cmVS7FlagTable::UserValue}, + {"ManifestFile", "ManifestFile:", + "Manifest File", + "", cmVS7FlagTable::UserValue}, + {"ProgramDatabaseFile", "PDB:", + "Generate Program Database File", + "", cmVS7FlagTable::UserValue}, + {"StripPrivateSymbols", "PDBSTRIPPED:", + "Strip Private Symbols", + "", cmVS7FlagTable::UserValue}, + // Skip [MapFileName] - no command line Switch. + // Skip [MinimumRequiredVersion] - no command line Switch. + {"HeapReserveSize", "HEAP:", + "Heap Reserve Size", + "", cmVS7FlagTable::UserValue}, + // Skip [HeapCommitSize] - no command line Switch. + {"StackReserveSize", "STACK:", + "Stack Reserve Size", + "", cmVS7FlagTable::UserValue}, + // Skip [StackCommitSize] - no command line Switch. + {"FunctionOrder", "ORDER:@", + "Function Order", + "", cmVS7FlagTable::UserValue}, + {"ProfileGuidedDatabase", "PGD:", + "Profile Guided Database", + "", cmVS7FlagTable::UserValue}, + {"MidlCommandFile", "MIDL:@", + "MIDL Commands", + "", cmVS7FlagTable::UserValue}, + {"MergedIDLBaseFileName", "IDLOUT:", + "Merged IDL Base File Name", + "", cmVS7FlagTable::UserValue}, + {"TypeLibraryFile", "TLBOUT:", + "Type Library", + "", cmVS7FlagTable::UserValue}, + {"WindowsMetadataFile", "WINMDFILE:", + "Windows Metadata File", + "", cmVS7FlagTable::UserValue}, + {"WindowsMetadataLinkKeyFile", "WINMDKEYFILE:", + "Windows Metadata Key File", + "", cmVS7FlagTable::UserValue}, + {"WindowsMetadataKeyContainer", "WINMDKEYCONTAINER:", + "Windows Metadata Key Container", + "", cmVS7FlagTable::UserValue}, + {"EntryPointSymbol", "ENTRY:", + "Entry Point", + "", cmVS7FlagTable::UserValue}, + {"BaseAddress", "BASE:", + "Base Address", + "", cmVS7FlagTable::UserValue}, + {"ImportLibrary", "IMPLIB:", + "Import Library", + "", cmVS7FlagTable::UserValue}, + {"MergeSections", "MERGE:", + "Merge Sections", + "", cmVS7FlagTable::UserValue}, + {"LinkKeyFile", "KEYFILE:", + "Key File", + "", cmVS7FlagTable::UserValue}, + {"KeyContainer", "KEYCONTAINER:", + "Key Container", + "", cmVS7FlagTable::UserValue}, + // Skip [AdditionalOptions] - no command line Switch. + {0,0,0,0,0} +}; diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 0e97a83..747e9be 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -22,7 +22,7 @@ bool cmVariableRequiresCommand return false; } - std::string testVariable = args[0]; + std::string testVariable = args[0]; if(!this->Makefile->IsOn(testVariable.c_str())) { return true; @@ -38,7 +38,7 @@ bool cmVariableRequiresCommand requirementsMet = false; notSet += args[i]; notSet += "\n"; - cmCacheManager::CacheIterator it = + cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->GetCacheIterator(args[i].c_str()); if(!it.IsAtEnd() && it.GetPropertyAsBool("ADVANCED")) { @@ -47,7 +47,7 @@ bool cmVariableRequiresCommand } } const char* reqVar = this->Makefile->GetDefinition(resultVariable.c_str()); - // if reqVar is unset, then set it to requirementsMet + // if reqVar is unset, then set it to requirementsMet // if reqVar is set to true, but requirementsMet is false , then // set reqVar to false. if(!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar))) @@ -58,14 +58,14 @@ bool cmVariableRequiresCommand if(!requirementsMet) { std::string message = "Variable assertion failed:\n"; - message += testVariable + + message += testVariable + " Requires that the following unset variables are set:\n"; message += notSet; message += "\nPlease set them, or set "; message += testVariable + " to false, and re-configure.\n"; if(hasAdvanced) { - message += + message += "One or more of the required variables is advanced." " To set the variable, you must turn on advanced mode in cmake."; } diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h index 91c351e..c86f43d 100644 --- a/Source/cmVariableRequiresCommand.h +++ b/Source/cmVariableRequiresCommand.h @@ -24,7 +24,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmVariableRequiresCommand; } @@ -35,7 +35,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -48,7 +48,7 @@ public: { return "Deprecated. Use the if() command instead."; } - + /** * More documentation. */ @@ -63,12 +63,12 @@ public: "tested, if that variable is false nothing else is done. If " "TEST_VARIABLE is true, then " "the next argument (RESULT_VARIABLE) is a variable that is set to true " - "if all the required variables are set. " + "if all the required variables are set. " "The rest of the arguments are variables that must be true or not " "set to NOTFOUND to avoid an error. If any are not true, an error " "is reported."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index 47bab15..f5fdca4 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -38,7 +38,7 @@ cmVariableWatch::~cmVariableWatch() { } -void cmVariableWatch::AddWatch(const std::string& variable, +void cmVariableWatch::AddWatch(const std::string& variable, WatchMethod method, void* client_data /*=0*/) { cmVariableWatch::Pair p; @@ -58,7 +58,7 @@ void cmVariableWatch::AddWatch(const std::string& variable, vp->push_back(p); } -void cmVariableWatch::RemoveWatch(const std::string& variable, +void cmVariableWatch::RemoveWatch(const std::string& variable, WatchMethod method) { cmVariableWatch::VectorOfPairs* vp = &this->WatchMap[variable]; @@ -73,12 +73,12 @@ void cmVariableWatch::RemoveWatch(const std::string& variable, } } -void cmVariableWatch::VariableAccessed(const std::string& variable, +void cmVariableWatch::VariableAccessed(const std::string& variable, int access_type, const char* newValue, const cmMakefile* mf) const { - cmVariableWatch::StringToVectorOfPairs::const_iterator mit = + cmVariableWatch::StringToVectorOfPairs::const_iterator mit = this->WatchMap.find(variable); if ( mit != this->WatchMap.end() ) { diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h index 83e9e97..7dd4ac5 100644 --- a/Source/cmVariableWatch.h +++ b/Source/cmVariableWatch.h @@ -36,7 +36,7 @@ public: void AddWatch(const std::string& variable, WatchMethod method, void* client_data=0); void RemoveWatch(const std::string& variable, WatchMethod method); - + /** * This method is called when variable is accessed */ @@ -61,7 +61,7 @@ public: * Return the access as string */ static const char* GetAccessAsString(int access_type); - + protected: struct Pair { diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 93c05af..a432943 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -95,7 +95,7 @@ void cmVariableWatchCommand::VariableAccessed(const std::string& variable, cmListFileArgument(currentListFile, true, "unknown", 9999)); newLFF.Arguments.push_back( cmListFileArgument(stack, true, "unknown", 9999)); - newLFF.Name = command; + newLFF.Name = command; newLFF.FilePath = "Some weird path"; newLFF.Line = 9999; cmExecutionStatus status; diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h index cb80736..3abc088 100644 --- a/Source/cmVariableWatchCommand.h +++ b/Source/cmVariableWatchCommand.h @@ -31,7 +31,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmVariableWatchCommand; } @@ -67,7 +67,7 @@ public: { return "Watch the CMake variable for change."; } - + /** * More documentation. */ @@ -80,7 +80,7 @@ public: "will be executed. The command will receive the following arguments:" " COMMAND(<variable> <access> <value> <current list file> <stack>)"; } - + cmTypeMacro(cmVariableWatchCommand, cmCommand); void VariableAccessed(const std::string& variable, int access_type, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9a97ab0..def4133 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -22,9 +22,36 @@ #include "cmVS10CLFlagTable.h" #include "cmVS10LinkFlagTable.h" #include "cmVS10LibFlagTable.h" +#include "cmVS11CLFlagTable.h" +#include "cmVS11LinkFlagTable.h" +#include "cmVS11LibFlagTable.h" #include <cmsys/auto_ptr.hxx> +static cmVS7FlagTable const* +cmVSGetCLFlagTable(cmLocalVisualStudioGenerator* lg) +{ + if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS11) + { return cmVS11CLFlagTable; } + return cmVS10CLFlagTable; +} + +static cmVS7FlagTable const* +cmVSGetLibFlagTable(cmLocalVisualStudioGenerator* lg) +{ + if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS11) + { return cmVS11LibFlagTable; } + return cmVS10LibFlagTable; +} + +static cmVS7FlagTable const* +cmVSGetLinkFlagTable(cmLocalVisualStudioGenerator* lg) +{ + if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS11) + { return cmVS11LinkFlagTable; } + return cmVS10LinkFlagTable; +} + static std::string cmVS10EscapeXML(std::string arg) { cmSystemTools::ReplaceString(arg, "&", "&"); @@ -65,7 +92,7 @@ cmVisualStudio10TargetGenerator(cmTarget* target, this->Target = target; this->GeneratorTarget = gg->GetGeneratorTarget(target); this->Makefile = target->GetMakefile(); - this->LocalGenerator = + this->LocalGenerator = (cmLocalVisualStudio7Generator*) this->Makefile->GetLocalGenerator(); this->Name = this->Target->GetName(); @@ -82,6 +109,11 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() { delete i->second; } + for(OptionsMap::iterator i = this->LinkOptions.begin(); + i != this->LinkOptions.end(); ++i) + { + delete i->second; + } if(!this->BuildFileStream) { return; @@ -108,9 +140,9 @@ void cmVisualStudio10TargetGenerator::WritePlatformConfigTag( stream = this->BuildFileStream; } stream->fill(' '); - stream->width(indentLevel*2 ); + stream->width(indentLevel*2 ); (*stream ) << ""; - (*stream ) << "<" << tag + (*stream ) << "<" << tag << " Condition=\"'$(Configuration)|$(Platform)'=='"; (*stream ) << config << "|" << this->Platform << "'\""; if(attribute) @@ -154,6 +186,10 @@ void cmVisualStudio10TargetGenerator::Generate() { return; } + if(!this->ComputeLinkOptions()) + { + return; + } } cmMakefile* mf = this->Target->GetMakefile(); std::string path = mf->GetStartOutputDirectory(); @@ -164,7 +200,7 @@ void cmVisualStudio10TargetGenerator::Generate() new cmGeneratedFileStream(path.c_str()); this->PathToVcxproj = path; this->BuildFileStream->SetCopyIfDifferent(true); - + // Write the encoding header into the file char magic[] = {0xEF,0xBB, 0xBF}; this->BuildFileStream->write(magic, 3); @@ -370,9 +406,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() break; } configType += "</ConfigurationType>\n"; - this->WriteString(configType.c_str(), 2); + this->WriteString(configType.c_str(), 2); - const char* mfcFlag = + const char* mfcFlag = this->Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG"); std::string mfcFlagValue = mfcFlag ? mfcFlag : "0"; @@ -413,7 +449,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() } if(this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { - this->WriteString("<Immersive>true</Immersive>\n", 2); + this->WriteString("<WindowsAppContainer>true" + "</WindowsAppContainer>\n", 2); } this->WriteString("</PropertyGroup>\n", 1); } @@ -453,9 +490,9 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommand(cmSourceFile* sf) } } -void +void cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, - cmCustomCommand const & + cmCustomCommand const & command) { std::string sourcePath = source->GetFullPath(); @@ -490,7 +527,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, comment = cmVS10EscapeComment(comment); std::vector<std::string> *configs = static_cast<cmGlobalVisualStudio7Generator *> - (this->GlobalGenerator)->GetConfigurations(); + (this->GlobalGenerator)->GetConfigurations(); this->WriteSource("CustomBuild", source, ">\n"); @@ -504,11 +541,11 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, this->WritePlatformConfigTag("Command", i->c_str(), 3); (*this->BuildFileStream ) << script << "</Command>\n"; this->WritePlatformConfigTag("AdditionalInputs", i->c_str(), 3); - + (*this->BuildFileStream ) << source->GetFullPath(); - for(std::vector<std::string>::const_iterator d = + for(std::vector<std::string>::const_iterator d = command.GetDepends().begin(); - d != command.GetDepends().end(); + d != command.GetDepends().end(); ++d) { std::string dep; @@ -521,9 +558,9 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, (*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n"; this->WritePlatformConfigTag("Outputs", i->c_str(), 3); const char* sep = ""; - for(std::vector<std::string>::const_iterator o = + for(std::vector<std::string>::const_iterator o = command.GetOutputs().begin(); - o != command.GetOutputs().end(); + o != command.GetOutputs().end(); ++o) { std::string out = *o; @@ -559,19 +596,19 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s) } } void cmVisualStudio10TargetGenerator::WriteGroups() -{ +{ // collect up group information - std::vector<cmSourceGroup> sourceGroups = + std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); std::vector<cmSourceFile*> classes = this->Target->GetSourceFiles(); - + std::set<cmSourceGroup*> groupsUsed; - for(std::vector<cmSourceFile*>::const_iterator s = classes.begin(); + for(std::vector<cmSourceFile*>::const_iterator s = classes.begin(); s != classes.end(); s++) { - cmSourceFile* sf = *s; + cmSourceFile* sf = *s; std::string const& source = sf->GetFullPath(); - cmSourceGroup& sourceGroup = + cmSourceGroup& sourceGroup = this->Makefile->FindSourceGroup(source.c_str(), sourceGroups); groupsUsed.insert(&sourceGroup); } @@ -634,9 +671,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups() guidName += name; this->GlobalGenerator->CreateGUID(guidName.c_str()); this->WriteString("<UniqueIdentifier>", 3); - std::string guid + std::string guid = this->GlobalGenerator->GetGUID(guidName.c_str()); - (*this->BuildFileStream) + (*this->BuildFileStream) << "{" << guid << "}" << "</UniqueIdentifier>\n"; @@ -724,10 +761,10 @@ WriteGroupSources(const char* name, { cmSourceFile* sf = s->SourceFile; std::string const& source = sf->GetFullPath(); - cmSourceGroup& sourceGroup = + cmSourceGroup& sourceGroup = this->Makefile->FindSourceGroup(source.c_str(), sourceGroups); const char* filter = sourceGroup.GetFullName(); - this->WriteString("<", 2); + this->WriteString("<", 2); std::string path = this->ConvertPath(source, s->RelativePath); this->ConvertToWindowsSlash(path); (*this->BuildFileStream) << name << " Include=\"" @@ -868,7 +905,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources() bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( cmSourceFile* source) -{ +{ cmSourceFile& sf = *source; cmLocalVisualStudio7Generator* lg = this->LocalGenerator; @@ -883,7 +920,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( if(const char* cflags = sf.GetProperty("COMPILE_FLAGS")) { flags += cflags; - } + } if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { defines += cdefs; @@ -899,7 +936,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( { needForceLang = true; lang = sourceLang; - } + } // if the source file does not match the linker language // then force c or c++ if(needForceLang || (linkLanguage && lang @@ -923,7 +960,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( if(objectName.size()) { (*this->BuildFileStream ) << firstString; - firstString = ""; + firstString = ""; hasFlags = true; this->WriteString("<ObjectFileName>", 3); (*this->BuildFileStream ) @@ -934,7 +971,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( (this->GlobalGenerator)->GetConfigurations(); for( std::vector<std::string>::iterator config = configs->begin(); config != configs->end(); ++config) - { + { std::string configUpper = cmSystemTools::UpperCase(*config); std::string configDefines = defines; std::string defPropName = "COMPILE_DEFINITIONS_"; @@ -947,22 +984,22 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( } configDefines += ccdefs; } - // if we have flags or defines for this config then + // if we have flags or defines for this config then // use them if(flags.size() || configDefines.size()) { (*this->BuildFileStream ) << firstString; firstString = ""; // only do firstString once hasFlags = true; - cmVisualStudioGeneratorOptions + cmVisualStudioGeneratorOptions clOptions(this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler, - cmVS10CLFlagTable, 0, this); + cmVSGetCLFlagTable(this->LocalGenerator), 0, this); clOptions.Parse(flags.c_str()); clOptions.AddDefines(configDefines.c_str()); clOptions.SetConfiguration((*config).c_str()); clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); - clOptions.OutputFlagMap(*this->BuildFileStream, " "); + clOptions.OutputFlagMap(*this->BuildFileStream, " "); clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", "\n", lang); } @@ -1045,11 +1082,10 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() -void +void cmVisualStudio10TargetGenerator:: OutputLinkIncremental(std::string const& configName) -{ - std::string CONFIG = cmSystemTools::UpperCase(configName); +{ // static libraries and things greater than modules do not need // to set this option if(this->Target->GetType() == cmTarget::STATIC_LIBRARY @@ -1057,72 +1093,36 @@ OutputLinkIncremental(std::string const& configName) { return; } - const char* linkType = "SHARED"; - if(this->Target->GetType() == cmTarget::EXECUTABLE) - { - linkType = "EXE"; - } - - // assume incremental linking - const char* incremental = "true"; - const char* linkLanguage = - this->Target->GetLinkerLanguage(configName.c_str()); - if(!linkLanguage) - { - cmSystemTools::Error - ("CMake can not determine linker language for target:", - this->Name.c_str()); - return; - } - std::string linkFlagVarBase = "CMAKE_"; - linkFlagVarBase += linkType; - linkFlagVarBase += "_LINKER_FLAGS"; - std::string flags = this-> - Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str()); - std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG; - flags += this-> - Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str()); - if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0 - || strcmp(linkLanguage, "Fortran") == 0) - { - std::string baseFlagVar = "CMAKE_"; - baseFlagVar += linkLanguage; - baseFlagVar += "_FLAGS"; - flags += this-> - Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str()); - std::string flagVar = baseFlagVar + std::string("_") + CONFIG; - flags += - Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str()); - } - const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS"); - if(targetLinkFlags) - { - flags += " "; - flags += targetLinkFlags; - } - std::string flagsProp = "LINK_FLAGS_"; - flagsProp += CONFIG; - if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str())) - { - flags += " "; - flags += flagsConfig; - } - if(flags.find("INCREMENTAL:NO") != flags.npos) - { - incremental = "false"; - } + Options& linkOptions = *(this->LinkOptions[configName]); + + const char* incremental = linkOptions.GetFlag("LinkIncremental"); this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3); - *this->BuildFileStream << incremental - << "</LinkIncremental>\n"; + *this->BuildFileStream << (incremental?incremental:"true") + << "</LinkIncremental>\n"; + linkOptions.RemoveFlag("LinkIncremental"); - const char* manifest = "true"; - if(flags.find("MANIFEST:NO") != flags.npos) - { - manifest = "false"; - } + const char* manifest = linkOptions.GetFlag("GenerateManifest"); this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3); - *this->BuildFileStream << manifest + *this->BuildFileStream << (manifest?manifest:"true") << "</GenerateManifest>\n"; + linkOptions.RemoveFlag("GenerateManifest"); + + // Some link options belong here. Use them now and remove them so that + // WriteLinkOptions does not use them. + const char* flags[] = { + "LinkDelaySign", + "LinkKeyFile", + 0}; + for(const char** f = flags; *f; ++f) + { + const char* flag = *f; + if(const char* value = linkOptions.GetFlag(flag)) + { + this->WritePlatformConfigTag(flag, configName.c_str(), 3); + *this->BuildFileStream << value << "</" << flag << ">\n"; + linkOptions.RemoveFlag(flag); + } + } } //---------------------------------------------------------------------------- @@ -1151,11 +1151,11 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( cmsys::auto_ptr<Options> pOptions( new Options(this->LocalGenerator, Options::Compiler, - cmVS10CLFlagTable)); + cmVSGetCLFlagTable(this->LocalGenerator))); Options& clOptions = *pOptions; std::string flags; - // collect up flags for + // collect up flags for if(this->Target->GetType() < cmTarget::UTILITY) { const char* linkLanguage = @@ -1197,20 +1197,16 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( flags += " "; flags += targetFlags; } - std::string configUpper = cmSystemTools::UpperCase(configName); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += configUpper; - // Get preprocessor definitions for this directory. std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags(); clOptions.FixExceptionHandlingDefault(); + clOptions.AddFlag("PrecompiledHeader", "NotUsing"); clOptions.Parse(flags.c_str()); clOptions.Parse(defineFlags.c_str()); - clOptions.AddDefines - (this->Makefile->GetProperty("COMPILE_DEFINITIONS")); - clOptions.AddDefines(this->Target->GetProperty("COMPILE_DEFINITIONS")); - clOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str())); - clOptions.AddDefines(this->Target->GetProperty(defPropName.c_str())); + clOptions.AddDefines( + this->GeneratorTarget->GetCompileDefinitions().c_str()); + clOptions.AddDefines(this->GeneratorTarget->GetCompileDefinitions( + configName.c_str()).c_str()); clOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); @@ -1247,17 +1243,16 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( "</DebugInformationFormat>\n", 3); } - clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", + clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", "\n", "CXX"); this->WriteString("<AssemblerListingLocation>", 3); - *this->BuildFileStream << configName + *this->BuildFileStream << configName << "</AssemblerListingLocation>\n"; this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { - // TODO: PDB for object library? this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + *this->BuildFileStream << this->Target->GetPDBDirectory(configName.c_str()) << "/" << this->Target->GetPDBName(configName.c_str()) << "</ProgramDataBaseFileName>\n"; @@ -1277,7 +1272,7 @@ OutputIncludes(std::vector<std::string> const & includes) this->WriteString("%(AdditionalIncludeDirectories)" "</AdditionalIncludeDirectories>\n", 0); } - + void cmVisualStudio10TargetGenerator:: @@ -1311,27 +1306,45 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config) cmVisualStudioGeneratorOptions libOptions(this->LocalGenerator, cmVisualStudioGeneratorOptions::Linker, - cmVS10LibFlagTable, 0, this); + cmVSGetLibFlagTable(this->LocalGenerator), 0, this); libOptions.Parse(libflags?libflags:""); libOptions.Parse(libflagsConfig?libflagsConfig:""); libOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); - libOptions.OutputFlagMap(*this->BuildFileStream, " "); + libOptions.OutputFlagMap(*this->BuildFileStream, " "); this->WriteString("</Lib>\n", 2); } } - -void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& - config) +//---------------------------------------------------------------------------- +bool cmVisualStudio10TargetGenerator::ComputeLinkOptions() { - - // static libraries and things greater than modules do not need - // to set this option - if(this->Target->GetType() == cmTarget::STATIC_LIBRARY - || this->Target->GetType() > cmTarget::MODULE_LIBRARY) - { - return; + if(this->Target->GetType() == cmTarget::EXECUTABLE || + this->Target->GetType() == cmTarget::SHARED_LIBRARY || + this->Target->GetType() == cmTarget::MODULE_LIBRARY) + { + std::vector<std::string> const* configs = + this->GlobalGenerator->GetConfigurations(); + for(std::vector<std::string>::const_iterator i = configs->begin(); + i != configs->end(); ++i) + { + if(!this->ComputeLinkOptions(*i)) + { + return false; + } + } } + return true; +} + +//---------------------------------------------------------------------------- +bool +cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) +{ + cmsys::auto_ptr<Options> pOptions( + new Options(this->LocalGenerator, Options::Linker, + cmVSGetLinkFlagTable(this->LocalGenerator), 0, this)); + Options& linkOptions = *pOptions; + const char* linkLanguage = this->Target->GetLinkerLanguage(config.c_str()); if(!linkLanguage) @@ -1339,12 +1352,11 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& cmSystemTools::Error ("CMake can not determine linker language for target:", this->Name.c_str()); - return; + return false; } - this->WriteString("<Link>\n", 2); std::string CONFIG = cmSystemTools::UpperCase(config); - + const char* linkType = "SHARED"; if(this->Target->GetType() == cmTarget::MODULE_LIBRARY) { @@ -1364,7 +1376,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& flags += " "; flags += stackVal; } - // assume incremental linking std::string linkFlagVarBase = "CMAKE_"; linkFlagVarBase += linkType; linkFlagVarBase += "_LINKER_FLAGS"; @@ -1388,10 +1399,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& flags += " "; flags += flagsConfig; } - cmVisualStudioGeneratorOptions - linkOptions(this->LocalGenerator, - cmVisualStudioGeneratorOptions::Linker, - cmVS10LinkFlagTable, 0, this); if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") ) { flags += " /SUBSYSTEM:WINDOWS"; @@ -1400,12 +1407,10 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& { flags += " /SUBSYSTEM:CONSOLE"; } - cmSystemTools::ReplaceString(flags, "/INCREMENTAL:YES", ""); - cmSystemTools::ReplaceString(flags, "/INCREMENTAL:NO", ""); std::string standardLibsVar = "CMAKE_"; standardLibsVar += linkLanguage; standardLibsVar += "_STANDARD_LIBRARIES"; - std::string + std::string libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); // Remove trailing spaces from libs std::string::size_type pos = libs.size()-1; @@ -1423,13 +1428,13 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& // Replace spaces in libs with ; cmSystemTools::ReplaceString(libs, " ", ";"); cmComputeLinkInformation* pcli = - this->Target->GetLinkInformation(config.c_str()); + this->GeneratorTarget->GetLinkInformation(config.c_str()); if(!pcli) { cmSystemTools::Error ("CMake can not compute cmComputeLinkInformation for target:", this->Name.c_str()); - return; + return false; } // add the libraries for the target to libs string cmComputeLinkInformation& cli = *pcli; @@ -1463,7 +1468,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& else { linkOptions.AddFlag("GenerateDebugInformation", "false"); - } + } std::string targetName; std::string targetNameSO; std::string targetNameFull; @@ -1472,19 +1477,18 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& if(this->Target->GetType() == cmTarget::EXECUTABLE) { this->Target->GetExecutableNames(targetName, targetNameFull, - targetNameImport, targetNamePDB, + targetNameImport, targetNamePDB, config.c_str()); } else { this->Target->GetLibraryNames(targetName, targetNameSO, targetNameFull, - targetNameImport, targetNamePDB, + targetNameImport, targetNamePDB, config.c_str()); } - std::string dir = this->Target->GetDirectory(config.c_str()); - dir += "/"; - std::string pdb = dir; + std::string pdb = this->Target->GetPDBDirectory(config.c_str()); + pdb += "/"; pdb += targetNamePDB; std::string imLib = this->Target->GetDirectory(config.c_str(), true); imLib += "/"; @@ -1499,10 +1503,25 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& this->GeneratorTarget->ModuleDefinitionFile.c_str()); } - linkOptions.RemoveFlag("GenerateManifest"); + this->LinkOptions[config] = pOptions.release(); + return true; +} + +//---------------------------------------------------------------------------- +void +cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config) +{ + if(this->Target->GetType() == cmTarget::STATIC_LIBRARY + || this->Target->GetType() > cmTarget::MODULE_LIBRARY) + { + return; + } + Options& linkOptions = *(this->LinkOptions[config]); + this->WriteString("<Link>\n", 2); + linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); linkOptions.OutputFlagMap(*this->BuildFileStream, " "); - + this->WriteString("</Link>\n", 2); if(!this->GlobalGenerator->NeedLinkLibraryDependencies(*this->Target)) { @@ -1516,7 +1535,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& void cmVisualStudio10TargetGenerator::AddLibraries( cmComputeLinkInformation& cli, std::string& libstring) -{ +{ typedef cmComputeLinkInformation::ItemVector ItemVector; ItemVector libs = cli.GetItems(); const char* sep = ";"; @@ -1564,11 +1583,13 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() std::vector<std::string> *configs = static_cast<cmGlobalVisualStudio7Generator *> (this->GlobalGenerator)->GetConfigurations(); - std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); for(std::vector<std::string>::iterator i = configs->begin(); i != configs->end(); ++i) { + std::vector<std::string> includes; + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", i->c_str()); this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1); *this->BuildFileStream << "\n"; // output cl compile flags <ClCompile></ClCompile> @@ -1582,15 +1603,15 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() this->WriteMidlOptions(*i, includes); // write events this->WriteEvents(*i); - // output link flags <Link></Link> + // output link flags <Link></Link> this->WriteLinkOptions(*i); - // output lib flags <Lib></Lib> + // output lib flags <Lib></Lib> this->WriteLibOptions(*i); this->WriteString("</ItemDefinitionGroup>\n", 1); } } -void +void cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName) { this->WriteEvent("PreLinkEvent", @@ -1618,7 +1639,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( std::string comment; for(std::vector<cmCustomCommand>::iterator i = commands.begin(); i != commands.end(); ++i) - { + { cmCustomCommand& command = *i; comment += pre; comment += lg->ConstructComment(command); @@ -1675,7 +1696,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences() } (*this->BuildFileStream) << path << "\">\n"; this->WriteString("<Project>", 3); - (*this->BuildFileStream) + (*this->BuildFileStream) << this->GlobalGenerator->GetGUID(name.c_str()) << "</Project>\n"; this->WriteString("</ProjectReference>\n", 2); diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 2d5ec2a..55a850a 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -28,20 +28,20 @@ class cmVisualStudioGeneratorOptions; class cmVisualStudio10TargetGenerator { public: - cmVisualStudio10TargetGenerator(cmTarget* target, + cmVisualStudio10TargetGenerator(cmTarget* target, cmGlobalVisualStudio10Generator* gg); ~cmVisualStudio10TargetGenerator(); void Generate(); - // used by cmVisualStudioGeneratorOptions - void WritePlatformConfigTag( + // used by cmVisualStudioGeneratorOptions + void WritePlatformConfigTag( const char* tag, - const char* config, + const char* config, int indentLevel, const char* attribute = 0, const char* end = 0, std::ostream* strm = 0 ); - + private: struct ToolSource { @@ -68,6 +68,8 @@ private: std::vector<std::string> const & includes); void WriteRCOptions(std::string const& config, std::vector<std::string> const & includes); + bool ComputeLinkOptions(); + bool ComputeLinkOptions(std::string const& config); void WriteLinkOptions(std::string const& config); void WriteMidlOptions(std::string const& config, std::vector<std::string> const & includes); @@ -95,6 +97,7 @@ private: typedef cmVisualStudioGeneratorOptions Options; typedef std::map<cmStdString, Options*> OptionsMap; OptionsMap ClOptions; + OptionsMap LinkOptions; std::string PathToVcxproj; cmTarget* Target; cmGeneratorTarget* GeneratorTarget; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 9369af6..1df0d9e 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -342,10 +342,10 @@ cmVisualStudioGeneratorOptions if(!this->FlagString.empty()) { if(this->Version >= cmLocalVisualStudioGenerator::VS10) - { + { fout << prefix; if(this->Configuration.size()) - { + { this->TargetGenerator->WritePlatformConfigTag( "AdditionalOptions", this->Configuration.c_str(), diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h index e111ae4..1bdf27a 100644 --- a/Source/cmWhileCommand.h +++ b/Source/cmWhileCommand.h @@ -25,7 +25,7 @@ public: cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - + std::vector<cmListFileArgument> Args; std::vector<cmListFileFunction> Functions; private: @@ -39,7 +39,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmWhileCommand; } @@ -50,7 +50,7 @@ public: */ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, cmExecutionStatus &); - + /** * This is called when the command is first encountered in * the CMakeLists.txt file. @@ -75,7 +75,7 @@ public: { return "Evaluate a group of commands while a condition is true"; } - + /** * More documentation. */ @@ -93,7 +93,7 @@ public: "is true. The condition is evaluated using the same logic as the " "if command."; } - + cmTypeMacro(cmWhileCommand, cmCommand); }; diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx index f37e0ff..9a536c1 100644 --- a/Source/cmWin32ProcessExecution.cxx +++ b/Source/cmWin32ProcessExecution.cxx @@ -11,7 +11,7 @@ ============================================================================*/ #include "cmWin32ProcessExecution.h" -#include "cmSystemTools.h" +#include "cmSystemTools.h" #include <malloc.h> #include <io.h> @@ -48,26 +48,26 @@ void DisplayErrorMessage() { LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, - NULL + NULL ); // Process any inserts in lpMsgBuf. - // ... + // ... // Display the string. MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); // Free the buffer. LocalFree( lpMsgBuf ); } - -// Code from a Borland web site with the following explaination : + +// Code from a Borland web site with the following explaination : /* In this article, I will explain how to spawn a console application * and redirect its standard input/output using anonymous pipes. An * anonymous pipe is a pipe that goes only in one direction (read @@ -93,74 +93,74 @@ void DisplayErrorMessage() * monitor the read end of the stdout pipe to check for display on our * child process. Every time there is something availabe for reading, * we will display it in our app. Consequently, we check for input in - * our app and send it off to the write end of the stdin pipe. */ + * our app and send it off to the write end of the stdin pipe. */ -inline bool IsWinNT() -//check if we're running NT +inline bool IsWinNT() +//check if we're running NT { OSVERSIONINFO osv; osv.dwOSVersionInfoSize = sizeof(osv); GetVersionEx(&osv); - return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT); + return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT); } -//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- bool cmWin32ProcessExecution::BorlandRunCommand( - const char* command, const char* dir, - std::string& output, int& retVal, bool verbose, int /* timeout */, - bool hideWindows) + const char* command, const char* dir, + std::string& output, int& retVal, bool verbose, int /* timeout */, + bool hideWindows) { //verbose = true; - //std::cerr << std::endl - // << "WindowsRunCommand(" << command << ")" << std::endl + //std::cerr << std::endl + // << "WindowsRunCommand(" << command << ")" << std::endl // << std::flush; const int BUFFER_SIZE = 4096; char buf[BUFFER_SIZE]; - -//i/o buffer + +//i/o buffer STARTUPINFO si; SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; - -//security information for pipes + +//security information for pipes PROCESS_INFORMATION pi; HANDLE newstdin,newstdout,read_stdout,write_stdin; - -//pipe handles - if (IsWinNT()) -//initialize security descriptor (Windows NT) + +//pipe handles + if (IsWinNT()) +//initialize security descriptor (Windows NT) { InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, true, NULL, false); sa.lpSecurityDescriptor = &sd; - + } else sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; - -//allow inheritable handles - if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) -//create stdin pipe + +//allow inheritable handles + if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) +//create stdin pipe { return false; } - if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) -//create stdout pipe + if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) +//create stdout pipe { CloseHandle(newstdin); CloseHandle(write_stdin); return false; - + } GetStartupInfo(&si); - -//set startupinfo for the spawned process + +//set startupinfo for the spawned process /* The dwFlags member tells CreateProcess how to make the * process. STARTF_USESTDHANDLES validates the hStd* * members. STARTF_USESHOWWINDOW validates the wShowWindow - * member. */ - + * member. */ + si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.hStdOutput = newstdout; @@ -170,12 +170,12 @@ bool cmWin32ProcessExecution::BorlandRunCommand( { si.wShowWindow = SW_HIDE; } - + //set the new handles for the child process si.hStdInput = newstdin; char* commandAndArgs = strcpy(new char[strlen(command)+1], command); if (!CreateProcess(NULL,commandAndArgs,NULL,NULL,TRUE, - 0, // CREATE_NEW_CONSOLE, - NULL,dir,&si,&pi)) + 0, // CREATE_NEW_CONSOLE, + NULL,dir,&si,&pi)) { std::cerr << "CreateProcess failed " << commandAndArgs << std::endl; CloseHandle(newstdin); @@ -184,37 +184,37 @@ bool cmWin32ProcessExecution::BorlandRunCommand( CloseHandle(write_stdin); delete [] commandAndArgs; return false; - + } delete [] commandAndArgs; unsigned long exit=0; - -//process exit code unsigned + +//process exit code unsigned unsigned long bread; - -//bytes read unsigned + +//bytes read unsigned unsigned long avail; - -//bytes available + +//bytes available memset(buf, 0, sizeof(buf)); - for(;;) -//main program loop + for(;;) +//main program loop { Sleep(10); -//check to see if there is any data to read from stdout +//check to see if there is any data to read from stdout //std::cout << "Peek for data..." << std::endl; PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL); - if (bread != 0) + if (bread != 0) { memset(buf, 0, sizeof(buf)); - if (avail > 1023) + if (avail > 1023) { - while (bread >= 1023) + while (bread >= 1023) { //std::cout << "Read data..." << std::endl; ReadFile(read_stdout,buf,1023,&bread,NULL); - - //read the stdout pipe + + //read the stdout pipe memset(buf, 0, sizeof(buf)); output += buf; if (verbose) @@ -223,39 +223,39 @@ bool cmWin32ProcessExecution::BorlandRunCommand( } } } - else + else { ReadFile(read_stdout,buf,1023,&bread,NULL); output += buf; - if(verbose) + if(verbose) { cmSystemTools::Stdout(buf); } - + } - + } - + //std::cout << "Check for process..." << std::endl; GetExitCodeProcess(pi.hProcess,&exit); - -//while the process is running + +//while the process is running if (exit != STILL_ACTIVE) break; - + } WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess,&exit); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(newstdin); - -//clean stuff up + +//clean stuff up CloseHandle(newstdout); CloseHandle(read_stdout); CloseHandle(write_stdin); retVal = exit; return true; - + } bool cmWin32ProcessExecution::StartProcess( @@ -279,7 +279,7 @@ bool cmWin32ProcessExecution::Wait(int timeout) static void *_PyPopenProcs = NULL; static BOOL RealPopenCreateProcess(const char *cmdstring, - const char *path, + const char *path, const char *szConsoleSpawn, HANDLE hStdin, HANDLE hStdout, @@ -314,7 +314,7 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, ++comshell; if (GetVersion() < 0x80000000 && - STRICMP(comshell, "command.com") != 0) + STRICMP(comshell, "command.com") != 0) { /* NT/2000 and not using command.com. */ x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1; @@ -323,7 +323,7 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, //sprintf(s2, "%s%s%s", s1, s3, cmdstring); sprintf(s2, "%s", cmdstring); } - else + else { /* * Oh gag, we're on Win9x or using COMMAND.COM. Use @@ -337,22 +337,22 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, x = i+1; modulepath[x] = '\0'; /* Create the full-name to w9xpopen, so we can test it exists */ - strncat(modulepath, - szConsoleSpawn, + strncat(modulepath, + szConsoleSpawn, (sizeof(modulepath)/sizeof(modulepath[0])) -strlen(modulepath)); - if (stat(modulepath, &statinfo) != 0) + if (stat(modulepath, &statinfo) != 0) { - /* Eeek - file-not-found - possibly an embedding - situation - see if we can locate it in sys.prefix + /* Eeek - file-not-found - possibly an embedding + situation - see if we can locate it in sys.prefix */ - strncpy(modulepath, - ".", + strncpy(modulepath, + ".", sizeof(modulepath)/sizeof(modulepath[0])); if (modulepath[strlen(modulepath)-1] != '\\') strcat(modulepath, "\\"); - strncat(modulepath, - szConsoleSpawn, + strncat(modulepath, + szConsoleSpawn, (sizeof(modulepath)/sizeof(modulepath[0])) -strlen(modulepath)); /* No where else to look - raise an easily identifiable @@ -361,20 +361,20 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, unaware this shim EXE is used, and it will confuse them. (well, it confused me for a while ;-) */ - if (stat(modulepath, &statinfo) != 0) + if (stat(modulepath, &statinfo) != 0) { - std::cout + std::cout << "Can not locate '" << modulepath << "' which is needed " "for popen to work with your shell " - "or platform." << std::endl; + "or platform." << std::endl; free(s1); free(s2); return FALSE; } } x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 + - (int)strlen(modulepath) + + (int)strlen(modulepath) + (int)strlen(szConsoleSpawn) + 1; if(s2) { @@ -399,22 +399,22 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, /* Could be an else here to try cmd.exe / command.com in the path Now we'll just error out.. */ - else + else { std::cout << "Cannot locate a COMSPEC environment variable to " - << "use as the shell" << std::endl; + << "use as the shell" << std::endl; free(s2); free(s1); return FALSE; } - + ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; siStartInfo.hStdInput = hStdin; siStartInfo.hStdOutput = hStdout; siStartInfo.hStdError = hStderr; - siStartInfo.wShowWindow = SW_SHOWDEFAULT; + siStartInfo.wShowWindow = SW_SHOWDEFAULT; if(hideWindows) { siStartInfo.wShowWindow = SW_HIDE; @@ -430,7 +430,7 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, NULL, path, &siStartInfo, - &piProcInfo) ) + &piProcInfo) ) { /* Close the handles now so anyone waiting is woken. */ CloseHandle(piProcInfo.hThread); @@ -477,9 +477,9 @@ static BOOL RealPopenCreateProcess(const char *cmdstring, /* The following code is based off of KB: Q190351 */ -bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, +bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, const char* path, - int mode, + int mode, int n) { HANDLE hProcess; @@ -496,11 +496,11 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, this->hChildStdinWrDup = 0; this->hChildStdoutRdDup = 0; this->hChildStderrRdDup = 0; - + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; - + fd1 = 0; fd2 = 0; fd3 = 0; @@ -510,7 +510,7 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, this->Output += "CreatePipeError\n"; return false; } - + /* Create new output read handle and the input write handle. Set * the inheritance properties to FALSE. Otherwise, the child inherits * the these handles; resulting in non-closeable handles to the pipes @@ -549,7 +549,7 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, that we're using. */ CloseHandle(hChildStdoutRd); - if (n != POPEN_4) + if (n != POPEN_4) { if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0)) { @@ -570,11 +570,11 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, CloseHandle(hChildStderrRd); } - - switch (n) + + switch (n) { case POPEN_1: - switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) + switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) { case _O_WRONLY | _O_TEXT: /* Case for writing to child Stdin in text mode. */ @@ -606,18 +606,18 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, break; } break; - + case POPEN_2: - case POPEN_4: - //if ( 1 ) + case POPEN_4: + //if ( 1 ) { fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode); fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode); break; } - + case POPEN_3: - //if ( 1) + //if ( 1) { fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode); fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode); @@ -626,7 +626,7 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, } } - if (n == POPEN_4) + if (n == POPEN_4) { if (!RealPopenCreateProcess(cmdstring, path, @@ -652,7 +652,7 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, return 0; } } - else + else { if (!RealPopenCreateProcess(cmdstring, path, @@ -852,15 +852,15 @@ bool cmWin32ProcessExecution::PrivateClose(int /* timeout */) break; } } - } + } + - if (WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED && - GetExitCodeProcess(hProcess, &exit_code)) + GetExitCodeProcess(hProcess, &exit_code)) { result = exit_code; - } - else + } + else { /* Indicate failure - this will cause the file object * to raise an I/O error and translate the last Win32 @@ -868,7 +868,7 @@ bool cmWin32ProcessExecution::PrivateClose(int /* timeout */) * last errors that overlap the normal errno table, * but that's a consistent problem with the file object. */ - if (result != EOF) + if (result != EOF) { /* If the error wasn't from the fclose(), then * set errno for the file object error handling. @@ -897,7 +897,7 @@ int cmWin32ProcessExecution::Windows9xHack(const char* command) PROCESS_INFORMATION pi; DWORD exit_code=0; - if (!command) + if (!command) { cmSystemTools::Error("Windows9xHack: Command not specified"); return 1; @@ -911,7 +911,7 @@ int cmWin32ProcessExecution::Windows9xHack(const char* command) si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - + char * app = 0; char* cmd = new char[ strlen(command) + 1 ]; strcpy(cmd, command); @@ -925,9 +925,9 @@ int cmWin32ProcessExecution::Windows9xHack(const char* command) ); delete [] cmd; - if (bRet) + if (bRet) { - if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) + if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) { GetExitCodeProcess(pi.hProcess, &exit_code); } diff --git a/Source/cmWin32ProcessExecution.h b/Source/cmWin32ProcessExecution.h index def69a8..98b6bda 100644 --- a/Source/cmWin32ProcessExecution.h +++ b/Source/cmWin32ProcessExecution.h @@ -47,12 +47,12 @@ public: ~cmWin32ProcessExecution(); ///! If true windows will be created hidden. void SetHideWindows(bool v) { this->HideWindows = v; } - + /** * Initialize the process execution datastructure. Do not call while * running the process. */ - void Initialize() + void Initialize() { this->ProcessHandle = 0; this->ExitValue = -1; @@ -65,7 +65,7 @@ public: this->pStdOut = -1; this->pStdErr = -1; } - + /** * Start the process in the directory path. Make sure that the * executable is either in the path or specify the full path. The @@ -129,10 +129,10 @@ public: * process. Every time there is something availabe for reading, we * will display it in our app. Consequently, we check for input in * our app and send it off to the write end of the stdin pipe. - */ - static bool BorlandRunCommand(const char* command, - const char* dir, - std::string& output, int& retVal, + */ + static bool BorlandRunCommand(const char* command, + const char* dir, + std::string& output, int& retVal, bool verbose, int timeout, bool hideWindows); @@ -151,8 +151,8 @@ private: HANDLE hChildStdinWrDup; HANDLE hChildStdoutRdDup; HANDLE hChildStderrRdDup; - - + + int pStdIn; int pStdOut; int pStdErr; diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index b2acb2b..3642c6f 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -71,7 +71,7 @@ bool cmWriteFileCommand } // If GetPermissions fails, pretend like it is ok. File open will fail if // the file is not writable - std::ofstream file(fileName.c_str(), + std::ofstream file(fileName.c_str(), overwrite?std::ios::out : std::ios::app); if ( !file ) { diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h index 8808d32..771ef5a 100644 --- a/Source/cmWriteFileCommand.h +++ b/Source/cmWriteFileCommand.h @@ -24,7 +24,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmWriteFileCommand; } @@ -53,7 +53,7 @@ public: { return "Deprecated. Use the file(WRITE ) command instead."; } - + /** * More documentation. */ @@ -71,7 +71,7 @@ public: "lead to an infinite loop. Use configure_file if you want to generate " "input files to CMake."; } - + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() const { diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx index c679cd8..855e1ad 100644 --- a/Source/cmXCode21Object.cxx +++ b/Source/cmXCode21Object.cxx @@ -79,20 +79,20 @@ void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v, cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXBuildStyle); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXContainerItemProxy); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXFileReference); - cmXCode21Object::PrintList(v, out, + cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXFrameworksBuildPhase); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXGroup); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXHeadersBuildPhase); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXNativeTarget); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXProject); - cmXCode21Object::PrintList(v, out, + cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXShellScriptBuildPhase); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXResourcesBuildPhase); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXSourcesBuildPhase); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXCopyFilesBuildPhase); - cmXCode21Object::PrintList(v, out, + cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXApplicationReference); - cmXCode21Object::PrintList(v, out, + cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXExecutableFileReference); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXLibraryReference); cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXToolTarget); diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx index 30ade96..de150ee 100644 --- a/Source/cmXCodeObject.cxx +++ b/Source/cmXCodeObject.cxx @@ -16,13 +16,13 @@ //---------------------------------------------------------------------------- const char* cmXCodeObject::PBXTypeNames[] = { - "PBXGroup", "PBXBuildStyle", "PBXProject", "PBXHeadersBuildPhase", + "PBXGroup", "PBXBuildStyle", "PBXProject", "PBXHeadersBuildPhase", "PBXSourcesBuildPhase", "PBXFrameworksBuildPhase", "PBXNativeTarget", - "PBXFileReference", "PBXBuildFile", "PBXContainerItemProxy", - "PBXTargetDependency", "PBXShellScriptBuildPhase", + "PBXFileReference", "PBXBuildFile", "PBXContainerItemProxy", + "PBXTargetDependency", "PBXShellScriptBuildPhase", "PBXResourcesBuildPhase", "PBXApplicationReference", "PBXExecutableFileReference", "PBXLibraryReference", "PBXToolTarget", - "PBXLibraryTarget", "PBXAggregateTarget", "XCBuildConfiguration", + "PBXLibraryTarget", "PBXAggregateTarget", "XCBuildConfiguration", "XCConfigurationList", "PBXCopyFilesBuildPhase", "None" @@ -92,7 +92,7 @@ void cmXCodeObject::Print(std::ostream& out) { std::string separator = "\n"; int indentFactor = 1; - if(this->Version > 15 + if(this->Version > 15 && (this->IsA == PBXFileReference || this->IsA == PBXBuildFile)) { separator = " "; @@ -112,12 +112,12 @@ void cmXCodeObject::Print(std::ostream& out) std::map<cmStdString, cmXCodeObject*>::iterator i; cmXCodeObject::Indent(3*indentFactor, out); out << "isa = " << PBXTypeNames[this->IsA] << ";" << separator; - for(i = this->ObjectAttributes.begin(); + for(i = this->ObjectAttributes.begin(); i != this->ObjectAttributes.end(); ++i) - { + { cmXCodeObject* object = i->second; if(i->first != "isa") - { + { cmXCodeObject::Indent(3*indentFactor, out); } else @@ -133,7 +133,7 @@ void cmXCodeObject::Print(std::ostream& out) out << i->second->List[k]->Id << " "; i->second->List[k]->PrintComment(out); out << "," << separator; - } + } cmXCodeObject::Indent(3*indentFactor, out); out << ");" << separator; } @@ -141,7 +141,7 @@ void cmXCodeObject::Print(std::ostream& out) { std::map<cmStdString, cmXCodeObject*>::iterator j; out << i->first << " = {" << separator; - for(j = object->ObjectAttributes.begin(); j != + for(j = object->ObjectAttributes.begin(); j != object->ObjectAttributes.end(); ++j) { cmXCodeObject::Indent(4 *indentFactor, out); @@ -209,11 +209,11 @@ void cmXCodeObject::Print(std::ostream& out) cmXCodeObject::Indent(2*indentFactor, out); out << "};\n"; } - + //---------------------------------------------------------------------------- void cmXCodeObject::PrintList(std::vector<cmXCodeObject*> const& objs, std::ostream& out) -{ +{ cmXCodeObject::Indent(1, out); out << "objects = {\n"; for(unsigned int i = 0; i < objs.size(); ++i) diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index 2fb96f3..bb2d5b2 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -19,13 +19,13 @@ class cmXCodeObject { public: enum Type { OBJECT_LIST, STRING, ATTRIBUTE_GROUP, OBJECT_REF, OBJECT }; - enum PBXType { PBXGroup, PBXBuildStyle, PBXProject, PBXHeadersBuildPhase, - PBXSourcesBuildPhase, PBXFrameworksBuildPhase, - PBXNativeTarget, PBXFileReference, PBXBuildFile, + enum PBXType { PBXGroup, PBXBuildStyle, PBXProject, PBXHeadersBuildPhase, + PBXSourcesBuildPhase, PBXFrameworksBuildPhase, + PBXNativeTarget, PBXFileReference, PBXBuildFile, PBXContainerItemProxy, PBXTargetDependency, PBXShellScriptBuildPhase, PBXResourcesBuildPhase, - PBXApplicationReference, PBXExecutableFileReference, - PBXLibraryReference, PBXToolTarget, PBXLibraryTarget, + PBXApplicationReference, PBXExecutableFileReference, + PBXLibraryReference, PBXToolTarget, PBXLibraryTarget, PBXAggregateTarget,XCBuildConfiguration,XCConfigurationList, PBXCopyFilesBuildPhase, None @@ -38,16 +38,16 @@ public: PBXType GetIsA() { return this->IsA;} void SetString(const char* s); - const char* GetString() + const char* GetString() { return this->String.c_str(); } - + void AddAttribute(const char* name, cmXCodeObject* value) { this->ObjectAttributes[name] = value; } - + void SetObject(cmXCodeObject* value) { this->Object = value; @@ -60,14 +60,14 @@ public: { this->List.push_back(value); } - bool HasObject(cmXCodeObject* o) + bool HasObject(cmXCodeObject* o) { - return !(std::find(this->List.begin(), this->List.end(), o) + return !(std::find(this->List.begin(), this->List.end(), o) == this->List.end()); } void AddUniqueObject(cmXCodeObject* value) { - if(std::find(this->List.begin(), this->List.end(), value) + if(std::find(this->List.begin(), this->List.end(), value) == this->List.end()) { this->List.push_back(value); @@ -77,7 +77,7 @@ public: void Print(std::ostream& out); virtual void PrintComment(std::ostream&) {}; - static void PrintList(std::vector<cmXCodeObject*> const&, + static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out); const char* GetId() { @@ -119,7 +119,7 @@ public: } return 0; } - + cmXCodeObject* GetPBXTargetDependency() { return this->PBXTargetDependencyValue; @@ -129,7 +129,7 @@ public: this->PBXTargetDependencyValue = d; } void CopyAttributes(cmXCodeObject* ); - + void AddDependLibrary(const char* configName, const char* l) { diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx index 46a1ca4..882fc17 100644 --- a/Source/cmXMLParser.cxx +++ b/Source/cmXMLParser.cxx @@ -34,7 +34,7 @@ cmXMLParser::~cmXMLParser() int cmXMLParser::Parse(const char* string) { return (int)this->InitializeParser() && - this->ParseChunk(string, strlen(string)) && + this->ParseChunk(string, strlen(string)) && this->CleanupParser(); } @@ -79,7 +79,7 @@ int cmXMLParser::InitializeParser() } //---------------------------------------------------------------------------- -int cmXMLParser::ParseChunk(const char* inputString, +int cmXMLParser::ParseChunk(const char* inputString, std::string::size_type length) { if ( !this->Parser ) @@ -116,11 +116,11 @@ int cmXMLParser::CleanupParser() result = 0; } } - + // Clean up the parser. XML_ParserFree(static_cast<XML_Parser>(this->Parser)); this->Parser = 0; - + return result; } @@ -128,7 +128,7 @@ int cmXMLParser::CleanupParser() int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count) { // Pass the buffer to the expat XML parser. - if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer, + if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer, static_cast<int>(count), 0)) { this->ReportXmlParseError(); diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h index c72be57..d916075 100644 --- a/Source/cmXMLParser.h +++ b/Source/cmXMLParser.h @@ -18,7 +18,7 @@ extern "C" { void cmXMLParserStartElement(void*, const char*, const char**); void cmXMLParserEndElement(void*, const char*); - void cmXMLParserCharacterDataHandler(void*, const char*, int); + void cmXMLParserCharacterDataHandler(void*, const char*, int); } /** \class cmXMLParser @@ -37,7 +37,7 @@ public: //! Parse given XML file virtual int ParseFile(const char* file); - + /** * When parsing fragments of XML or streaming XML, use the following * three methods. InitializeParser method initialize parser but does @@ -47,7 +47,7 @@ public: * them. */ virtual int InitializeParser(); - virtual int ParseChunk(const char* inputString, + virtual int ParseChunk(const char* inputString, std::string::size_type length); virtual int CleanupParser(); @@ -65,7 +65,7 @@ protected: * terminating condition for parsing. Parsing always stops when the end of * file is reached in the stream. */ - + virtual int ParsingComplete(); /** @@ -75,28 +75,28 @@ protected: * Even indices are attribute names, and odd indices are values. */ virtual void StartElement(const char* name, const char** atts); - + //! Called at the end of an element in the XML source opened when //StartElement was called. virtual void EndElement(const char* name); - + //! Called when there is character data to handle. - virtual void CharacterDataHandler(const char* data, int length); + virtual void CharacterDataHandler(const char* data, int length); //! Called by Parse to report an XML syntax error. - virtual void ReportXmlParseError(); + virtual void ReportXmlParseError(); /** Called by ReportXmlParseError with basic error info. */ virtual void ReportError(int line, int column, const char* msg); //! Utility for convenience of subclasses. Wraps isspace C library // routine. - static int IsSpace(char c); - + static int IsSpace(char c); + //! Send the given buffer to the XML parser. - virtual int ParseBuffer(const char* buffer, + virtual int ParseBuffer(const char* buffer, std::string::size_type length); - + //! Send the given c-style string to the XML parser. int ParseBuffer(const char* buffer); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2ffff42..0123427 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -84,10 +84,8 @@ #else #endif #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmGlobalNinjaGenerator.h" -#ifdef CMAKE_USE_NINJA -# include "cmGlobalNinjaGenerator.h" -#endif #if defined(CMAKE_HAVE_VS_GENERATORS) #include "cmCallVisualStudioMacro.h" @@ -630,9 +628,14 @@ bool cmake::FindPackage(const std::vector<std::string>& args) std::string linkLibs; + std::string frameworkPath; + std::string linkPath; std::string flags; std::string linkFlags; - lg->GetTargetFlags(linkLibs, flags, linkFlags, *tgt); + cmGeneratorTarget gtgt(tgt); + lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags, + >gt); + linkLibs = frameworkPath + linkPath + linkLibs; printf("%s\n", linkLibs.c_str() ); @@ -1045,7 +1048,7 @@ int cmake::AddCMakePaths() { cMakeRoot = cMakeRoot.substr(0, slashPos); } - // is there no Modules direcory there? + // is there no Modules directory there? modules = cMakeRoot + "/Modules/CMake.cmake"; } @@ -1074,7 +1077,7 @@ int cmake::AddCMakePaths() { // next try exe cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str()); - // is there no Modules direcory there? + // is there no Modules directory there? modules = cMakeRoot + "/Modules/CMake.cmake"; } if (!cmSystemTools::FileExists(modules.c_str())) @@ -1423,7 +1426,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) int retval = 0; int timeout = 0; if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval, - directory.c_str(), cmSystemTools::OUTPUT_MERGE, timeout) ) + directory.c_str(), cmSystemTools::OUTPUT_NORMAL, timeout) ) { return retval; } @@ -1699,8 +1702,8 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) else if (args[1] == "cmake_automoc") { cmQtAutomoc automoc; - automoc.Run(args[2].c_str()); - return 0; + bool automocSuccess = automoc.Run(args[2].c_str()); + return automocSuccess ? 0 : 1; } #endif @@ -2186,6 +2189,7 @@ int cmake::ActualConfigure() std::vector<std::string> vsVerions; vsVerions.push_back("VisualStudio\\"); vsVerions.push_back("VCExpress\\"); + vsVerions.push_back("WDExpress\\"); struct VSRegistryEntryName { const char* MSVersion; @@ -2198,10 +2202,11 @@ int cmake::ActualConfigure() {"8.0", "Visual Studio 8 2005"}, {"9.0", "Visual Studio 9 2008"}, {"10.0", "Visual Studio 10"}, + {"11.0", "Visual Studio 11"}, {0, 0}}; - for(size_t b=0; b < vsVerions.size() && installedCompiler.empty(); b++) + for(int i=0; version[i].MSVersion != 0; i++) { - for(int i =0; version[i].MSVersion != 0; i++) + for(size_t b=0; b < vsVerions.size(); b++) { std::string reg = vsregBase + vsVerions[b] + version[i].MSVersion; reg += ";InstallDir]"; @@ -2210,6 +2215,7 @@ int cmake::ActualConfigure() if (!(reg == "/registry")) { installedCompiler = version[i].GeneratorName; + break; } } } @@ -2328,6 +2334,17 @@ int cmake::ActualConfigure() this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR"); this->CacheManager->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR"); } + + cmMakefile* mf=this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile(); + if (mf->IsOn("CTEST_USE_LAUNCHERS") + && !this->GetProperty("RULE_LAUNCH_COMPILE", cmProperty::GLOBAL)) + { + cmSystemTools::Error("CTEST_USE_LAUNCHERS is enabled, but the " + "RULE_LAUNCH_COMPILE global property is not defined.\n" + "Did you forget to include(CTest) in the toplevel " + "CMakeLists.txt ?"); + } + // only save the cache if there were no fatal errors if ( this->GetWorkingMode() == NORMAL_MODE ) { @@ -2440,9 +2457,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) this->PreLoadCMakeFiles(); - std::string systemFile = this->GetHomeOutputDirectory(); - systemFile += "/CMakeSystem.cmake"; - if ( noconfigure ) { return 0; @@ -2600,10 +2614,8 @@ void cmake::AddDefaultGenerators() #endif this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] = &cmGlobalUnixMakefileGenerator3::New; -#ifdef CMAKE_USE_NINJA this->Generators[cmGlobalNinjaGenerator::GetActualName()] = &cmGlobalNinjaGenerator::New; -#endif #ifdef CMAKE_USE_XCODE this->Generators[cmGlobalXCodeGenerator::GetActualName()] = &cmGlobalXCodeGenerator::New; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index c3de8ca..11a4267 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -// include these first, otherwise there will be problems on Windows -// with GetCurrentDirectory() being redefined +// include these first, otherwise there will be problems on Windows +// with GetCurrentDirectory() being redefined #ifdef CMAKE_BUILD_WITH_CMAKE #include "cmDynamicLoader.h" #include "cmDocumentation.h" @@ -183,7 +183,7 @@ static const char * cmDocumentationOptions[][3] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML, DocBook and plain text."}, - {"--help-policy cmp [file]", + {"--help-policy cmp [file]", "Print help for a single policy and exit.", "Full documentation specific to the given policy is displayed." "If a file is specified, the documentation is written into and the output " @@ -194,7 +194,7 @@ static const char * cmDocumentationOptions[][3] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML, DocBook and plain text."}, - {"--help-property prop [file]", + {"--help-property prop [file]", "Print help for a single property and exit.", "Full documentation specific to the given property is displayed." "If a file is specified, the documentation is written into and the output " @@ -212,7 +212,7 @@ static const char * cmDocumentationOptions[][3] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML, DocBook and plain text."}, - {"--help-variable var [file]", + {"--help-variable var [file]", "Print help for a single variable and exit.", "Full documentation specific to the given variable is displayed." "If a file is specified, the documentation is written into and the output " @@ -296,13 +296,13 @@ static std::string cmakemainGetStack(void *clientdata) return msg; } -static void cmakemainErrorCallback(const char* m, const char*, bool&, +static void cmakemainErrorCallback(const char* m, const char*, bool&, void *clientdata) { std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush; } -static void cmakemainProgressCallback(const char *m, float prog, +static void cmakemainProgressCallback(const char *m, float prog, void* clientdata) { cmMakefile* mf = cmakemainGetMakefile(clientdata); @@ -348,7 +348,7 @@ int do_cmake(int ac, char** av) if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) { - std::cerr << "Current working directory cannot be established." + std::cerr << "Current working directory cannot be established." << std::endl; nocwd = 1; } @@ -357,13 +357,13 @@ int do_cmake(int ac, char** av) cmDocumentation doc; doc.addCMakeStandardDocSections(); if(doc.CheckOptions(ac, av, "-E") || nocwd) - { + { // Construct and print requested documentation. cmake hcm; hcm.AddCMakePaths(); doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT")); - // the command line args are processed here so that you can do + // the command line args are processed here so that you can do // -DCMAKE_MODULE_PATH=/some/path and have this value accessible here std::vector<std::string> args; for(int i =0; i < ac; ++i) @@ -401,7 +401,7 @@ int do_cmake(int ac, char** av) doc.SetSections(propDocs); cmDocumentationEntry e; - e.Brief = + e.Brief = "variables defined by cmake, that give information about the project, " "and cmake"; doc.PrependSection("Variables that Provide Information",e); @@ -418,7 +418,7 @@ int do_cmake(int ac, char** av) { doc.ClearSections(); doc.SetSection("NOTE", cmDocumentationNOTE); - doc.Print(cmDocumentation::UsageForm, std::cerr); + doc.Print(cmDocumentation::UsageForm, 0, std::cerr); return 1; } return result; @@ -426,13 +426,13 @@ int do_cmake(int ac, char** av) #else if ( nocwd || ac == 1 ) { - std::cout << + std::cout << "Bootstrap CMake should not be used outside CMake build process." << std::endl; return 0; } #endif - + bool wiz = false; bool sysinfo = false; bool command = false; @@ -453,7 +453,7 @@ int do_cmake(int ac, char** av) sysinfo = true; } // if command has already been set, then - // do not eat the -E + // do not eat the -E else if (!command && strcmp(av[i], "-E") == 0) { command = true; @@ -500,7 +500,7 @@ int do_cmake(int ac, char** av) workingMode = cmake::FIND_PACKAGE_MODE; args.push_back(av[i]); } - else + else { args.push_back(av[i]); } @@ -513,15 +513,15 @@ int do_cmake(int ac, char** av) if (wiz) { cmakewizard wizard; - return wizard.RunWizard(args); + return wizard.RunWizard(args); } if (sysinfo) { cmake cm; int ret = cm.GetSystemInformation(args); - return ret; + return ret; } - cmake cm; + cmake cm; cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm); cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm); cm.SetWorkingMode(workingMode); @@ -529,7 +529,7 @@ int do_cmake(int ac, char** av) int res = cm.Run(args, view_only); if ( list_cached || list_all_cached ) { - cmCacheManager::CacheIterator it = + cmCacheManager::CacheIterator it = cm.GetCacheManager()->GetCacheIterator(); std::cout << "-- Cache values" << std::endl; for ( it.Begin(); !it.IsAtEnd(); it.Next() ) @@ -545,8 +545,8 @@ int do_cmake(int ac, char** av) { std::cout << "// " << it.GetProperty("HELPSTRING") << std::endl; } - std::cout << it.GetName() << ":" << - cmCacheManager::TypeToString(it.GetType()) + std::cout << it.GetName() << ":" << + cmCacheManager::TypeToString(it.GetType()) << "=" << it.GetValue() << std::endl; if ( list_help ) { diff --git a/Source/cmakewizard.cxx b/Source/cmakewizard.cxx index cd427cb..749f669 100644 --- a/Source/cmakewizard.cxx +++ b/Source/cmakewizard.cxx @@ -137,7 +137,7 @@ int cmakewizard::RunWizard(std::vector<std::string> const& args) } } else - { + { if(this->ShowAdvanced || !i.GetPropertyAsBool("ADVANCED")) { this->AskUser(key.c_str(), i); diff --git a/Source/cmakewizard.h b/Source/cmakewizard.h index fcb2c7a..0c8dba9 100644 --- a/Source/cmakewizard.h +++ b/Source/cmakewizard.h @@ -18,24 +18,24 @@ class cmakewizard public: cmakewizard(); virtual ~cmakewizard() {} - /** + /** * Prompt the user to see if they want to see advanced entries. */ virtual bool AskAdvanced(); - + /** * Prompt the User for a new value for key, the answer is put in entry. */ virtual void AskUser(const char* key, cmCacheManager::CacheIterator& iter); ///! Show a message to wait for cmake to run. virtual void ShowMessage(const char*); - - /** - * Run cmake in wizard mode. This will coninue to ask the user questions + + /** + * Run cmake in wizard mode. This will coninue to ask the user questions * until there are no more entries in the cache. */ int RunWizard(std::vector<std::string>const& args); - + private: bool ShowAdvanced; }; diff --git a/Source/cmakexbuild.cxx b/Source/cmakexbuild.cxx index 8eaae47..9aaeeaa 100644 --- a/Source/cmakexbuild.cxx +++ b/Source/cmakexbuild.cxx @@ -33,7 +33,7 @@ int RunXCode(std::vector<const char*>& argv, bool& hitbug) int pipe = cmSystemTools::WaitForLine(cp, line, 100.0, out, err); while(pipe != cmsysProcess_Pipe_None) { - if(line.find("/bin/sh: bad interpreter: Text file busy") + if(line.find("/bin/sh: bad interpreter: Text file busy") != line.npos) { hitbug = true; @@ -69,7 +69,7 @@ int RunXCode(std::vector<const char*>& argv, bool& hitbug) } int main(int ac, char*av[]) -{ +{ std::vector<const char*> argv; argv.push_back("xcodebuild"); for(int i =1; i < ac; i++) diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx new file mode 100644 index 0000000..34350bf --- /dev/null +++ b/Source/cmcldeps.cxx @@ -0,0 +1,287 @@ +// Copyright 2011 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Wrapper around cl that adds /showIncludes to command line, and uses that to +// generate .d files that match the style from gcc -MD. +// +// /showIncludes is equivalent to -MD, not -MMD, that is, system headers are +// included. + + +#include <windows.h> +#include <sstream> +#include <cmSystemTools.h> + +// We don't want any wildcard expansion. +// See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx +void _setargv() {} + +static void Fatal(const char* msg, ...) { + va_list ap; + fprintf(stderr, "ninja: FATAL: "); + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); + fprintf(stderr, "\n"); + // On Windows, some tools may inject extra threads. + // exit() may block on locks held by those threads, so forcibly exit. + fflush(stderr); + fflush(stdout); + ExitProcess(1); +} + +static void usage(const char* msg) { + Fatal("%s\n\nusage:\n " + "cmcldeps " + "<language C, CXX or RC> " + "<source file path> " + "<output path for *.d file> " + "<output path for *.obj file> " + "<prefix of /showIncludes> " + "<path to cl.exe> " + "<path to tool (cl or rc)> " + "<rest of command ...>\n", msg); +} + +static std::string trimLeadingSpace(const std::string& cmdline) { + int i = 0; + for (; cmdline[i] == ' '; ++i) + ; + return cmdline.substr(i); +} + +static void doEscape(std::string& str, const std::string& search, + const std::string& repl) { + std::string::size_type pos = 0; + while ((pos = str.find(search, pos)) != std::string::npos) { + str.replace(pos, search.size(), repl); + pos += repl.size(); + } +} + +// Strips one argument from the cmdline and returns it. "surrounding quotes" +// are removed from the argument if there were any. +static std::string getArg(std::string& cmdline) { + std::string ret; + bool in_quoted = false; + unsigned int i = 0; + + cmdline = trimLeadingSpace(cmdline); + + for (;; ++i) { + if (i >= cmdline.size()) + usage("Couldn't parse arguments."); + if (!in_quoted && cmdline[i] == ' ') + break; // "a b" "x y" + if (cmdline[i] == '"') + in_quoted = !in_quoted; + } + + ret = cmdline.substr(0, i); + if (ret[0] == '"' && ret[i - 1] == '"') + ret = ret.substr(1, ret.size() - 2); + cmdline = cmdline.substr(i); + return ret; +} + +static void parseCommandLine(LPTSTR wincmdline, + std::string& lang, + std::string& srcfile, + std::string& dfile, + std::string& objfile, + std::string& prefix, + std::string& clpath, + std::string& binpath, + std::string& rest) { + std::string cmdline(wincmdline); + /* self */ getArg(cmdline); + lang = getArg(cmdline); + srcfile = getArg(cmdline); + dfile = getArg(cmdline); + objfile = getArg(cmdline); + prefix = getArg(cmdline); + clpath = getArg(cmdline); + binpath = getArg(cmdline); + rest = trimLeadingSpace(cmdline); +} + +static void outputDepFile(const std::string& dfile, const std::string& objfile, + std::vector<std::string>& incs) { + + if (dfile.empty()) + return; + + // strip duplicates + std::sort(incs.begin(), incs.end()); + incs.erase(std::unique(incs.begin(), incs.end()), incs.end()); + + FILE* out = fopen(dfile.c_str(), "wb"); + + // FIXME should this be fatal or not? delete obj? delete d? + if (!out) + return; + + std::string tmp = objfile; + doEscape(tmp, " ", "\\ "); + fprintf(out, "%s: \\\n", tmp.c_str()); + + std::vector<std::string>::iterator it = incs.begin(); + for (; it != incs.end(); ++it) { + tmp = *it; + doEscape(tmp, "\\", "/"); + doEscape(tmp, " ", "\\ "); + fprintf(out, "%s \\\n", tmp.c_str()); + } + + fprintf(out, "\n"); + fclose(out); +} + + +bool startsWith(const std::string& str, const std::string& what) { + return str.compare(0, what.size(), what) == 0; +} + +bool contains(const std::string& str, const std::string& what) { + return str.find(what) != std::string::npos; +} + +std::string replace(const std::string& str, const std::string& what, + const std::string& replacement) { + size_t pos = str.find(what); + if (pos == std::string::npos) + return str; + std::string replaced = str; + return replaced.replace(pos, what.size(), replacement); +} + + + +static int process( const std::string& srcfilename, + const std::string& dfile, + const std::string& objfile, + const std::string& prefix, + const std::string& cmd, + const std::string& dir = "", + bool quiet = false) +{ + std::string output; + // break up command line into a vector + std::vector<std::string> args; + cmSystemTools::ParseWindowsCommandLine(cmd.c_str(), args); + // convert to correct vector type for RunSingleCommand + std::vector<cmStdString> command; + for(std::vector<std::string>::iterator i = args.begin(); + i != args.end(); ++i) + { + command.push_back(i->c_str()); + } + // run the command + int exit_code = 0; + bool run = cmSystemTools::RunSingleCommand(command, &output, &exit_code, + dir.c_str(), cmSystemTools::OUTPUT_NONE); + + // process the include directives and output everything else + std::stringstream ss(output); + std::string line; + std::vector<std::string> includes; + bool isFirstLine = true; // cl prints always first the source filename + while (std::getline(ss, line)) { + if (startsWith(line, prefix)) { + std::string inc = trimLeadingSpace(line.substr(prefix.size()).c_str()); + if (inc[inc.size() - 1] == '\r') // blech, stupid \r\n + inc = inc.substr(0, inc.size() - 1); + includes.push_back(inc); + } else { + if (!isFirstLine || !startsWith(line, srcfilename)) { + if (!quiet || exit_code != 0) { + fprintf(stdout, "%s\n", line.c_str()); + } + } else { + isFirstLine = false; + } + } + } + + // don't update .d until/unless we succeed compilation + if (run && exit_code == 0) + outputDepFile(dfile, objfile, includes); + + return exit_code; +} + + +int main() { + + // Use the Win32 api instead of argc/argv so we can avoid interpreting the + // rest of command line after the .d and .obj. Custom parsing seemed + // preferable to the ugliness you get into in trying to re-escape quotes for + // subprocesses, so by avoiding argc/argv, the subprocess is called with + // the same command line verbatim. + + std::string lang, srcfile, dfile, objfile, prefix, cl, binpath, rest; + parseCommandLine(GetCommandLine(), lang, srcfile, dfile, objfile, + prefix, cl, binpath, rest); + + // needed to suppress filename output of msvc tools + std::string srcfilename; + std::string::size_type pos = srcfile.rfind("\\"); + if (pos == std::string::npos) { + srcfilename = srcfile; + } else { + srcfilename = srcfile.substr(pos + 1); + } + + std::string nol = " /nologo "; + std::string show = " /showIncludes "; + if (lang == "C" || lang == "CXX") { + return process(srcfilename, dfile, objfile, prefix, + binpath + nol + show + rest); + } else if (lang == "RC") { + // "misuse" cl.exe to get headers from .rc files + + std::string clrest = rest; + // rc: /fo x.dir\x.rc.res -> cl: /out:x.dir\x.rc.res.dep.obj + clrest = replace(clrest, "/fo", "/out:"); + clrest = replace(clrest, objfile, objfile + ".dep.obj "); + + // rc: src\x\x.rc -> cl: /Tc src\x\x.rc + if (srcfile.find(" ") != std::string::npos) + srcfile = "\"" + srcfile + "\""; + clrest = replace(clrest, srcfile, "/Tc " + srcfile); + + cl = "\"" + cl + "\" /P /DRC_INVOKED "; + + // call cl in object dir so the .i is generated there + std::string objdir; + std::string::size_type pos = objfile.rfind("\\"); + if (pos != std::string::npos) { + objdir = objfile.substr(0, pos); + } + + // extract dependencies with cl.exe + int exit_code = process(srcfilename, dfile, objfile, + prefix, cl + nol + show + clrest, objdir, true); + + if (exit_code != 0) + return exit_code; + + // compile rc file with rc.exe + return process(srcfilename, "" , objfile, prefix, binpath + " " + rest); + } + + usage("Invalid language specified."); + return 1; +} diff --git a/Source/cmparseMSBuildXML.py b/Source/cmparseMSBuildXML.py index 4877e59..35b55ca 100755 --- a/Source/cmparseMSBuildXML.py +++ b/Source/cmparseMSBuildXML.py @@ -6,10 +6,13 @@ # "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/cl.xml" # "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/lib.xml" # "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/link.xml" +# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/cl.xml" +# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/lib.xml" +# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/link.xml" # # BoolProperty <Name>true|false</Name> # simple example: -# <BoolProperty ReverseSwitch="Oy-" Name="OmitFramePointers" +# <BoolProperty ReverseSwitch="Oy-" Name="OmitFramePointers" # Category="Optimization" Switch="Oy"> # <BoolProperty.DisplayName> <BoolProperty.Description> # <CLCompile> @@ -67,7 +70,7 @@ # <Optimization>MaxSpeed</Optimization> # example for O1 would be this: # <Optimization>MinSpace</Optimization> -# +# # StringListProperty # <StringListProperty Name="PreprocessorDefinitions" Category="Preprocessor" Switch="D "> # <StringListProperty.DisplayName> @@ -130,7 +133,7 @@ class Property: if document is not None: self.populate(document) pass - + #document = the dom file that's root node is the Property node (ex. if you were parsing a BoolProperty the root node should be something like <BoolProperty Name="RegisterOutput" Category="General" IncludeInCommandLine="false"> #spaces = do not use def populate(self,document, spaces = ""): @@ -148,16 +151,16 @@ class Property: self.argumentProperty = child.getAttribute("Property") self.argumentIsRequired = child.getAttribute("IsRequired") if child.nodeName == self.prefix_type+"Value": - va = Property(self.prefix_type,["Name","Switch"]) + va = Property(self.prefix_type,["Name","DisplayName","Switch"]) va.suffix_type = "Value" va.populate(child) self.values.append(va) self.populate(child,spaces+"----") pass - #toString function + #toString function def __str__(self): - toReturn = self.prefix_type+self.suffix_type+":" + toReturn = self.prefix_type+self.suffix_type+":" for i in self.attributeNames: toReturn += "\n "+i+": "+self.attributes[i] if self.argumentProperty != "": @@ -191,7 +194,7 @@ class MSBuildToCMake: # self.<Name>Properties.append(Property("<Name>",[<List of attributes>],child)) # #Replace <Name> with the name of the new property (ex. if property is StringProperty replace <Name> with String) - #Replace <List of attributes> with a list of attributes in your property's root node + #Replace <List of attributes> with a list of attributes in your property's root node #in the __init__ function add the line self.<Name>Properties = [] # #That is all that is required to add new properties @@ -203,11 +206,11 @@ class MSBuildToCMake: if child.nodeName == "EnumProperty": self.enumProperties.append(Property("Enum",["Name","Category"],child)) if child.nodeName == "StringProperty": - self.stringProperties.append(Property("String",["Name","Subtype","Separator","Category","Visible","IncludeInCommandLine","Switch","ReadOnly"],child)) + self.stringProperties.append(Property("String",["Name","Subtype","Separator","Category","Visible","IncludeInCommandLine","Switch","DisplayName","ReadOnly"],child)) if child.nodeName == "StringListProperty": - self.stringListProperties.append(Property("StringList",["Name","Category","Switch","Subtype"],child)) + self.stringListProperties.append(Property("StringList",["Name","Category","Switch","DisplayName","Subtype"],child)) if child.nodeName == "BoolProperty": - self.boolProperties.append(Property("Bool",["ReverseSwitch","Name","Category","Switch","SwitchPrefix","IncludeInCommandLine"],child)) + self.boolProperties.append(Property("Bool",["ReverseSwitch","Name","Category","Switch","DisplayName","SwitchPrefix","IncludeInCommandLine"],child)) if child.nodeName == "IntProperty": self.intProperties.append(Property("Int",["Name","Category","Visible"],child)) self.populate(child,spaces+"----") @@ -226,17 +229,17 @@ class MSBuildToCMake: for j in i.values: #hardcore Brad King's manual fixes for cmVS10CLFlagTable.h if i.attributes["Name"] == "PrecompiledHeader" and j.attributes["Switch"] != "": - toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.DisplayName+"\", \""+j.attributes["Name"]+"\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n" + toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.attributes["DisplayName"]+"\", \""+j.attributes["Name"]+"\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n" else: #default (normal, non-hardcoded) case - toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.DisplayName+"\", \""+j.attributes["Name"]+"\", 0},\n" + toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.attributes["DisplayName"]+"\", \""+j.attributes["Name"]+"\", 0},\n" toReturn += "\n" if lastProp != {}: for j in lastProp.values: - toReturn+=" {\""+lastProp.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.DisplayName+"\", \""+j.attributes["Name"]+"\", 0},\n" + toReturn+=" {\""+lastProp.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.attributes["DisplayName"]+"\", \""+j.attributes["Name"]+"\", 0},\n" toReturn += "\n" - + toReturn += "\n //Bool Properties\n" for i in self.boolProperties: if i.argumentProperty == "": @@ -250,17 +253,17 @@ class MSBuildToCMake: if i.argumentProperty != "": if i.attributes["ReverseSwitch"] != "": toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \"\", \"false\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n" - toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \""+i.DisplayName+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n" + toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \""+i.attributes["DisplayName"]+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n" if i.attributes["Switch"] != "": toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\", \"\", \"true\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n" - toReturn += " {\""+i.argumentProperty+"\", \""+i.attributes["Switch"]+"\", \""+i.DisplayName+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n" - + toReturn += " {\""+i.argumentProperty+"\", \""+i.attributes["Switch"]+"\", \""+i.attributes["DisplayName"]+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n" + toReturn += "\n //String List Properties\n" for i in self.stringListProperties: if i.attributes["Switch"] == "": toReturn += " // Skip [" + i.attributes["Name"] + "] - no command line Switch.\n"; else: - toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\",\n \""+i.DisplayName+"\",\n \"\", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},\n" + toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\",\n \""+i.attributes["DisplayName"]+"\",\n \"\", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},\n" toReturn += "\n //String Properties\n" for i in self.stringProperties: @@ -276,7 +279,7 @@ class MSBuildToCMake: else: toReturn += " // Skip [" + i.attributes["Name"] + "] - no command line Switch.\n"; else: - toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+i.attributes["Separator"]+"\",\n \""+i.DisplayName+"\",\n \"\", cmVS7FlagTable::UserValue},\n" + toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+i.attributes["Separator"]+"\",\n \""+i.attributes["DisplayName"]+"\",\n \"\", cmVS7FlagTable::UserValue},\n" toReturn += " {0,0,0,0,0}\n};" return toReturn @@ -289,7 +292,7 @@ class MSBuildToCMake: for p in allList: for i in p: toReturn += "==================================================\n"+str(i).replace("\n","\n ")+"\n==================================================\n" - + return toReturn ########################################################################################### @@ -305,8 +308,8 @@ def main(argv): for i in range(0,len(argv)): if argv[i] == "-x": xml_file = argv[i+1] - if argv[i] == "-h": - print help + if argv[i] == "-h": + print help sys.exit(0) pass if xml_file == None: diff --git a/Source/cmw9xcom.cxx b/Source/cmw9xcom.cxx index 4ba2749..e6014b3 100644 --- a/Source/cmw9xcom.cxx +++ b/Source/cmw9xcom.cxx @@ -22,7 +22,7 @@ int main (int argc, char *argv[]) return 1; } std::string arg = argv[1]; - if ( (arg.find_first_of(" ") != arg.npos) && + if ( (arg.find_first_of(" ") != arg.npos) && (arg.find_first_of("\"") == arg.npos) ) { arg = "\"" + arg + "\""; @@ -32,7 +32,7 @@ int main (int argc, char *argv[]) for ( cc = 2; cc < argc; cc ++ ) { std::string arg = argv[cc]; - if ( (arg.find_first_of(" ") != arg.npos) && + if ( (arg.find_first_of(" ") != arg.npos) && (arg.find_first_of("\"") == arg.npos) ) { arg = "\"" + arg + "\""; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index d41627e..d650777 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -103,6 +103,12 @@ static const char * cmDocumentationOptions[][3] = "a dashboard test. All tests are <Mode><Test>, where Mode can be " "Experimental, Nightly, and Continuous, and Test can be Start, Update, " "Configure, Build, Test, Coverage, and Submit."}, + {"-D <var>:<type>=<value>", "Define a variable for script mode", + "Pass in variable values on the command line. Use in " + "conjunction with -S to pass variable values to a dashboard script. " + "Parsing -D arguments as variable values is only attempted if " + "the value following -D does not match any of the known dashboard " + "types."}, {"-M <model>, --test-model <model>", "Sets the model for a dashboard", "This option tells ctest to act as a Dart client " "where the TestModel can be Experimental, " |