diff options
author | Brad King <brad.king@kitware.com> | 2011-01-27 19:39:55 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2011-01-27 19:39:55 (GMT) |
commit | dd2f81491e6e17681dd18882a8ccfa01fa32a3f7 (patch) | |
tree | 6b782de32aeb462333d70747f269b1725e723e00 /Source | |
parent | 949d32c3067830a1376950fc78dbcde39bc378a8 (diff) | |
parent | 7679f9fab099e729b61320927a9e0b8d03546f7f (diff) | |
download | CMake-dd2f81491e6e17681dd18882a8ccfa01fa32a3f7.zip CMake-dd2f81491e6e17681dd18882a8ccfa01fa32a3f7.tar.gz CMake-dd2f81491e6e17681dd18882a8ccfa01fa32a3f7.tar.bz2 |
Merge branch 'dev/add_test-working-directory' into dev/strict-mode
Conflicts:
Tests/CMakeLists.txt
Diffstat (limited to 'Source')
84 files changed, 1422 insertions, 1211 deletions
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index c86434e..46be99b 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -105,12 +105,12 @@ if (!archive) \ } //---------------------------------------------------------------------- -int cmCPackArchiveGenerator::PackageComponents(bool ignoreComponentGroup) +int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) { packageFileNames.clear(); // The default behavior is to have one package by component group // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. - if (!ignoreComponentGroup) + if (!ignoreGroup) { std::map<std::string, cmCPackComponentGroup>::iterator compGIt; for (compGIt=this->ComponentGroups.begin(); @@ -170,7 +170,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreComponentGroup) } //---------------------------------------------------------------------- -int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponentInOne) +int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponent) { // reset the package file names packageFileNames.clear(); @@ -185,7 +185,7 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponentInOne) DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive); // The ALL GROUP in ONE package case - if (! allComponentInOne) { + if (! allComponent) { // iterate over the component groups std::map<std::string, cmCPackComponentGroup>::iterator compGIt; for (compGIt=this->ComponentGroups.begin(); @@ -226,78 +226,27 @@ int cmCPackArchiveGenerator::PackageFiles() cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); - // The default behavior is to create 1 package by component group - // unless the user asked to put all COMPONENTS in a single package - bool allGroupInOne = (NULL != - (this->GetOption( - "CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE"))); - bool allComponentInOne = (NULL != - (this->GetOption( - "CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))); - bool ignoreComponentGroup = ( NULL != - (this->GetOption( - "CPACK_COMPONENTS_IGNORE_GROUPS"))); + PrepareGroupingKind(); - std::string groupingType; - - // Second way to specify grouping - if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) { - groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); - } - - if (groupingType.length()>0) - { - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" - << this->Name << "]" - << " requested component grouping = "<< groupingType <<std::endl); - if (groupingType == "ALL_GROUP_IN_ONE") - { - allGroupInOne = true; - } - else if (groupingType == "ALL_COMPONENT_IN_ONE") - { - allComponentInOne = true; - } - else if (groupingType == "IGNORE") + if (SupportsComponentInstallation()) { + // CASE 1 : COMPONENT ALL-IN-ONE package + // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested + // then the package file is unique and should be open here. + if (allComponentInOne || + (allGroupInOne && (!this->ComponentGroups.empty())) + ) { - ignoreComponentGroup = true; + return PackageComponentsAllInOne(allComponentInOne); } - else + // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) + // There will be 1 package for each component group + // however one may require to ignore component group and + // in this case you'll get 1 package for each component. + else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup)) { - cmCPackLogger(cmCPackLog::LOG_WARNING, "[" - << this->Name << "]" - << " requested component grouping type <"<< groupingType - << "> UNKNOWN not in (ALL_GROUP_IN_ONE," - "ALL_COMPONENT_IN_ONE,IGNORE)" <<std::endl); + return PackageComponents(ignoreComponentGroup); } - } - - // Some components were defined but NO group - // force ignoreGroups - if (this->ComponentGroups.empty() && (!this->Components.empty()) - && (!ignoreComponentGroup)) { - cmCPackLogger(cmCPackLog::LOG_WARNING, "[" - << this->Name << "]" - << " Some Components defined but NO component group:" - << " Ignoring component group." - << std::endl); - ignoreComponentGroup = true; } - // CASE 1 : COMPONENT ALL-IN-ONE package - // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested - // then the package file is unique and should be open here. - if (allComponentInOne || (allGroupInOne && (!this->ComponentGroups.empty()))) - { - return PackageComponentsAllInOne(allComponentInOne); - } - // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) - // There will be 1 package for each component group - // however one may require to ignore component group and - // in this case you'll get 1 package for each component. - else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup)) - { - return PackageComponents(ignoreComponentGroup); - } // CASE 3 : NON COMPONENT package. DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive); @@ -333,5 +282,15 @@ int cmCPackArchiveGenerator::GenerateHeader(std::ostream*) } bool cmCPackArchiveGenerator::SupportsComponentInstallation() const { - return true; + // The Component installation support should only + // be activated if explicitly requested by the user + // (for backward compatibility reason) + if (IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL")) + { + return true; + } + else + { + return false; + } } diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 6e173bd..dc17257 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -60,12 +60,12 @@ protected: * install is used. This will create one * archive for each component group. */ - int PackageComponents(bool ignoreComponentGroup); + int PackageComponents(bool ignoreGroup); /** * Special case of component install where all * components will be put in a single installer. */ - int PackageComponentsAllInOne(bool allComponentInOne); + int PackageComponentsAllInOne(bool allComponent); virtual const char* GetOutputExtension() = 0; cmArchiveWrite::Compress Compress; cmArchiveWrite::Type Archive; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index c39aea4..feda52c 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -35,6 +35,9 @@ cmCPackGenerator::cmCPackGenerator() this->GeneratorVerbose = false; this->MakefileMap = 0; this->Logger = 0; + this->allGroupInOne = false; + this->allComponentInOne = false; + this->ignoreComponentGroup = false; } //---------------------------------------------------------------------- @@ -220,7 +223,7 @@ int cmCPackGenerator::InstallProject() // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY - // This is used in Source packageing + // This is used in Source packaging if ( !this->InstallProjectViaInstalledDirectories( setDestDir, tempInstallDirectory) ) { @@ -548,7 +551,14 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( std::vector<std::string> componentsVector; bool componentInstall = false; - if (this->SupportsComponentInstallation()) + /* + * We do a component install iff + * - the CPack generator support component + * - the user did not request Monolithic install + * (this works at CPack time too) + */ + if (this->SupportsComponentInstallation() & + !(this->IsSet("CPACK_MONOLITHIC_INSTALL"))) { // Determine the installation types for this project (if provided). std::string installTypesVar = "CPACK_" @@ -691,7 +701,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // // If DESTDIR has been 'internally set ON' this means that // the underlying CPack specific generator did ask for that - // In this case we may overrode CPACK_INSTALL_PREFIX with + // In this case we may override CPACK_INSTALL_PREFIX with // CPACK_PACKAGING_INSTALL_PREFIX // I know this is tricky and awkward but it's the price for // CPACK_SET_DESTDIR backward compatibility. @@ -727,7 +737,20 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( { dir = tempInstallDirectory + "/" + dir; } - + /* + * We must re-set DESTDIR for each component + * We must not add the CPACK_INSTALL_PREFIX part because + * it will be added using the override of CMAKE_INSTALL_PREFIX + * The main reason for this awkward trick is that + * are using DESTDIR for 2 different reasons: + * - Because it was asked by the CPack Generator or the user + * using CPACK_SET_DESTDIR + * - Because it was already used for component install + * in order to put things in subdirs... + */ + cmSystemTools::PutEnv( + (std::string("DESTDIR=")+tempInstallDirectory).c_str() + ); cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Creating directory: '" << dir << "'" << std::endl); @@ -1047,7 +1070,13 @@ bool cmCPackGenerator::IsSet(const char* name) const } //---------------------------------------------------------------------- -const char* cmCPackGenerator::GetOption(const char* op) +bool cmCPackGenerator::IsOn(const char* name) const +{ + return cmSystemTools::IsOn(GetOption(name)); +} + +//---------------------------------------------------------------------- +const char* cmCPackGenerator::GetOption(const char* op) const { const char* ret = this->MakefileMap->GetDefinition(op); if(!ret) @@ -1196,6 +1225,70 @@ int cmCPackGenerator::CleanTemporaryDirectory() } //---------------------------------------------------------------------- +int cmCPackGenerator::PrepareGroupingKind() +{ + // The default behavior is to create 1 package by component group + // unless the user asked to put all COMPONENTS in a single package + allGroupInOne = (NULL != + (this->GetOption( + "CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE"))); + allComponentInOne = (NULL != + (this->GetOption( + "CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))); + ignoreComponentGroup = (NULL != + (this->GetOption( + "CPACK_COMPONENTS_IGNORE_GROUPS"))); + + std::string groupingType; + + // Second way to specify grouping + if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) { + groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); + } + + if (groupingType.length()>0) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" + << this->Name << "]" + << " requested component grouping = "<< groupingType <<std::endl); + if (groupingType == "ALL_GROUP_IN_ONE") + { + allGroupInOne = true; + } + else if (groupingType == "ALL_COMPONENT_IN_ONE") + { + allComponentInOne = true; + } + else if (groupingType == "IGNORE") + { + ignoreComponentGroup = true; + } + else + { + cmCPackLogger(cmCPackLog::LOG_WARNING, "[" + << this->Name << "]" + << " requested component grouping type <"<< groupingType + << "> UNKNOWN not in (ALL_GROUP_IN_ONE," + "ALL_COMPONENT_IN_ONE,IGNORE)" <<std::endl); + } + } + + // Some components were defined but NO group + // force ignoreGroups + if (this->ComponentGroups.empty() && (!this->Components.empty()) + && (!ignoreComponentGroup)) { + cmCPackLogger(cmCPackLog::LOG_WARNING, "[" + << this->Name << "]" + << " Some Components defined but NO component group:" + << " Ignoring component group." + << std::endl); + ignoreComponentGroup = true; + } + + return 1; +} + +//---------------------------------------------------------------------- bool cmCPackGenerator::SupportsComponentInstallation() const { return false; diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 74b780d..f44a334 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -88,8 +88,9 @@ public: //! Set and get the options void SetOption(const char* op, const char* value); void SetOptionIfNotSet(const char* op, const char* value); - const char* GetOption(const char* op); + const char* GetOption(const char* op) const; bool IsSet(const char* name) const; + bool IsOn(const char* name) const; //! Set all the variables int SetCMakeRoot(); @@ -120,6 +121,17 @@ protected: virtual const char* GetOutputPostfix() { return 0; } /** + * Prepare requested grouping kind from CPACK_xxx vars + * CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE + * CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE + * CPACK_COMPONENTS_IGNORE_GROUPS + * or + * CPACK_COMPONENTS_GROUPING + * @return 1 on success 0 on failure. + */ + virtual int PrepareGroupingKind(); + + /** * Package the list of files and/or components which * has been prepared by the beginning of DoPackage. * @pre @ref toplevel has been filled-in @@ -200,6 +212,20 @@ protected: */ std::map<std::string, cmCPackComponent> Components; std::map<std::string, cmCPackComponentGroup> ComponentGroups; + /** + * If true All component groups will be put in a single package. + */ + bool allGroupInOne; + /** + * If true All component will be put in a single package. + */ + bool allComponentInOne; + /** + * If true component grouping will be ignored. + * You will still get 1 package for each component unless + * allComponentInOne is true. + */ + bool ignoreComponentGroup; cmCPackLog* Logger; private: diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 0641418..a5db78f 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -37,13 +37,84 @@ int cmCPackRPMGenerator::InitializeInternal() //---------------------------------------------------------------------- int cmCPackRPMGenerator::PackageFiles() { - this->ReadListFile("CPackRPM.cmake"); + int retval = 1; + /* Digest Component grouping specification */ + retval = PrepareGroupingKind(); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " + << toplevel << std::endl); + + /* Are we in the component packaging case */ + if (SupportsComponentInstallation() & (!this->ComponentGroups.empty())) + { + /* Reset package file name list it will be populated during the + * component packaging run*/ + packageFileNames.clear(); + std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + /* One Package per component CASE */ + /* Iterate over components */ + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt=this->Components.begin(); + compIt!=this->Components.end(); ++compIt ) + { + std::string localToplevel(initialTopLevel); + std::string packageFileName( + cmSystemTools::GetParentDirectory(toplevel.c_str()) + ); + std::string outputFileName( + std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME") + ) + +"-"+compIt->first + this->GetOutputExtension()); + + localToplevel += "/"+ compIt->first; + /* replace the TEMP DIRECTORY with the component one */ + this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str()); + packageFileName += "/"+ outputFileName; + /* replace proposed CPACK_OUTPUT_FILE_NAME */ + this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str()); + /* replace the TEMPORARY package file name */ + this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME", + packageFileName.c_str()); + + this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compIt->first.c_str()); + if (!this->ReadListFile("CPackRPM.cmake")) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while execution CPackRPM.cmake" << std::endl); + retval = 0; + } + + // add the generated package to package file names list + packageFileNames.push_back(packageFileName); + } + } + /* This is the non component case */ + else + { + if (!this->ReadListFile("CPackRPM.cmake")) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while execution CPackRPM.cmake" << std::endl); + retval = 0; + } + } + if (!this->IsSet("RPMBUILD_EXECUTABLE")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find rpmbuild" << std::endl); - return 0; + retval = 0; } - return 1; + return retval; } +bool cmCPackRPMGenerator::SupportsComponentInstallation() const + { + if (IsOn("CPACK_RPM_COMPONENT_INSTALL")) + { + return true; + } + else + { + return false; + } + } diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h index 570e45f..57d5cca 100644 --- a/Source/CPack/cmCPackRPMGenerator.h +++ b/Source/CPack/cmCPackRPMGenerator.h @@ -39,6 +39,7 @@ protected: virtual int InitializeInternal(); virtual int PackageFiles(); virtual const char* GetOutputExtension() { return ".rpm"; } + virtual bool SupportsComponentInstallation() const; }; diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 0d14c2d..93c2963 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -275,12 +275,6 @@ void cmCTestMultiProcessHandler::StartNextTests() } numToStart -= processors; } - else - { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl - << "Test did not start waiting on depends to finish: " - << *test << "\n"); - } if(numToStart == 0) { return; diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 411eb01..468cd85 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h @@ -63,11 +63,10 @@ public: virtual const char* GetFullDocumentation() { return - " ctest_sleep( seconds )\n" - " ctest_sleep( time1 duration time2 )\n" - "With one argument it will sleep for a given number of seconds. " - "With three arguments it will wait for time2 - time1 - duration " - "seconds."; + " ctest_sleep(<seconds>)\n" + "Sleep for given number of seconds.\n" + " ctest_sleep(<time1> <duration> <time2>)\n" + "Sleep for t=(time1 + duration - time2) seconds if t > 0."; } cmTypeMacro(cmCTestSleepCommand, cmCTestCommand); diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 6dd348d..b8e38fb 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -2190,7 +2190,6 @@ bool cmCTestTestHandler::SetTestsProperties( { rtit->Labels.push_back(*crit); } - } if ( key == "MEASUREMENT" ) { @@ -2219,6 +2218,10 @@ bool cmCTestTestHandler::SetTestsProperties( std::string(crit->c_str()))); } } + if ( key == "WORKING_DIRECTORY" ) + { + rtit->Directory = val; + } } } } diff --git a/Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake b/Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake deleted file mode 100644 index 9f5cf00..0000000 --- a/Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake +++ /dev/null @@ -1,347 +0,0 @@ -# -# CMakeIngestOSXBundleLibraries.cmake -# -# Only for the Mac build. -# -# Depends on OS tools: -# otool -# install_name_tool -# -# This script ingests libraries and frameworks into an existing .app bundle and -# then uses install_name_tool to fixup the references to the newly embedded -# libraries so that they all refer to each other via "@executable_path." -# -# The main intent (and simplifying assumption used for developing the script) -# is to have a single executable .app bundle that becomes "self-contained" by -# copying all non-system libs that it depends on into itself. The further -# assumption is that all such dependencies are simple .dylib shared library -# files or Mac Framework libraries. -# -# This script can be used as part of the build via ADD_CUSTOM_COMMAND, or used -# only during make install via INSTALL SCRIPT. -# -if(NOT DEFINED input_file) - message(FATAL_ERROR " -${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): error: Variable input_file is not defined. - -Use a command line like this to use this script: - cmake \"-Dinput_file=filename\" \"-Dextra_libs=/path/to/lib1;/path/to/lib2\" \"-Dlib_path=/path/to/unqualified/libs\" -P \"${CMAKE_CURRENT_LIST_FILE}\" - -'input_file' should be the main executable inside a Mac bundle directory structure. -For example, use 'bin/paraview.app/Contents/MacOS/paraview' from a ParaView binary dir. - -'extra_libs' should be a semi-colon separated list of full path names to extra libraries -to copy into the bundle that cannot be derived from otool -L output. For example, you may -also want to fixup dynamically loaded plugins from your build tree and copy them into the -bundle. - -'lib_path' should be the path where to find libraries referenced without a path name in -otool -L output. - -") -endif(NOT DEFINED input_file) -message("ingest ${input_file}") -set(eol_char "E") - -if(APPLE) - set(dep_tool "otool") - set(dep_cmd_args "-L") - set(dep_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$") -endif(APPLE) - -message("") -message("# Script \"${CMAKE_CURRENT_LIST_FILE}\" running...") -message("") -message("input_file: '${input_file}'") -message("extra_libs: '${extra_libs}'") -message("lib_path: '${lib_path}'") -message("") - -get_filename_component(input_file_full "${input_file}" ABSOLUTE) -message("input_file_full: '${input_file_full}'") - -get_filename_component(bundle "${input_file_full}/../../.." ABSOLUTE) -message("bundle: '${bundle}'") - - -find_program(dep_cmd ${dep_tool}) - -# find the full path to the framework in path set the result -# in pathout -macro(find_framework_full_path path pathout) - set(${pathout} "${path}") - if(NOT EXISTS "${path}") - set(FRAMEWORK_SEARCH "/Library/Frameworks" - "/System/Library/Frameworks" ) - set(__FOUND FALSE) - foreach(f ${FRAMEWORK_SEARCH}) - set(newd "${f}/${path}") - if(EXISTS "${newd}" AND NOT __FOUND) - set(${pathout} "${newd}") - set(__FOUND TRUE) - endif(EXISTS "${newd}" AND NOT __FOUND) - endforeach(f) - endif(NOT EXISTS "${path}") -endmacro(find_framework_full_path) - - -macro(append_unique au_list_var au_value) - set(${au_list_var} ${${au_list_var}} "${au_value}") -endmacro(append_unique) - - -macro(gather_dependents gd_target gd_dependents_var) - execute_process( - COMMAND ${dep_cmd} ${dep_cmd_args} ${gd_target} - OUTPUT_VARIABLE dep_tool_ov - ) - - string(REGEX REPLACE ";" "\\\\;" dep_candidates "${dep_tool_ov}") - string(REGEX REPLACE "\n" "${eol_char};" dep_candidates "${dep_candidates}") - - set(${gd_dependents_var} "") - - foreach(candidate ${dep_candidates}) - if("${candidate}" MATCHES "${dep_regex}") - string(REGEX REPLACE "${dep_regex}" "\\1" raw_item "${candidate}") - string(REGEX REPLACE "${dep_regex}" "\\2" raw_compat_version "${candidate}") - string(REGEX REPLACE "${dep_regex}" "\\3" raw_current_version "${candidate}") - - set(item "${raw_item}") - - string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}") - string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}") - string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}") - - string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}") - string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}") - string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}") - - #message("${raw_item} - compat ${raw_compat_version} - current ${raw_current_version}") - append_unique("${gd_dependents_var}" "${item}") - else("${candidate}" MATCHES "${dep_regex}") - if("${candidate}" STREQUAL "${gd_target}:${eol_char}") - #message("info: ignoring target name...") - else("${candidate}" STREQUAL "${gd_target}:${eol_char}") - message("error: candidate='${candidate}'") - endif("${candidate}" STREQUAL "${gd_target}:${eol_char}") - endif("${candidate}" MATCHES "${dep_regex}") - endforeach(candidate) -endmacro(gather_dependents) - - -message("Gathering dependent libraries for '${input_file_full}'...") -gather_dependents("${input_file_full}" deps) -message("") - - -# Order lexicographically: -# -list(SORT deps) - - -# Split into separate lists, "system" "embedded" and "nonsystem" libraries. -# System libs are assumed to be available on all target runtime Macs and do not -# need to be copied/fixed-up by this script. Embedded libraries are assumed to -# be in the bundle and fixed-up already. Only non-system, non-embedded libs -# need copying and fixing up... -# -set(system_deps "") -set(embedded_deps "") -set(nonsystem_deps "") - -foreach(d ${deps}) - set(d_is_embedded_lib 0) - set(d_is_system_lib 0) - - if("${d}" MATCHES "^(/System/Library|/usr/lib)") - set(d_is_system_lib 1) - else("${d}" MATCHES "^(/System/Library|/usr/lib)") - if("${d}" MATCHES "^@executable_path") - set(d_is_embedded_lib 1) - endif("${d}" MATCHES "^@executable_path") - endif("${d}" MATCHES "^(/System/Library|/usr/lib)") - - if(d_is_system_lib) - set(system_deps ${system_deps} "${d}") - else(d_is_system_lib) - if(d_is_embedded_lib) - set(embedded_deps ${embedded_deps} "${d}") - else(d_is_embedded_lib) - set(nonsystem_deps ${nonsystem_deps} "${d}") - endif(d_is_embedded_lib) - endif(d_is_system_lib) -endforeach(d) - -message("") -message("system_deps:") -foreach(d ${system_deps}) - message("${d}") -endforeach(d ${system_deps}) - -message("") -message("embedded_deps:") -foreach(d ${embedded_deps}) - message("${d}") -endforeach(d ${embedded_deps}) - -message("") -message("nonsystem_deps:") -foreach(d ${nonsystem_deps}) - message("${d}") -endforeach(d ${nonsystem_deps}) - -message("") - - -macro(copy_library_into_bundle clib_bundle clib_libsrc clib_dstlibs clib_fixups) - # - # If the source library is a framework, copy just the shared lib bit of the framework - # into the bundle under "${clib_bundle}/Contents/Frameworks" - if it is just a dylib - # copy it into the same directory with the main bundle executable under - # "${clib_bundle}/Contents/MacOS" - # - if("${clib_libsrc}" MATCHES ".framework/.*/.*/.*") - # make sure clib_libsrc is a full path to the framework as a framework - # maybe linked in with relative paths in some cases - find_framework_full_path("${clib_libsrc}" fw_full_src) - get_filename_component(fw_src "${fw_full_src}" ABSOLUTE) - get_filename_component(fw_srcdir "${clib_libsrc}/../../.." ABSOLUTE) - get_filename_component(fwdirname "${fw_srcdir}" NAME) - string(REGEX REPLACE "^(.*)\\.framework$" "\\1" fwname "${fwdirname}") - string(REGEX REPLACE "^.*/${fwname}\\.framework/(.*)$" "\\1" fwlibname "${clib_libsrc}") - set(fw_dstdir "${clib_bundle}/Contents/Frameworks") - -# message("") -# message("fwdirname: '${fwdirname}'") -# message("fwname: '${fwname}'") -# message("fwlibname: '${fwlibname}'") -# message("fw_src: '${fw_src}'") -# message("fw_srcdir: '${fw_srcdir}'") -# message("fw_dstdir: '${fw_dstdir}'") -# message("new_name: '@executable_path/../Frameworks/${fwdirname}/${fwlibname}'") -# message("") - - message("Copying ${fw_srcdir} into bundle...") - - # This command copies the *entire* framework recursively: - # -# execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory -# "${fw_srcdir}" "${fw_dstdir}" -# ) - - # This command copies just the main shared lib of the framework: - # (This technique will not work for frameworks that have necessary - # resource or auxiliary files...) - # - message("fw_src = [${fw_src}] fw_full_src = [${fw_full_src}]") - message("Copy: ${CMAKE_COMMAND} -E copy \"${fw_src}\" \"${fw_dstdir}/${fwlibname}\"") - execute_process(COMMAND ${CMAKE_COMMAND} -E copy - "${fw_src}" "${fw_dstdir}/${fwlibname}" - ) - - get_filename_component(fw_src_path "${fw_src}" PATH) - message("Checking ${fw_src_path}/Resources") - if(EXISTS "${fw_src_path}/Resources") - message("Copy: ${CMAKE_COMMAND} -E copy_directory \"${fw_src_path}/Resources/\" \"${fw_dstdir}/Resources/\"") - execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory - "${fw_src_path}/Resources/" "${fw_dstdir}/${fwdirname}/Resources/") - endif(EXISTS "${fw_src_path}/Resources") - - execute_process(COMMAND install_name_tool - -id "@executable_path/../Frameworks/${fwlibname}" - "${clib_bundle}/Contents/Frameworks/${fwlibname}" - ) - set(${clib_dstlibs} ${${clib_dstlibs}} - "${clib_bundle}/Contents/Frameworks/${fwlibname}" - ) - set(${clib_fixups} ${${clib_fixups}} - "-change" - "${clib_libsrc}" - "@executable_path/../Frameworks/${fwlibname}" - ) - else("${clib_libsrc}" MATCHES ".framework/.*/.*/.*") - if("${clib_libsrc}" MATCHES "/") - set(clib_libsrcfull "${clib_libsrc}") - else("${clib_libsrc}" MATCHES "/") - set(clib_libsrcfull "${lib_path}/${clib_libsrc}") - if(NOT EXISTS "${clib_libsrcfull}") - message(FATAL_ERROR "error: '${clib_libsrcfull}' does not exist...") - endif(NOT EXISTS "${clib_libsrcfull}") - endif("${clib_libsrc}" MATCHES "/") - - get_filename_component(dylib_src "${clib_libsrcfull}" ABSOLUTE) - get_filename_component(dylib_name "${dylib_src}" NAME) - set(dylib_dst "${clib_bundle}/Contents/MacOS/${dylib_name}") - -# message("dylib_src: ${dylib_src}") -# message("dylib_dst: ${dylib_dst}") -# message("new_name: '@executable_path/${dylib_name}'") - - message("Copying ${dylib_src} into bundle...") - execute_process(COMMAND ${CMAKE_COMMAND} -E copy - "${dylib_src}" "${dylib_dst}") - execute_process(COMMAND install_name_tool - -id "@executable_path/${dylib_name}" - "${dylib_dst}" - ) - set(${clib_dstlibs} ${${clib_dstlibs}} - "${dylib_dst}" - ) - set(${clib_fixups} ${${clib_fixups}} - "-change" - "${clib_libsrc}" - "@executable_path/${dylib_name}" - ) - endif("${clib_libsrc}" MATCHES ".framework/.*/.*/.*") -endmacro(copy_library_into_bundle) - - -# Copy dependent "nonsystem" libraries into the bundle: -# -message("Copying dependent libraries into bundle...") -set(srclibs ${nonsystem_deps} ${extra_libs}) -set(dstlibs "") -set(fixups "") -foreach(d ${srclibs}) - message("copy it --- ${d}") - copy_library_into_bundle("${bundle}" "${d}" dstlibs fixups) -endforeach(d) - -message("") -message("dstlibs='${dstlibs}'") -message("") -message("fixups='${fixups}'") -message("") - - -# Fixup references to copied libraries in the main bundle executable and in the -# copied libraries themselves: -# -if(NOT "${fixups}" STREQUAL "") - message("Fixing up references...") - foreach(d ${dstlibs} "${input_file_full}") - message("fixing up references in: '${d}'") - execute_process(COMMAND install_name_tool ${fixups} "${d}") - endforeach(d) - message("") -endif(NOT "${fixups}" STREQUAL "") - - -# List all references to eyeball them and make sure they look right: -# -message("Listing references...") -foreach(d ${dstlibs} "${input_file_full}") - execute_process(COMMAND otool -L "${d}") - message("") -endforeach(d) -message("") - - -# Output file: -# -#get_filename_component(script_name "${CMAKE_CURRENT_LIST_FILE}" NAME) -#file(WRITE "${input_file_full}_${script_name}" "# Script \"${CMAKE_CURRENT_LIST_FILE}\" completed.\n") -message("") -message("# Script \"${CMAKE_CURRENT_LIST_FILE}\" completed.") -message("") diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 405c952..4785188 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -19,13 +19,6 @@ ELSE(NOT QT4_FOUND) INCLUDE(${QT_USE_FILE}) SET(CMAKE_PACKAGE_QTGUI TRUE) - # i don't want to install or package the qt gui on windows - # unless qt is static - IF(WIN32 AND NOT QT_CONFIG MATCHES "static") - SET(CMAKE_PACKAGE_QTGUI FALSE) - MESSAGE(STATUS - "WARNING: QtDialog requires a static built qt for installation.") - ENDIF(WIN32 AND NOT QT_CONFIG MATCHES "static") SET(SRCS AddCacheEntry.cxx AddCacheEntry.h @@ -86,12 +79,8 @@ ELSE(NOT QT4_FOUND) SET(CMAKE_INSTALL_DESTINATION_ARGS BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) - # if qt is not static and we are on windows then skip the install - # I don't want to distribute qt dlls - IF(CMAKE_PACKAGE_QTGUI) - INSTALL(TARGETS cmake-gui RUNTIME DESTINATION bin - ${CMAKE_INSTALL_DESTINATION_ARGS}) - ENDIF(CMAKE_PACKAGE_QTGUI) + + INSTALL(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) IF(UNIX) # install a desktop file so CMake appears in the application start menu @@ -112,10 +101,21 @@ ELSE(NOT QT4_FOUND) "${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)") - INSTALL(CODE "set(input_file - \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}\")") - INSTALL(SCRIPT "${CMake_SOURCE_DIR}/Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake") ENDIF(APPLE) + + 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) + CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) ENDIF(NOT QT4_FOUND) diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 28f4697..7ba7f51 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -165,13 +165,25 @@ int main(int argc, char** argv) if(args.count() == 2) { cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toAscii().data()); + + // check if argument is a directory containing CMakeCache.txt cmsys_stl::string buildFilePath = cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str()); + + // check if argument is a CMakeCache.txt file + if(cmSystemTools::GetFilenameName(filePath) == "CMakeCache.txt" && + cmSystemTools::FileExists(filePath.c_str())) + { + buildFilePath = filePath; + } + + // check if argument is a directory containing CMakeLists.txt cmsys_stl::string srcFilePath = cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str()); + if(cmSystemTools::FileExists(buildFilePath.c_str())) { - dialog.setBinaryDirectory(filePath.c_str()); + dialog.setBinaryDirectory(cmSystemTools::GetFilenamePath(buildFilePath).c_str()); } else if(cmSystemTools::FileExists(srcFilePath.c_str())) { diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index f6b3234..7af6ec8 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -161,6 +161,7 @@ bool cmAddCustomCommandCommand filename += "/"; } filename += copy; + cmSystemTools::ConvertToUnixSlashes(filename); break; case doing_source: // We do not want to convert the argument to SOURCE because diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index c67caa5..6c5e1af 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -152,6 +152,9 @@ public: "If any dependency is an OUTPUT of another custom command in the " "same directory (CMakeLists.txt file) CMake automatically brings the " "other custom command into the target in which this command is built. " + "If DEPENDS is not specified the command will run whenever the OUTPUT " + "is missing; if the command does not actually create the OUTPUT then " + "the rule will always run. " "If DEPENDS specifies any target (created by an ADD_* command) " "a target-level dependency is created to make sure the target is " "built before any target using this custom command. Additionally, " diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index 1205f07..a77140d 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -24,11 +24,7 @@ bool cmAddDependenciesCommand } std::string target_name = args[0]; - - cmTarget* target = - this->GetMakefile()->GetLocalGenerator()-> - GetGlobalGenerator()->FindTarget(0, target_name.c_str()); - if(target) + if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str())) { std::vector<std::string>::const_iterator s = args.begin(); ++s; // skip over target_name diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h index 6a981c3..fee011c 100644 --- a/Source/cmAddDependenciesCommand.h +++ b/Source/cmAddDependenciesCommand.h @@ -62,6 +62,8 @@ public: "top-level target is one created by ADD_EXECUTABLE, ADD_LIBRARY, " "or ADD_CUSTOM_TARGET. Adding dependencies with this command " "can be used to make sure one target is built before another target. " + "Dependencies added to an IMPORTED target are followed transitively " + "in its place since the target itself does not build. " "See the DEPENDS option of ADD_CUSTOM_TARGET " "and ADD_CUSTOM_COMMAND for adding file-level dependencies in custom " "rules. See the OBJECT_DEPENDS option in " diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 2aa6236..c8374db 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -93,14 +93,14 @@ bool cmCacheManager::LoadCache(const char* path, return this->LoadCache(path, internal, emptySet, emptySet); } -bool cmCacheManager::ParseEntry(const char* entry, - std::string& var, - std::string& value) +static bool ParseEntryWithoutType(const char* entry, + std::string& var, + std::string& value) { - // input line is: key:type=value + // input line is: key=value static cmsys::RegularExpression reg( - "^([^:]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); - // input line is: "key":type=value + "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); + // input line is: "key"=value static cmsys::RegularExpression regQuoted( "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); bool flag = false; @@ -169,6 +169,11 @@ bool cmCacheManager::ParseEntry(const char* entry, value.size() - 2); } + if (!flag) + { + return ParseEntryWithoutType(entry, var, value); + } + return flag; } @@ -336,7 +341,7 @@ bool cmCacheManager::LoadCache(const char* path, std::string("The current CMakeCache.txt directory ") + currentcwd + std::string(" is different than the directory ") + std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) + - std::string(" where CMackeCache.txt was created. This may result " + std::string(" where CMakeCache.txt was created. This may result " "in binaries being created in the wrong place. If you " "are not sure, reedit the CMakeCache.txt"); cmSystemTools::Error(message.c_str()); diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index da14966..314017b 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -139,10 +139,6 @@ public: std::string& value, CacheEntryType& type); - static bool ParseEntry(const char* entry, - std::string& var, - std::string& value); - ///! Get a value from the cache given a key const char* GetCacheValue(const char* key) const; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 1cabed2..d53200c 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -923,7 +923,7 @@ void cmComputeLinkInformation::ComputeItemParserInfo() //---------------------------------------------------------------------------- void cmComputeLinkInformation::AddLinkPrefix(const char* p) { - if(p) + if(p && *p) { this->LinkPrefixes.insert(p); } diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 313c680..a4ca363 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -144,7 +144,7 @@ bool cmComputeTargetDepends::Compute() //---------------------------------------------------------------------------- void cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t, - std::set<cmTarget*>& deps) + cmTargetDependSet& deps) { // Lookup the index for this target. All targets should be known by // this point. @@ -156,7 +156,9 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t, EdgeList const& nl = this->FinalGraph[i]; for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { - deps.insert(this->Targets[*ni]); + cmTarget* dep = this->Targets[*ni]; + cmTargetDependSet::iterator di = deps.insert(dep).first; + di->SetType(ni->IsStrong()); } } @@ -244,13 +246,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, // Check the target's makefile first. cmTarget* dependee = - depender->GetMakefile()->FindTarget(dependee_name); - - // Then search globally. - if(!dependee) - { - dependee = this->GlobalGenerator->FindTarget(0, dependee_name); - } + depender->GetMakefile()->FindTargetToUse(dependee_name); // Skip targets that will not really be linked. This is probably a // name conflict between an external library and an executable @@ -262,25 +258,42 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, dependee = 0; } - // If not found then skip then the dependee. - if(!dependee) + if(dependee) { - return; + this->AddTargetDepend(depender_index, dependee, linking); } +} - // No imported targets should have been found. - assert(!dependee->IsImported()); - - // Lookup the index for this target. All targets should be known by - // this point. - std::map<cmTarget*, int>::const_iterator tii = - this->TargetIndex.find(dependee); - assert(tii != this->TargetIndex.end()); - int dependee_index = tii->second; - - // Add this entry to the dependency graph. - this->InitialGraph[depender_index].push_back( - cmGraphEdge(dependee_index, !linking)); +//---------------------------------------------------------------------------- +void cmComputeTargetDepends::AddTargetDepend(int depender_index, + cmTarget* dependee, + bool linking) +{ + if(dependee->IsImported()) + { + // Skip imported targets but follow their utility dependencies. + std::set<cmStdString> const& utils = dependee->GetUtilities(); + for(std::set<cmStdString>::const_iterator i = utils.begin(); + i != utils.end(); ++i) + { + cmTarget* transitive_dependee = + dependee->GetMakefile()->FindTargetToUse(i->c_str()); + this->AddTargetDepend(depender_index, transitive_dependee, false); + } + } + else + { + // Lookup the index for this target. All targets should be known by + // this point. + std::map<cmTarget*, int>::const_iterator tii = + this->TargetIndex.find(dependee); + assert(tii != this->TargetIndex.end()); + int dependee_index = tii->second; + + // Add this entry to the dependency graph. + this->InitialGraph[depender_index].push_back( + cmGraphEdge(dependee_index, !linking)); + } } //---------------------------------------------------------------------------- @@ -445,7 +458,7 @@ cmComputeTargetDepends int j = *ei; if(cmap[j] == c && ei->IsStrong()) { - this->FinalGraph[i].push_back(j); + this->FinalGraph[i].push_back(cmGraphEdge(j, true)); if(!this->IntraComponent(cmap, c, j, head, emitted, visited)) { return false; @@ -456,7 +469,7 @@ cmComputeTargetDepends // Prepend to a linear linked-list of intra-component edges. if(*head >= 0) { - this->FinalGraph[i].push_back(*head); + this->FinalGraph[i].push_back(cmGraphEdge(*head, false)); } else { @@ -515,7 +528,7 @@ cmComputeTargetDepends int dependee_component = *ni; int dependee_component_head = this->ComponentHead[dependee_component]; this->FinalGraph[depender_component_tail] - .push_back(dependee_component_head); + .push_back(cmGraphEdge(dependee_component_head, ni->IsStrong())); } } return true; diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 240de76..67bce72 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -21,6 +21,7 @@ class cmComputeComponentGraph; class cmGlobalGenerator; class cmTarget; +class cmTargetDependSet; /** \class cmComputeTargetDepends * \brief Compute global interdependencies among targets. @@ -38,13 +39,14 @@ public: bool Compute(); std::vector<cmTarget*> const& GetTargets() const { return this->Targets; } - void GetTargetDirectDepends(cmTarget* t, std::set<cmTarget*>& deps); + void GetTargetDirectDepends(cmTarget* t, cmTargetDependSet& deps); private: void CollectTargets(); void CollectDepends(); void CollectTargetDepends(int depender_index); void AddTargetDepend(int depender_index, const char* dependee_name, bool linking); + void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking); bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); cmGlobalGenerator* GlobalGenerator; diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 30356c8..75f9824 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -169,8 +169,9 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) const char* lang =(this->Makefile->GetCMakeInstance()->GetGlobalGenerator() ->GetLanguageFromExtension(ext.c_str())); const char* def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH"); - fprintf(fout, "cmake_minimum_required(VERSION %u.%u)\n", - cmVersion::GetMajorVersion(), cmVersion::GetMinorVersion()); + fprintf(fout, "cmake_minimum_required(VERSION %u.%u.%u.%u)\n", + cmVersion::GetMajorVersion(), cmVersion::GetMinorVersion(), + cmVersion::GetPatchVersion(), cmVersion::GetTweakVersion()); if(def) { fprintf(fout, "SET(CMAKE_MODULE_PATH %s)\n", def); @@ -394,28 +395,18 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir) } else { - if(!cmSystemTools::RemoveFile(fullPath.c_str())) + // Sometimes anti-virus software hangs on to new files so we + // cannot delete them immediately. Try a few times. + int tries = 5; + while(!cmSystemTools::RemoveFile(fullPath.c_str()) && + --tries && cmSystemTools::FileExists(fullPath.c_str())) { - bool removed = false; - int numAttempts = 0; - // sometimes anti-virus software hangs on to - // new files and we can not delete them, so try - // 5 times with .5 second delay between tries. - while(!removed && numAttempts < 5) - { - cmSystemTools::Delay(500); - if(cmSystemTools::RemoveFile(fullPath.c_str())) - { - removed = true; - } - numAttempts++; - } - if(!removed) - { - std::string m = "Remove failed on file: "; - m += fullPath; - cmSystemTools::ReportLastSystemError(m.c_str()); - } + cmSystemTools::Delay(500); + } + if(tries == 0) + { + std::string m = "Remove failed on file: " + fullPath; + cmSystemTools::ReportLastSystemError(m.c_str()); } } } diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index a877680..a69bb8f 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1336,6 +1336,29 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "this variable is defined to 1.", false,"Variables for Languages"); + cm->DefineProperty( + "CMAKE_Fortran_MODDIR_FLAG", cmProperty::VARIABLE, + "Fortran flag for module output directory.", + "This stores the flag needed to pass the value of the " + "Fortran_MODULE_DIRECTORY target property to the compiler.", + false,"Variables for Languages"); + + cm->DefineProperty( + "CMAKE_Fortran_MODDIR_DEFAULT", cmProperty::VARIABLE, + "Fortran default module output directory.", + "Most Fortran compilers write .mod files to the current working " + "directory. " + "For those that do not, this is set to \".\" and used when the " + "Fortran_MODULE_DIRECTORY target property is not set.", + false,"Variables for Languages"); + + cm->DefineProperty( + "CMAKE_Fortran_MODOUT_FLAG", cmProperty::VARIABLE, + "Fortran flag to enable module output.", + "Most Fortran compilers write .mod files out by default. " + "For others, this stores the flag needed to enable module output.", + false,"Variables for Languages"); + // variables that are used by cmake but not to be documented cm->DefineProperty("CMAKE_MATCH_0", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_MATCH_1", cmProperty::VARIABLE,0,0); diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index e6d7a6d..a5650d4 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -23,7 +23,7 @@ #include <cmsys/SystemTools.hxx> /* Some useful URLs: -Homepage: +Homepage: http://www.codeblocks.org File format docs: @@ -63,16 +63,6 @@ cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator() } -void cmExtraCodeBlocksGenerator::SetGlobalGenerator( - cmGlobalGenerator* generator) -{ - cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator); - cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*) - generator; - mf->SetToolSupportsColor(false); - mf->SetForceVerboseMakefiles(true); -} - void cmExtraCodeBlocksGenerator::Generate() { // for each sub project in the project create a codeblocks project @@ -107,7 +97,7 @@ void cmExtraCodeBlocksGenerator::CreateProjectFile( /* Tree is used to create a "Virtual Folder" in CodeBlocks, in which all CMake files this project depends on will be put. This means additionally to the "Sources" and "Headers" virtual folders of CodeBlocks, there will - now also be a "CMake Files" virtual folder. + now also be a "CMake Files" virtual folder. Patch by Daniel Teske <daniel.teske AT nokia.com> (which use C::B project files in QtCreator).*/ struct Tree @@ -115,24 +105,24 @@ struct Tree std::string path; //only one component of the path std::vector<Tree> folders; std::vector<std::string> files; - void InsertPath(const std::vector<std::string>& splitted, - std::vector<std::string>::size_type start, + void InsertPath(const std::vector<std::string>& splitted, + std::vector<std::string>::size_type start, const std::string& fileName); void BuildVirtualFolder(std::string& virtualFolders) const; - void BuildVirtualFolderImpl(std::string& virtualFolders, + void BuildVirtualFolderImpl(std::string& virtualFolders, const std::string& prefix) const; void BuildUnit(std::string& unitString, const std::string& fsPath) const; - void BuildUnitImpl(std::string& unitString, - const std::string& virtualFolderPath, + void BuildUnitImpl(std::string& unitString, + const std::string& virtualFolderPath, const std::string& fsPath) const; }; -void Tree::InsertPath(const std::vector<std::string>& splitted, - std::vector<std::string>::size_type start, +void Tree::InsertPath(const std::vector<std::string>& splitted, + std::vector<std::string>::size_type start, const std::string& fileName) { - if (start == splitted.size()) + if (start == splitted.size()) { files.push_back(fileName); return; @@ -301,7 +291,7 @@ void cmExtraCodeBlocksGenerator } // Now build a virtual tree string - std::string virtualFolders; + std::string virtualFolders; tree.BuildVirtualFolder(virtualFolders); // And one for <Unit> std::string unitFiles; @@ -323,7 +313,7 @@ void cmExtraCodeBlocksGenerator this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str()); - // add all executable and library targets and some of the GLOBAL + // add all executable and library targets and some of the GLOBAL // and UTILITY targets for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin(); lg!=lgs.end(); lg++) @@ -338,9 +328,9 @@ void cmExtraCodeBlocksGenerator case cmTarget::GLOBAL_TARGET: { bool insertTarget = false; - // Only add the global targets from CMAKE_BINARY_DIR, + // Only add the global targets from CMAKE_BINARY_DIR, // not from the subdirs - if (strcmp(makefile->GetStartOutputDirectory(), + if (strcmp(makefile->GetStartOutputDirectory(), makefile->GetHomeOutputDirectory())==0) { insertTarget = true; @@ -362,7 +352,7 @@ void cmExtraCodeBlocksGenerator } if (insertTarget) { - this->AppendTarget(fout, ti->first.c_str(), 0, + this->AppendTarget(fout, ti->first.c_str(), 0, make.c_str(), makefile, compiler.c_str()); } } @@ -372,13 +362,13 @@ void cmExtraCodeBlocksGenerator // Experimental-"sub"targets as e.g. NightlyStart if (((ti->first.find("Nightly")==0) &&(ti->first!="Nightly")) || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous")) - || ((ti->first.find("Experimental")==0) + || ((ti->first.find("Experimental")==0) && (ti->first!="Experimental"))) { break; } - this->AppendTarget(fout, ti->first.c_str(), 0, + this->AppendTarget(fout, ti->first.c_str(), 0, make.c_str(), makefile, compiler.c_str()); break; case cmTarget::EXECUTABLE: @@ -386,11 +376,11 @@ void cmExtraCodeBlocksGenerator case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: { - this->AppendTarget(fout, ti->first.c_str(), &ti->second, + this->AppendTarget(fout, ti->first.c_str(), &ti->second, make.c_str(), makefile, compiler.c_str()); std::string fastTarget = ti->first; fastTarget += "/fast"; - this->AppendTarget(fout, fastTarget.c_str(), &ti->second, + this->AppendTarget(fout, fastTarget.c_str(), &ti->second, make.c_str(), makefile, compiler.c_str()); } break; @@ -437,7 +427,7 @@ void cmExtraCodeBlocksGenerator { for(std::vector<std::string>::const_iterator ext = mf->GetSourceExtensions().begin(); - ext != mf->GetSourceExtensions().end(); + ext != mf->GetSourceExtensions().end(); ++ext) { if ((*si)->GetExtension() == *ext) @@ -467,11 +457,11 @@ void cmExtraCodeBlocksGenerator // The following loop tries to add header files matching to implementation // files to the project. It does that by iterating over all source files, - // replacing the file name extension with ".h" and checks whether such a + // replacing the file name extension with ".h" and checks whether such a // file exists. If it does, it is inserted into the map of files. // A very similar version of that code exists also in the kdevelop // project generator. - for (std::map<std::string, cmSourceFile*>::const_iterator + for (std::map<std::string, cmSourceFile*>::const_iterator sit=cFiles.begin(); sit!=cFiles.end(); ++sit) @@ -483,7 +473,7 @@ void cmExtraCodeBlocksGenerator // check if there's a matching header around for(std::vector<std::string>::const_iterator ext = mf->GetHeaderExtensions().begin(); - ext != mf->GetHeaderExtensions().end(); + ext != mf->GetHeaderExtensions().end(); ++ext) { std::string hname=headerBasename; @@ -506,7 +496,7 @@ void cmExtraCodeBlocksGenerator // insert all source files in the CodeBlocks project // first the C/C++ implementation files, then all others - for (std::map<std::string, cmSourceFile*>::const_iterator + for (std::map<std::string, cmSourceFile*>::const_iterator sit=cFiles.begin(); sit!=cFiles.end(); ++sit) @@ -514,7 +504,7 @@ void cmExtraCodeBlocksGenerator fout<<" <Unit filename=\""<< sit->first <<"\">\n" " </Unit>\n"; } - for (std::set<std::string>::const_iterator + for (std::set<std::string>::const_iterator sit=otherFiles.begin(); sit!=otherFiles.end(); ++sit) @@ -577,7 +567,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, " <Option compiler=\"" << compiler << "\" />\n" " <Compiler>\n"; // the include directories for this target - const std::vector<std::string>& incDirs = + const std::vector<std::string>& incDirs = target->GetMakefile()->GetIncludeDirectories(); for(std::vector<std::string>::const_iterator dirIt=incDirs.begin(); dirIt != incDirs.end(); @@ -589,27 +579,27 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, } else // e.g. all and the GLOBAL and UTILITY targets { - fout<<" <Option working_dir=\"" + fout<<" <Option working_dir=\"" << makefile->GetStartOutputDirectory() << "\" />\n" <<" <Option type=\"" << 4 << "\" />\n"; } fout<<" <MakeCommands>\n" - " <Build command=\"" + " <Build command=\"" << this->BuildMakeCommand(make, makefileName.c_str(), targetName) << "\" />\n" - " <CompileFile command=\"" + " <CompileFile command=\"" << this->BuildMakeCommand(make, makefileName.c_str(),""$file"") << "\" />\n" - " <Clean command=\"" - << this->BuildMakeCommand(make, makefileName.c_str(), "clean") + " <Clean command=\"" + << this->BuildMakeCommand(make, makefileName.c_str(), "clean") << "\" />\n" - " <DistClean command=\"" - << this->BuildMakeCommand(make, makefileName.c_str(), "clean") + " <DistClean command=\"" + << this->BuildMakeCommand(make, makefileName.c_str(), "clean") << "\" />\n" " </MakeCommands>\n" " </Target>\n"; - + } @@ -675,7 +665,7 @@ int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target) { return 2; } - else if ((target->GetType()==cmTarget::SHARED_LIBRARY) + else if ((target->GetType()==cmTarget::SHARED_LIBRARY) || (target->GetType()==cmTarget::MODULE_LIBRARY)) { return 3; @@ -695,16 +685,18 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand( command += " /NOLOGO /f ""; command += makefileName; command += "" "; + command += " VERBOSE=1 "; command += target; } else if (strcmp(this->GlobalGenerator->GetName(), "MinGW Makefiles")==0) { - // no escaping of spaces in this case, see + // no escaping of spaces in this case, see // http://public.kitware.com/Bug/view.php?id=10014 - std::string makefileName = makefile; + std::string makefileName = makefile; command += " -f ""; command += makefileName; command += "" "; + command += " VERBOSE=1 "; command += target; } else @@ -713,6 +705,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand( command += " -f ""; command += makefileName; command += "" "; + command += " VERBOSE=1 "; command += target; } return command; diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h index 97a2d24..57751fc 100644 --- a/Source/cmExtraCodeBlocksGenerator.h +++ b/Source/cmExtraCodeBlocksGenerator.h @@ -22,22 +22,19 @@ class cmGeneratedFileStream; /** \class cmExtraCodeBlocksGenerator * \brief Write CodeBlocks project files for Makefile based projects - * - * This generator is in early alpha stage. */ class cmExtraCodeBlocksGenerator : public cmExternalMakefileProjectGenerator { public: cmExtraCodeBlocksGenerator(); - virtual void SetGlobalGenerator(cmGlobalGenerator* generator); virtual const char* GetName() const { return cmExtraCodeBlocksGenerator::GetActualName();} static const char* GetActualName() { return "CodeBlocks";} - static cmExternalMakefileProjectGenerator* New() + static cmExternalMakefileProjectGenerator* New() { return new cmExtraCodeBlocksGenerator; } /** Get the documentation entry for this generator. */ - virtual void GetDocumentation(cmDocumentationEntry& entry, + virtual void GetDocumentation(cmDocumentationEntry& entry, const char* fullName) const; virtual void Generate(); @@ -49,7 +46,7 @@ private: const std::string& filename); std::string GetCBCompilerId(const cmMakefile* mf); int GetCBTargetType(cmTarget* target); - std::string BuildMakeCommand(const std::string& make, const char* makefile, + std::string BuildMakeCommand(const std::string& make, const char* makefile, const char* target); void AppendTarget(cmGeneratedFileStream& fout, const char* targetName, diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 204d5d7..502fefa 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -52,16 +52,6 @@ void cmExtraEclipseCDT4Generator } //---------------------------------------------------------------------------- -void cmExtraEclipseCDT4Generator -::SetGlobalGenerator(cmGlobalGenerator* generator) -{ - cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator); - cmGlobalUnixMakefileGenerator3* mf - = static_cast<cmGlobalUnixMakefileGenerator3*>(generator); - mf->SetToolSupportsColor(true); -} - -//---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator::Generate() { const cmMakefile* mf @@ -73,7 +63,7 @@ void cmExtraEclipseCDT4Generator::Generate() this->IsOutOfSourceBuild = (this->HomeDirectory!=this->HomeOutputDirectory); - this->GenerateSourceProject = (this->IsOutOfSourceBuild && + this->GenerateSourceProject = (this->IsOutOfSourceBuild && mf->IsOn("ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT")); // NOTE: This is not good, since it pollutes the source tree. However, @@ -109,7 +99,7 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() const return; } - fout << + fout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<projectDescription>\n" "\t<name>" << name << "</name>\n" @@ -129,7 +119,7 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() const void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout, const char* envVar, cmMakefile* mf) { - // get the variables from the environment and from the cache and then + // get the variables from the environment and from the cache and then // figure out which one to use: const char* envVarValue = getenv(envVar); @@ -148,7 +138,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout, } else if (envVarValue!=0 && cacheValue==0) { - // The variable is in the env, but not in the cache. Use it and put it + // The variable is in the env, but not in the cache. Use it and put it // in the cache valueToUse = envVarValue; mf->AddCacheDefinition(cacheEntryName.c_str(), valueToUse.c_str(), @@ -206,7 +196,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() compilerId = mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"); } - fout << + fout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<projectDescription>\n" "\t<name>" << @@ -225,7 +215,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() ; // use clean target - fout << + fout << "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>\n" "\t\t\t\t\t<value>clean</value>\n" @@ -246,7 +236,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() // set the make command std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); - fout << + fout << "\t\t\t\t<dictionary>\n" "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>\n" "\t\t\t\t\t<value>true</value>\n" @@ -296,7 +286,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() else if (compilerId == "Intel") { // if the env.var is set, use this one and put it in the cache - // if the env.var is not set, but the value is in the cache, + // if the env.var is not set, but the value is in the cache, // use it from the cache: AddEnvVar(fout, "INTEL_LICENSE_FILE", mf); } @@ -392,9 +382,9 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() { fout << "\t<linkedResources>\n"; // create a linked resource to CMAKE_SOURCE_DIR - // (this is not done anymore for each project because of - // http://public.kitware.com/Bug/view.php?id=9978 and because I found it - // actually quite confusing in bigger projects with many directories and + // (this is not done anymore for each project because of + // http://public.kitware.com/Bug/view.php?id=9978 and because I found it + // actually quite confusing in bigger projects with many directories and // projects, Alex std::string sourceLinkedResourceName = "[Source directory]"; @@ -440,7 +430,7 @@ void cmExtraEclipseCDT4Generator::AppendIncludeDirectories( if(emittedDirs.find(dir) == emittedDirs.end()) { emittedDirs.insert(dir); - fout << "<pathentry include=\"" + fout << "<pathentry include=\"" << cmExtraEclipseCDT4Generator::GetEclipsePath(dir) << "\" kind=\"inc\" path=\"\" system=\"true\"/>\n"; } @@ -452,7 +442,7 @@ void cmExtraEclipseCDT4Generator::AppendIncludeDirectories( void cmExtraEclipseCDT4Generator::CreateCProjectFile() const { std::set<std::string> emmited; - + const cmMakefile* mf = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile(); @@ -465,7 +455,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } // add header - fout << + fout << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" "<?fileVersion 4.0.0?>\n\n" "<cproject>\n" @@ -475,7 +465,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const fout << "<cconfiguration id=\"org.eclipse.cdt.core.default.config.1\">\n"; // Configuration settings... - fout << + fout << "<storageModule" " buildSystemId=\"org.eclipse.cdt.core.defaultConfigDataProvider\"" " id=\"org.eclipse.cdt.core.default.config.1\"" @@ -536,9 +526,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const fout << "</extensions>\n" "</storageModule>\n" ; - + // ??? - fout << + fout << "<storageModule moduleId=\"org.eclipse.cdt.core.language.mapping\">\n" "<project-mappings/>\n" "</storageModule>\n" @@ -619,13 +609,13 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const // we have -DFOO def = *di; } - + // insert the definition if not already added. if(emmited.find(def) == emmited.end()) { emmited.insert(def); fout << "<pathentry kind=\"mac\" name=\"" << def - << "\" path=\"\" value=\"" << this->EscapeForXML(val) + << "\" path=\"\" value=\"" << this->EscapeForXML(val) << "\"/>\n"; } } @@ -712,8 +702,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const = (*it)->GetMakefile()->GetIncludeDirectories(); this->AppendIncludeDirectories(fout, includeDirs, emmited); } - // now also the system include directories, in case we found them in - // CMakeSystemSpecificInformation.cmake. This makes Eclipse find the + // now also the system include directories, in case we found them in + // CMakeSystemSpecificInformation.cmake. This makes Eclipse find the // standard headers. mf->GetDefinition("CMAKE_ECLIPSE_C_SYSTEM_INCLUDE_DIRS"); std::string compiler = mf->GetSafeDefinition("CMAKE_C_COMPILER"); @@ -738,15 +728,17 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const fout << "</storageModule>\n"; // add build targets - fout << + fout << "<storageModule moduleId=\"org.eclipse.cdt.make.core.buildtargets\">\n" "<buildTargets>\n" ; emmited.clear(); const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); + const std::string makeArgs = mf->GetSafeDefinition( + "CMAKE_ECLIPSE_MAKE_ARGUMENTS"); cmGlobalGenerator* generator = const_cast<cmGlobalGenerator*>(this->GlobalGenerator); - + std::string allTarget; std::string cleanTarget; if (generator->GetAllTargetName()) @@ -758,7 +750,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const cleanTarget = generator->GetCleanTargetName(); } - // add all executable and library targets and some of the GLOBAL + // add all executable and library targets and some of the GLOBAL // and UTILITY targets for (std::vector<cmLocalGenerator*>::const_iterator it = this->GlobalGenerator->GetLocalGenerators().begin(); @@ -781,7 +773,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const case cmTarget::GLOBAL_TARGET: { bool insertTarget = false; - // Only add the global targets from CMAKE_BINARY_DIR, + // Only add the global targets from CMAKE_BINARY_DIR, // not from the subdirs if (subdir.empty()) { @@ -804,7 +796,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } if (insertTarget) { - this->AppendTarget(fout, ti->first, make, subdir, ": "); + this->AppendTarget(fout, ti->first, make, makeArgs, subdir, ": "); } } break; @@ -813,13 +805,13 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const // Experimental-"sub"targets as e.g. NightlyStart if (((ti->first.find("Nightly")==0) &&(ti->first!="Nightly")) || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous")) - || ((ti->first.find("Experimental")==0) + || ((ti->first.find("Experimental")==0) && (ti->first!="Experimental"))) { break; } - this->AppendTarget(fout, ti->first, make, subdir, ": "); + this->AppendTarget(fout, ti->first, make, makeArgs, subdir, ": "); break; case cmTarget::EXECUTABLE: case cmTarget::STATIC_LIBRARY: @@ -828,10 +820,10 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const { const char* prefix = (ti->second.GetType()==cmTarget::EXECUTABLE ? "[exe] " : "[lib] "); - this->AppendTarget(fout, ti->first, make, subdir, prefix); + this->AppendTarget(fout, ti->first, make, makeArgs, subdir, prefix); std::string fastTarget = ti->first; fastTarget += "/fast"; - this->AppendTarget(fout, fastTarget, make, subdir, prefix); + this->AppendTarget(fout, fastTarget, make, makeArgs, subdir, prefix); } break; // ignore these: @@ -842,15 +834,15 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const break; } } - + // insert the all and clean targets in every subdir if (!allTarget.empty()) { - this->AppendTarget(fout, allTarget, make, subdir, ": "); + this->AppendTarget(fout, allTarget, make, makeArgs, subdir, ": "); } if (!cleanTarget.empty()) { - this->AppendTarget(fout, cleanTarget, make, subdir, ": "); + this->AppendTarget(fout, cleanTarget, make, makeArgs, subdir, ": "); } //insert rules for compiling, preprocessing and assembling individual files @@ -870,7 +862,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const { prefix = "[pre] "; } - this->AppendTarget(fout, *fit, make, subdir, prefix); + this->AppendTarget(fout, *fit, make, makeArgs, subdir, prefix); } } @@ -955,7 +947,7 @@ std::string cmExtraEclipseCDT4Generator::EscapeForXML(const std::string& value) // Helper functions //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator -::AppendStorageScanners(cmGeneratedFileStream& fout, +::AppendStorageScanners(cmGeneratedFileStream& fout, const cmMakefile& makefile) { // we need the "make" and the C (or C++) compiler which are used, Alex @@ -972,7 +964,7 @@ void cmExtraEclipseCDT4Generator // the following right now hardcodes gcc behaviour :-/ - fout << + fout << "<storageModule moduleId=\"scannerConfiguration\">\n" "<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\"" " selectedProfileId=" @@ -996,24 +988,25 @@ void cmExtraEclipseCDT4Generator // of that is to sort the targets in the view of Eclipse, so that at first // the global/utility/all/clean targets appear ": ", then the executable // targets "[exe] ", then the libraries "[lib]", then the rules for the -// object files "[obj]", then for preprocessing only "[pre] " and -// finally the assembly files "[to asm] ". Note the "to" in "to asm", +// object files "[obj]", then for preprocessing only "[pre] " and +// finally the assembly files "[to asm] ". Note the "to" in "to asm", // without it, "asm" would be the first targets in the list, with the "to" // they are the last targets, which makes more sense. void cmExtraEclipseCDT4Generator::AppendTarget(cmGeneratedFileStream& fout, const std::string& target, const std::string& make, + const std::string& makeArgs, const std::string& path, const char* prefix) { - fout << + fout << "<target name=\"" << prefix << target << "\"" " path=\"" << path.c_str() << "\"" " targetID=\"org.eclipse.cdt.make.MakeTargetBuilder\">\n" "<buildCommand>" << cmExtraEclipseCDT4Generator::GetEclipsePath(make) << "</buildCommand>\n" - "<buildArguments/>\n" + "<buildArguments>" << makeArgs << "</buildArguments>\n" "<buildTarget>" << target << "</buildTarget>\n" "<stopOnError>true</stopOnError>\n" "<useDefaultCommand>false</useDefaultCommand>\n" @@ -1033,7 +1026,7 @@ void cmExtraEclipseCDT4Generator bool runActionUseDefault, bool sipParserEnabled) { - fout << + fout << "<profile id=\"" << profileID << "\">\n" "<buildOutputProvider>\n" "<openAction enabled=\"" << (openActionEnabled ? "true" : "false") diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index 143b7fa..99e69c4 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h @@ -21,8 +21,6 @@ class cmGeneratedFileStream; /** \class cmExtraEclipseCDT4Generator * \brief Write Eclipse project files for Makefile based projects - * - * This generator is in early alpha stage. */ class cmExtraEclipseCDT4Generator : public cmExternalMakefileProjectGenerator { @@ -42,8 +40,6 @@ public: virtual void GetDocumentation(cmDocumentationEntry& entry, const char* fullName) const; - virtual void SetGlobalGenerator(cmGlobalGenerator* generator); - virtual void Generate(); private: @@ -70,11 +66,12 @@ private: static std::string EscapeForXML(const std::string& value); // Helper functions - static void AppendStorageScanners(cmGeneratedFileStream& fout, + static void AppendStorageScanners(cmGeneratedFileStream& fout, const cmMakefile& makefile); static void AppendTarget (cmGeneratedFileStream& fout, const std::string& target, const std::string& make, + const std::string& makeArguments, const std::string& path, const char* prefix = ""); static void AppendScannerProfile (cmGeneratedFileStream& fout, @@ -100,7 +97,7 @@ private: const std::vector<std::string>& includeDirs, std::set<std::string>& emittedDirs); - static void AddEnvVar(cmGeneratedFileStream& fout, const char* envVar, + static void AddEnvVar(cmGeneratedFileStream& fout, const char* envVar, cmMakefile* mf); std::vector<std::string> SrcLinkedResources; diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index e1188d5..d0fe99f 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -13,11 +13,17 @@ cmFindBase::cmFindBase() { - cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, - "FIND_ARGS_XXX", "<VAR> NAMES name"); this->AlreadyInCache = false; this->AlreadyInCacheWithoutMetaInfo = false; - this->GenericDocumentation = +} + +//---------------------------------------------------------------------------- +void cmFindBase::GenerateDocumentation() +{ + this->cmFindCommon::GenerateDocumentation(); + cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, + "FIND_ARGS_XXX", "<VAR> NAMES name"); + this->GenericDocumentation = " FIND_XXX(<VAR> name1 [path1 path2 ...])\n" "This is the short-hand signature for the command that " "is sufficient in many cases. It is the same " @@ -97,7 +103,18 @@ cmFindBase::cmFindBase() this->GenericDocumentation += this->GenericDocumentationRootPath; this->GenericDocumentation += this->GenericDocumentationPathsOrder; } - + +//---------------------------------------------------------------------------- +const char* cmFindBase::GetFullDocumentation() +{ + if(this->GenericDocumentation.empty()) + { + this->GenerateDocumentation(); + } + return this->GenericDocumentation.c_str(); +} + +//---------------------------------------------------------------------------- bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) { if(argsIn.size() < 2 ) @@ -147,6 +164,11 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } } } + if(args.size() < 2 ) + { + this->SetError("called with incorrect number of arguments"); + return false; + } this->VariableName = args[0]; if(this->CheckForVariableInCache()) { diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index 2f1727e..de319b1 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -31,10 +31,10 @@ public: virtual bool ParseArguments(std::vector<std::string> const& args); cmTypeMacro(cmFindBase, cmFindCommon); - virtual const char* GetFullDocumentation() - {return this->GenericDocumentation.c_str();} + virtual const char* GetFullDocumentation(); protected: + virtual void GenerateDocumentation(); void PrintFindStuff(); void ExpandPaths(); void AddPathSuffixes(); diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index b7d3e52..a05e337 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -34,7 +34,11 @@ cmFindCommon::cmFindCommon() this->SearchFrameworkLast = false; this->SearchAppBundleOnly = false; this->SearchAppBundleLast = false; +} +//---------------------------------------------------------------------------- +void cmFindCommon::GenerateDocumentation() +{ // Documentation components. this->GenericDocumentationMacPolicy = "On Darwin or systems supporting OS X Frameworks, the cmake variable" diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index a4866ba..875c223 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -56,6 +56,8 @@ protected: /** Compute the current default bundle/framework search policy. */ void SelectDefaultMacMode(); + virtual void GenerateDocumentation(); + cmStdString CMakePathName; RootPathMode FindRootPathMode; diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx index 897b4bb..fa66fa1 100644 --- a/Source/cmFindFileCommand.cxx +++ b/Source/cmFindFileCommand.cxx @@ -15,11 +15,16 @@ cmFindFileCommand::cmFindFileCommand() { this->IncludeFileInPath = true; +} + +void cmFindFileCommand::GenerateDocumentation() +{ + this->cmFindPathCommand::GenerateDocumentation(); cmSystemTools::ReplaceString(this->GenericDocumentation, "find_path", "find_file"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "directory containing the named file", + "directory containing the named file", "full path to named file"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "file in a directory", "full path to a file"); + "file in a directory", "full path to a file"); } diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h index aa0d25e..dd2e01d 100644 --- a/Source/cmFindFileCommand.h +++ b/Source/cmFindFileCommand.h @@ -44,6 +44,8 @@ public: } cmTypeMacro(cmFindFileCommand, cmFindPathCommand); +protected: + virtual void GenerateDocumentation(); }; diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 9077c8e..b309376 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -16,6 +16,13 @@ cmFindLibraryCommand::cmFindLibraryCommand() { + this->EnvironmentPath = "LIB"; +} + +//---------------------------------------------------------------------------- +void cmFindLibraryCommand::GenerateDocumentation() +{ + this->cmFindBase::GenerateDocumentation(); cmSystemTools::ReplaceString(this->GenericDocumentation, "FIND_XXX", "find_library"); cmSystemTools::ReplaceString(this->GenericDocumentation, @@ -29,7 +36,7 @@ cmFindLibraryCommand::cmFindLibraryCommand() cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SYSTEM", "LIB"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_SYSTEM_XXX_PATH", + "CMAKE_SYSTEM_XXX_PATH", "CMAKE_SYSTEM_LIBRARY_PATH"); cmSystemTools::ReplaceString(this->GenericDocumentation, "SEARCH_XXX_DESC", "library"); @@ -38,11 +45,9 @@ cmFindLibraryCommand::cmFindLibraryCommand() cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SUBDIR", "lib"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_FIND_ROOT_PATH_MODE_XXX", + "CMAKE_FIND_ROOT_PATH_MODE_XXX", "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY"); - - this->EnvironmentPath = "LIB"; - this->GenericDocumentation += + this->GenericDocumentation += "\n" "If the library found is a framework, then VAR will be set to " "the full path to the framework <fullPath>/A.framework. " diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index 486c2cf..7930f52 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -64,6 +64,7 @@ protected: void AddArchitecturePaths(const char* suffix); void AddLib64Paths(); std::string FindLibrary(); + virtual void GenerateDocumentation(); private: std::string FindNormalLibrary(); std::string FindFrameworkLibrary(); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index ef0197a..fdc1a01 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -51,13 +51,6 @@ void cmFindPackageNeedBackwardsCompatibility(const std::string& variable, //---------------------------------------------------------------------------- cmFindPackageCommand::cmFindPackageCommand() { - cmSystemTools::ReplaceString(this->GenericDocumentationRootPath, - "CMAKE_FIND_ROOT_PATH_MODE_XXX", - "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE"); - cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, - "FIND_ARGS_XXX", "<package>"); - cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, - "FIND_XXX", "find_package"); this->CMakePathName = "PACKAGE"; this->Quiet = false; this->Required = false; @@ -78,6 +71,19 @@ cmFindPackageCommand::cmFindPackageCommand() this->VersionFoundPatch = 0; this->VersionFoundTweak = 0; this->VersionFoundCount = 0; +} + +//---------------------------------------------------------------------------- +void cmFindPackageCommand::GenerateDocumentation() +{ + this->cmFindCommon::GenerateDocumentation(); + cmSystemTools::ReplaceString(this->GenericDocumentationRootPath, + "CMAKE_FIND_ROOT_PATH_MODE_XXX", + "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE"); + cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, + "FIND_ARGS_XXX", "<package>"); + cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, + "FIND_XXX", "find_package"); this->CommandDocumentation = " find_package(<package> [version] [EXACT] [QUIET]\n" " [[REQUIRED|COMPONENTS] [components...]]\n" @@ -318,6 +324,10 @@ cmFindPackageCommand::cmFindPackageCommand() //---------------------------------------------------------------------------- const char* cmFindPackageCommand::GetFullDocumentation() { + if(this->CommandDocumentation.empty()) + { + this->GenerateDocumentation(); + } return this->CommandDocumentation.c_str(); } diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 57aeab9..19d2b10 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -65,6 +65,8 @@ public: virtual const char* GetFullDocumentation(); cmTypeMacro(cmFindPackageCommand, cmFindCommon); +protected: + virtual void GenerateDocumentation(); private: void AppendSuccessInformation(); void AppendToProperty(const char* propertyName); diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index cca243a..83b651b 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -18,6 +18,11 @@ cmFindPathCommand::cmFindPathCommand() { this->EnvironmentPath = "INCLUDE"; this->IncludeFileInPath = false; +} + +void cmFindPathCommand::GenerateDocumentation() +{ + this->cmFindBase::GenerateDocumentation(); cmSystemTools::ReplaceString(this->GenericDocumentation, "FIND_XXX", "find_path"); cmSystemTools::ReplaceString(this->GenericDocumentation, @@ -31,27 +36,21 @@ cmFindPathCommand::cmFindPathCommand() cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SYSTEM", "INCLUDE"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_SYSTEM_XXX_PATH", - "CMAKE_SYSTEM_INCLUDE_PATH"); + "CMAKE_SYSTEM_XXX_PATH", + "CMAKE_SYSTEM_INCLUDE_PATH"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "SEARCH_XXX_DESC", + "SEARCH_XXX_DESC", "directory containing the named file"); cmSystemTools::ReplaceString(this->GenericDocumentation, "SEARCH_XXX", "file in a directory"); cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SUBDIR", "include"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_FIND_ROOT_PATH_MODE_XXX", + "CMAKE_FIND_ROOT_PATH_MODE_XXX", "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE"); - - this->ExtraDocAdded = false; -} - -const char* cmFindPathCommand::GetFullDocumentation() -{ - if(!this->ExtraDocAdded && !this->IncludeFileInPath) + if(!this->IncludeFileInPath) { - this->GenericDocumentation += + this->GenericDocumentation += "\n" "When searching for frameworks, if the file is specified as " "A/b.h, then the framework search will look for " @@ -59,9 +58,7 @@ const char* cmFindPathCommand::GetFullDocumentation() "If that is found the path will be set to the path to the framework. " "CMake will convert this to the correct -F option to include the " "file. "; - this->ExtraDocAdded = true; } - return this->GenericDocumentation.c_str(); } // cmFindPathCommand diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h index 3c04343..bd94779 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -59,10 +59,10 @@ public: return "Find the directory containing a file."; } - virtual const char* GetFullDocumentation(); cmTypeMacro(cmFindPathCommand, cmFindBase); bool IncludeFileInPath; - bool ExtraDocAdded; +protected: + virtual void GenerateDocumentation(); private: std::string FindHeaderInFramework(std::string const& file, std::string const& dir); diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 519f862..71cfdcb 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -16,9 +16,10 @@ #if defined(__APPLE__) #include <CoreFoundation/CoreFoundation.h> #endif - -cmFindProgramCommand::cmFindProgramCommand() + +void cmFindProgramCommand::GenerateDocumentation() { + this->cmFindBase::GenerateDocumentation(); cmSystemTools::ReplaceString(this->GenericDocumentation, "FIND_XXX", "find_program"); cmSystemTools::ReplaceString(this->GenericDocumentation, @@ -32,8 +33,8 @@ cmFindProgramCommand::cmFindProgramCommand() cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SYSTEM", ""); cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_SYSTEM_XXX_PATH", - "CMAKE_SYSTEM_PROGRAM_PATH"); + "CMAKE_SYSTEM_XXX_PATH", + "CMAKE_SYSTEM_PROGRAM_PATH"); cmSystemTools::ReplaceString(this->GenericDocumentation, "SEARCH_XXX_DESC", "program"); cmSystemTools::ReplaceString(this->GenericDocumentation, @@ -41,7 +42,7 @@ cmFindProgramCommand::cmFindProgramCommand() cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SUBDIR", "[s]bin"); cmSystemTools::ReplaceString(this->GenericDocumentation, - "CMAKE_FIND_ROOT_PATH_MODE_XXX", + "CMAKE_FIND_ROOT_PATH_MODE_XXX", "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM"); } diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h index ae790a3..654e834 100644 --- a/Source/cmFindProgramCommand.h +++ b/Source/cmFindProgramCommand.h @@ -25,7 +25,6 @@ class cmFindProgramCommand : public cmFindBase { public: - cmFindProgramCommand(); /** * This is a virtual constructor for the command. */ @@ -63,6 +62,7 @@ public: protected: std::string FindProgram(std::vector<std::string> names); + virtual void GenerateDocumentation(); private: std::string FindAppBundle(std::vector<std::string> names); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 789d0e7..2ae1c93 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -699,9 +699,8 @@ bool cmGlobalGenerator::IsDependedOn(const char* project, l != targets.end(); l++) { cmTarget& target = l->second; - std::set<cmStdString>::const_iterator pos = - target.GetUtilities().find(targetIn->GetName()); - if(pos != target.GetUtilities().end()) + TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target); + if(tgtdeps.count(targetIn)) { return true; } @@ -815,24 +814,11 @@ void cmGlobalGenerator::Generate() // For each existing cmLocalGenerator unsigned int i; - // Consolidate global targets + // Put a copy of each global target in every directory. cmTargets globalTargets; this->CreateDefaultGlobalTargets(&globalTargets); for (i = 0; i < this->LocalGenerators.size(); ++i) { - cmTargets* targets = - &(this->LocalGenerators[i]->GetMakefile()->GetTargets()); - cmTargets::iterator tarIt; - for ( tarIt = targets->begin(); tarIt != targets->end(); ++ tarIt ) - { - if ( tarIt->second.GetType() == cmTarget::GLOBAL_TARGET ) - { - globalTargets[tarIt->first] = tarIt->second; - } - } - } - for (i = 0; i < this->LocalGenerators.size(); ++i) - { cmMakefile* mf = this->LocalGenerators[i]->GetMakefile(); cmTargets* targets = &(mf->GetTargets()); cmTargets::iterator tit; @@ -1884,8 +1870,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( const char* name, const char* message, const cmCustomCommandLines* commandLines, std::vector<std::string> depends, - const char* workingDirectory, - bool depends_on_all /* = false */) + const char* workingDirectory) { // Package cmTarget target; @@ -1900,10 +1885,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( workingDirectory); target.GetPostBuildCommands().push_back(cc); target.SetProperty("EchoString", message); - if ( depends_on_all ) - { - target.AddUtility("all"); - } std::vector<std::string>::iterator dit; for ( dit = depends.begin(); dit != depends.end(); ++ dit ) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 2aec19f..6a1aa53 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -16,6 +16,7 @@ #include "cmStandardIncludes.h" #include "cmTarget.h" // For cmTargets +#include "cmTargetDepend.h" // For cmTargetDependSet class cmake; class cmMakefile; @@ -38,31 +39,31 @@ public: ///! Free any memory allocated with the GlobalGenerator cmGlobalGenerator(); virtual ~cmGlobalGenerator(); - + ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); ///! Get the name for this generator virtual const char *GetName() const { return "Generic"; }; - + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + /** * Create LocalGenerators and process the CMakeLists files. This does not - * actually produce any makefiles, DSPs, etc. + * actually produce any makefiles, DSPs, etc. */ virtual void Configure(); /** * 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(); /** - * Set/Get and Clear the enabled languages. + * Set/Get and Clear the enabled languages. */ void SetLanguageEnabled(const char*, cmMakefile* mf); bool GetLanguageEnabled(const char*) const; @@ -70,7 +71,7 @@ public: void GetEnabledLanguages(std::vector<std::string>& lang); /** * 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); @@ -88,7 +89,7 @@ public: const char *projectName, const char *targetName, bool fast, std::string *output, cmMakefile* mf); - + /** * Build a file given the following information. This is a more direct call * that is used by both CTest and TryCompile. If target name is NULL or @@ -104,28 +105,28 @@ public: const char* extraOptions = 0, std::vector<std::string> const& nativeOptions = std::vector<std::string>()); - + virtual std::string GenerateBuildCommand( const char* makeProgram, - const char *projectName, const char* additionalOptions, + const char *projectName, const char* additionalOptions, const char *targetName, const char* config, bool ignoreErrors, bool fast); - + ///! Set the CMake instance void SetCMakeInstance(cmake *cm); - + ///! Get the CMake instance cmake *GetCMakeInstance() { return this->CMakeInstance; }; void SetConfiguredFilesPath(cmGlobalGenerator* gen); - const std::vector<cmLocalGenerator *>& GetLocalGenerators() const { + const std::vector<cmLocalGenerator *>& GetLocalGenerators() const { return this->LocalGenerators;} - cmLocalGenerator* GetCurrentLocalGenerator() + cmLocalGenerator* GetCurrentLocalGenerator() {return this->CurrentLocalGenerator;} - void SetCurrentLocalGenerator(cmLocalGenerator* lg) + void SetCurrentLocalGenerator(cmLocalGenerator* lg) {this->CurrentLocalGenerator = lg;} void AddLocalGenerator(cmLocalGenerator *lg); @@ -138,11 +139,11 @@ public: void AddInstallComponent(const char* component); - const std::set<cmStdString>* GetInstallComponents() const + 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, + void AddTargetToExports(const char* exportSet, cmTarget* target, cmInstallTargetGenerator* archive, cmInstallTargetGenerator* runTime, cmInstallTargetGenerator* library, @@ -158,10 +159,9 @@ public: void EnableInstallTarget(); int TryCompileTimeout; - + bool GetForceUnixPaths() {return this->ForceUnixPaths;} bool GetToolSupportsColor() { return this->ToolSupportsColor; } - void SetToolSupportsColor(bool enable) { this->ToolSupportsColor = enable; } ///! return the language for the given extension const char* GetLanguageFromExtension(const char* ext); @@ -234,7 +234,7 @@ public: virtual const char* GetCleanTargetName() { return 0; } // Class to track a set of dependencies. - class TargetDependSet: public std::set<cmTarget*> {}; + typedef cmTargetDependSet TargetDependSet; // what targets does the specified target depend on directly // via a target_link_libraries or add_dependencies @@ -254,7 +254,7 @@ public: bool BinaryDirectoryIsNew(const char* dir) { return this->BinaryDirectories.insert(dir).second; - } + } /** Supported systems creates a GUID for the given name */ virtual void CreateGUID(const char*) {} @@ -281,7 +281,7 @@ protected: bool CheckTargets(); - // Fill the ProjectMap, this must be called after LocalGenerators + // Fill the ProjectMap, this must be called after LocalGenerators // has been populated. void FillProjectMap(); void CheckLocalGenerators(); @@ -291,8 +291,7 @@ protected: void CreateDefaultGlobalTargets(cmTargets* targets); cmTarget CreateGlobalTarget(const char* name, const char* message, const cmCustomCommandLines* commandLines, - std::vector<std::string> depends, const char* workingDir, - bool depends_on_all = false); + std::vector<std::string> depends, const char* workingDir); bool NeedSymbolicMark; bool UseLinkScript; @@ -328,13 +327,13 @@ protected: private: float FirstTimeProgress; // If you add a new map here, make sure it is copied - // in EnableLanguagesFromGenerator + // in EnableLanguagesFromGenerator std::map<cmStdString, bool> IgnoreExtensions; std::map<cmStdString, bool> LanguageEnabled; std::map<cmStdString, cmStdString> OutputExtensions; std::map<cmStdString, cmStdString> LanguageToOutputExtension; std::map<cmStdString, cmStdString> ExtensionToLanguage; - std::map<cmStdString, int> LanguageToLinkerPreference; + std::map<cmStdString, int> LanguageToLinkerPreference; // Record hashes for rules and outputs. struct RuleHash { char Data[32]; }; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 4e8e7e6..d9a341c 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -24,7 +24,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() this->ForceUnixPaths = true; this->FindMakeProgramFile = "CMakeUnixFindMake.cmake"; this->ToolSupportsColor = true; - this->ForceVerboseMakefiles = false; + this->NoRuleMessages = false; #if defined(_WIN32) || defined(__VMS) this->UseLinkScript = false; @@ -34,8 +34,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() } void cmGlobalUnixMakefileGenerator3 -::EnableLanguage(std::vector<std::string>const& languages, - cmMakefile *mf, +::EnableLanguage(std::vector<std::string>const& languages, + cmMakefile *mf, bool optional) { this->cmGlobalGenerator::EnableLanguage(languages, mf, optional); @@ -51,17 +51,17 @@ void cmGlobalUnixMakefileGenerator3 std::string langComp = "CMAKE_"; langComp += lang; langComp += "_COMPILER"; - + if(!mf->GetDefinition(langComp.c_str())) { if(!optional) { - cmSystemTools::Error(langComp.c_str(), + cmSystemTools::Error(langComp.c_str(), " not set, after EnableLanguage"); } continue; } - const char* name = mf->GetRequiredDefinition(langComp.c_str()); + const char* name = mf->GetRequiredDefinition(langComp.c_str()); if(!cmSystemTools::FileIsFullPath(name)) { path = cmSystemTools::FindProgram(name); @@ -70,7 +70,7 @@ void cmGlobalUnixMakefileGenerator3 { path = name; } - if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str())) + if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str())) && (optional==false)) { std::string message = "your "; @@ -96,8 +96,8 @@ void cmGlobalUnixMakefileGenerator3 cmSystemTools::ConvertToUnixSlashes(cnameString); cmSystemTools::ConvertToUnixSlashes(pathString); if (cnameString != pathString) - { - const char* cvars = + { + const char* cvars = this->GetCMakeInstance()->GetProperty( "__CMAKE_DELETE_CACHE_CHANGE_VARS_"); if(cvars) @@ -139,44 +139,53 @@ void cmGlobalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- -void cmGlobalUnixMakefileGenerator3::Generate() +void cmGlobalUnixMakefileGenerator3::Generate() { // first do superclass method this->cmGlobalGenerator::Generate(); - // initialize progress - unsigned long total = 0; - for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin(); - pmi != this->ProgressMap.end(); ++pmi) + cmake* cm = this->GetCMakeInstance(); + if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES")) { - total += pmi->second.NumberOfActions; + this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); } - // write each target's progress.make this loop is done twice. Bascially the - // Generate pass counts all the actions, the first loop below determines - // how many actions have progress updates for each target and writes to - // corrrect variable values for everything except the all targets. The - // second loop actually writes out correct values for the all targets as - // well. This is because the all targets require more information that is - // computed in the first loop. - unsigned long current = 0; - for(ProgressMapType::iterator pmi = this->ProgressMap.begin(); - pmi != this->ProgressMap.end(); ++pmi) + if(!this->NoRuleMessages) { - pmi->second.WriteProgressVariables(total, current); - } - for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i) - { - cmLocalUnixMakefileGenerator3 *lg = - static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); - std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory(); - markFileName += "/"; - markFileName += cmake::GetCMakeFilesDirectory(); - markFileName += "/progress.marks"; - cmGeneratedFileStream markFile(markFileName.c_str()); - markFile << this->CountProgressMarksInAll(lg) << "\n"; + // initialize progress + unsigned long total = 0; + for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin(); + pmi != this->ProgressMap.end(); ++pmi) + { + total += pmi->second.NumberOfActions; + } + + // write each target's progress.make this loop is done twice. Bascially the + // Generate pass counts all the actions, the first loop below determines + // how many actions have progress updates for each target and writes to + // corrrect variable values for everything except the all targets. The + // second loop actually writes out correct values for the all targets as + // well. This is because the all targets require more information that is + // computed in the first loop. + unsigned long current = 0; + for(ProgressMapType::iterator pmi = this->ProgressMap.begin(); + pmi != this->ProgressMap.end(); ++pmi) + { + pmi->second.WriteProgressVariables(total, current); + } + for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i) + { + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); + std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory(); + markFileName += "/"; + markFileName += cmake::GetCMakeFilesDirectory(); + markFileName += "/progress.marks"; + cmGeneratedFileStream markFile(markFileName.c_str()); + markFile << this->CountProgressMarksInAll(lg) << "\n"; + } } - + // write the main makefile this->WriteMainMakefile2(); this->WriteMainCMakefile(); @@ -187,7 +196,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() // Open the output file. This should not be copy-if-different // because the check-build-system step compares the makefile time to // see if the build system must be regenerated. - std::string makefileName = + std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); makefileName += cmake::GetCMakeFilesDirectory(); makefileName += "/Makefile2"; @@ -196,11 +205,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() { return; } - + // get a local generator for some useful methods - cmLocalUnixMakefileGenerator3 *lg = + cmLocalUnixMakefileGenerator3 *lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]); - + // Write the do not edit header. lg->WriteDisclaimer(makefileStream); @@ -229,8 +238,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() } // Write and empty all: - lg->WriteMakeRule(makefileStream, - "The main recursive all target", "all", + lg->WriteMakeRule(makefileStream, + "The main recursive all target", "all", depends, no_commands, true); // Write an empty preinstall: @@ -240,12 +249,12 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() // Write out the "special" stuff lg->WriteSpecialTargetsTop(makefileStream); - + // write the target convenience rules unsigned int i; for (i = 0; i < this->LocalGenerators.size(); ++i) { - lg = + lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); this->WriteConvenienceRules2(makefileStream,lg); } @@ -261,7 +270,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // Open the output file. This should not be copy-if-different // because the check-build-system step compares the makefile time to // see if the build system must be regenerated. - std::string cmakefileName = + std::string cmakefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); cmakefileName += cmake::GetCMakeFilesDirectory(); cmakefileName += "/Makefile.cmake"; @@ -271,14 +280,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() return; } - std::string makefileName = + std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); makefileName += "/Makefile"; - + // get a local generator for some useful methods - cmLocalUnixMakefileGenerator3 *lg = + cmLocalUnixMakefileGenerator3 *lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]); - + // Write the do not edit header. lg->WriteDisclaimer(cmakefileStream); @@ -291,9 +300,9 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() std::vector<std::string> lfiles; for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { - lg = + lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); - + // Get the list of files contributing to this generation step. lfiles.insert(lfiles.end(),lg->GetMakefile()->GetListFiles().begin(), lg->GetMakefile()->GetListFiles().end()); @@ -301,7 +310,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // Sort the list and remove duplicates. std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>()); #if !defined(__VMS) // The Compaq STL on VMS crashes, so accept duplicates. - std::vector<std::string>::iterator new_end = + std::vector<std::string>::iterator new_end = std::unique(lfiles.begin(),lfiles.end()); lfiles.erase(new_end, lfiles.end()); #endif @@ -317,14 +326,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() cmakefileStream << "# The top level Makefile was generated from the following files:\n" << "SET(CMAKE_MAKEFILE_DEPENDS\n" - << " \"" + << " \"" << lg->Convert(cache.c_str(), cmLocalGenerator::START_OUTPUT).c_str() << "\"\n"; for(std::vector<std::string>::const_iterator i = lfiles.begin(); i != lfiles.end(); ++i) { cmakefileStream - << " \"" + << " \"" << lg->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT).c_str() << "\"\n"; } @@ -340,10 +349,10 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() cmakefileStream << "# The corresponding makefile is:\n" << "SET(CMAKE_MAKEFILE_OUTPUTS\n" - << " \"" + << " \"" << lg->Convert(makefileName.c_str(), cmLocalGenerator::START_OUTPUT).c_str() << "\"\n" - << " \"" + << " \"" << lg->Convert(check.c_str(), cmLocalGenerator::START_OUTPUT).c_str() << "\"\n"; cmakefileStream << " )\n\n"; @@ -367,19 +376,19 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() std::string tmpStr; for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { - lg = + lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); tmpStr = lg->GetMakefile()->GetStartOutputDirectory(); tmpStr += cmake::GetCMakeFilesDirectory(); tmpStr += "/CMakeDirectoryInformation.cmake"; - cmakefileStream << " \"" << - lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() + cmakefileStream << " \"" << + lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() << "\"\n"; } cmakefileStream << " )\n\n"; } - this->WriteMainCMakefileLanguageRules(cmakefileStream, + this->WriteMainCMakefileLanguageRules(cmakefileStream, this->LocalGenerators); } @@ -458,7 +467,7 @@ cmGlobalUnixMakefileGenerator3 // The directory-level rule should depend on the directory-level // rules of the subdirectories. - for(std::vector<cmLocalGenerator*>::iterator sdi = + for(std::vector<cmLocalGenerator*>::iterator sdi = lg->GetChildren().begin(); sdi != lg->GetChildren().end(); ++sdi) { cmLocalUnixMakefileGenerator3* slg = @@ -518,7 +527,7 @@ cmGlobalUnixMakefileGenerator3 std::string cmGlobalUnixMakefileGenerator3 -::GenerateBuildCommand(const char* makeProgram, const char *projectName, +::GenerateBuildCommand(const char* makeProgram, const char *projectName, const char* additionalOptions, const char *targetName, const char* config, bool ignoreErrors, bool fast) { @@ -526,9 +535,9 @@ std::string cmGlobalUnixMakefileGenerator3 (void)projectName; (void)config; - std::string makeCommand = + std::string makeCommand = cmSystemTools::ConvertToUnixOutputPath(makeProgram); - + // Since we have full control over the invocation of nmake, let us // make it quiet. if ( strcmp(this->GetName(), "NMake Makefiles") == 0 ) @@ -563,7 +572,7 @@ std::string cmGlobalUnixMakefileGenerator3 (this->CMakeInstance->GetStartOutputDirectory()); lg->GetMakefile()->MakeStartDirectoriesCurrent(); } - + makeCommand += " \""; std::string tname = targetName; if(fast) @@ -585,14 +594,14 @@ std::string cmGlobalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3 -::WriteConvenienceRules(std::ostream& ruleFileStream, +::WriteConvenienceRules(std::ostream& ruleFileStream, std::set<cmStdString> &emitted) { - std::vector<std::string> depends; + std::vector<std::string> depends; std::vector<std::string> commands; depends.push_back("cmake_check_build_system"); - + // write the target convenience rules unsigned int i; cmLocalUnixMakefileGenerator3 *lg; @@ -622,7 +631,7 @@ cmGlobalUnixMakefileGenerator3 ruleFileStream << "# Target rules for targets named " << t->second.GetName() << "\n\n"; - + // Write the rule. commands.clear(); std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); @@ -631,16 +640,16 @@ cmGlobalUnixMakefileGenerator3 (tmp.c_str(),t->second.GetName())); depends.clear(); depends.push_back("cmake_check_build_system"); - lg->WriteMakeRule(ruleFileStream, + lg->WriteMakeRule(ruleFileStream, "Build rule for target.", t->second.GetName(), depends, commands, true); - + // Add a fast rule to build the target std::string localName = lg->GetRelativeTargetDirectory(t->second); std::string makefileName; makefileName = localName; - makefileName += "/build.make"; + makefileName += "/build.make"; depends.clear(); commands.clear(); std::string makeTargetName = localName; @@ -677,10 +686,10 @@ cmGlobalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3 -::WriteConvenienceRules2(std::ostream& ruleFileStream, +::WriteConvenienceRules2(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *lg) { - std::vector<std::string> depends; + std::vector<std::string> depends; std::vector<std::string> commands; std::string localName; std::string makeTargetName; @@ -688,7 +697,7 @@ cmGlobalUnixMakefileGenerator3 // write the directory level rules for this local gen this->WriteDirectoryRules2(ruleFileStream,lg); - + depends.push_back("cmake_check_build_system"); // for each target Generate the rule files for each target. @@ -708,15 +717,15 @@ cmGlobalUnixMakefileGenerator3 localName = lg->GetRelativeTargetDirectory(t->second); makefileName = localName; makefileName += "/build.make"; - + bool needRequiresStep = this->NeedRequiresStep(t->second); - + lg->WriteDivider(ruleFileStream); ruleFileStream << "# Target rules for target " << localName << "\n\n"; - - commands.clear(); + + commands.clear(); makeTargetName = localName; makeTargetName += "/depend"; commands.push_back(lg->GetRecursiveMakeCall @@ -734,39 +743,43 @@ cmGlobalUnixMakefileGenerator3 makeTargetName += "/build"; commands.push_back(lg->GetRecursiveMakeCall (makefileName.c_str(),makeTargetName.c_str())); - + // Write the rule. localName += "/all"; depends.clear(); + std::string progressDir; - std::string progressDir = - lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); + if(!this->NoRuleMessages) { - cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; - // all target counts - progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " "; - std::vector<unsigned long>& progFiles = - this->ProgressMap[&t->second].Marks; - for (std::vector<unsigned long>::iterator i = progFiles.begin(); - i != progFiles.end(); ++i) + progressDir = + lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); { - progCmd << " " << *i; + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + // all target counts + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " "; + std::vector<unsigned long>& progFiles = + this->ProgressMap[&t->second].Marks; + for (std::vector<unsigned long>::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) + { + progCmd << " " << *i; + } + commands.push_back(progCmd.str()); } - commands.push_back(progCmd.str()); + progressDir = "Built target "; + progressDir += t->first; + lg->AppendEcho(commands,progressDir.c_str()); } - progressDir = "Built target "; - progressDir += t->first; - lg->AppendEcho(commands,progressDir.c_str()); - + this->AppendGlobalTargetDepends(depends,t->second); lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", localName.c_str(), depends, commands, true); - + // add the all/all dependency if(!this->IsExcluded(this->LocalGenerators[0], t->second)) { @@ -776,54 +789,58 @@ cmGlobalUnixMakefileGenerator3 lg->WriteMakeRule(ruleFileStream, "Include target in all.", "all", depends, commands, true); } - - // Write the rule. - commands.clear(); - progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); - - { - // TODO: Convert the total progress count to a make variable. - cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; - // # in target - progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - // - std::set<cmTarget *> emitted; - progCmd << " " - << this->CountProgressMarksInTarget(&t->second, emitted); - commands.push_back(progCmd.str()); - } + + if(!this->NoRuleMessages) + { + // Write the rule. + commands.clear(); + progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + + { + // TODO: Convert the total progress count to a make variable. + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; + // # in target + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + // + std::set<cmTarget *> emitted; + progCmd << " " + << this->CountProgressMarksInTarget(&t->second, emitted); + commands.push_back(progCmd.str()); + } + } std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); tmp += "Makefile2"; commands.push_back(lg->GetRecursiveMakeCall (tmp.c_str(),localName.c_str())); - { - cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 - progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " 0"; - commands.push_back(progCmd.str()); - } + if(!this->NoRuleMessages) + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " 0"; + commands.push_back(progCmd.str()); + } depends.clear(); depends.push_back("cmake_check_build_system"); localName = lg->GetRelativeTargetDirectory(t->second); localName += "/rule"; - lg->WriteMakeRule(ruleFileStream, + lg->WriteMakeRule(ruleFileStream, "Build rule for subdir invocation for target.", localName.c_str(), depends, commands, true); - + // Add a target with the canonical name (no prefix, suffix or path). commands.clear(); depends.clear(); depends.push_back(localName); lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", t->second.GetName(), depends, commands, true); - + // Add rules to prepare the target for installation. if(t->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str())) { @@ -833,7 +850,7 @@ cmGlobalUnixMakefileGenerator3 commands.clear(); commands.push_back(lg->GetRecursiveMakeCall (makefileName.c_str(), localName.c_str())); - lg->WriteMakeRule(ruleFileStream, + lg->WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.", localName.c_str(), depends, commands, true); @@ -846,7 +863,7 @@ cmGlobalUnixMakefileGenerator3 "preinstall", depends, commands, true); } } - + // add the clean rule localName = lg->GetRelativeTargetDirectory(t->second); makeTargetName = localName; @@ -987,7 +1004,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule lg->AppendEcho(commands,"... all (the default if no target is provided)"); lg->AppendEcho(commands,"... clean"); lg->AppendEcho(commands,"... depend"); - + // Keep track of targets already listed. std::set<cmStdString> emittedTargets; @@ -996,7 +1013,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule cmLocalUnixMakefileGenerator3 *lg2; for (i = 0; i < this->LocalGenerators.size(); ++i) { - lg2 = + lg2 = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); // for the passed in makefile or if this is the top Makefile wripte out // the targets diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index f499536..cdc9460 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -22,19 +22,19 @@ class cmLocalUnixMakefileGenerator3; * \brief Write a Unix makefiles. * * cmGlobalUnixMakefileGenerator3 manages UNIX build process for a tree - - + + The basic approach of this generator is to produce Makefiles that will all be run with the current working directory set to the Home Output directory. The one exception to this is the subdirectory Makefiles which are created as a convenience and just cd up to the Home Output directory and - invoke the main Makefiles. - + invoke the main Makefiles. + The make process starts with Makefile. Makefile should only contain the targets the user is likely to invoke directly from a make command line. No internal targets should be in this file. Makefile2 contains the internal targets that are required to make the process work. - + Makefile2 in turn will recursively make targets in the correct order. Each target has its own directory <target>.dir and its own makefile build.make in that directory. Also in that directory is a couple makefiles per source file @@ -47,7 +47,7 @@ class cmLocalUnixMakefileGenerator3; rescanned. Rules for custom commands follow the same model as rules for source files. - + */ class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator @@ -64,13 +64,13 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - + ///! Create a local generator appropriate to this Global Generator3 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); @@ -78,11 +78,11 @@ 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(); - - + + void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream, std::vector<cmLocalGenerator *> &); @@ -91,7 +91,7 @@ public: cmLocalUnixMakefileGenerator3 *); // write the top lvel target rules - void WriteConvenienceRules(std::ostream& ruleFileStream, + void WriteConvenienceRules(std::ostream& ruleFileStream, std::set<cmStdString> &emitted); /** Get the command to use for a target that has no rule. This is @@ -105,23 +105,13 @@ public: // change the build command for speed virtual std::string GenerateBuildCommand (const char* makeProgram, - const char *projectName, const char* additionalOptions, + const char *projectName, const char* additionalOptions, const char *targetName, const char* config, bool ignoreErrors, bool fast); /** Record per-target progress information. */ void RecordTargetProgress(cmMakefileTargetGenerator* tg); - /** - * If true, the CMake variable CMAKE_VERBOSE_MAKEFILES doesn't have effect - * anymore. Set it to true when writing a generator where short output - * doesn't make sense, e.g. because the full output is parsed by an - * IDE/editor. - */ - bool GetForceVerboseMakefiles() { return this->ForceVerboseMakefiles; } - void SetForceVerboseMakefiles(bool enable) - {this->ForceVerboseMakefiles=enable;} - protected: void WriteMainMakefile2(); void WriteMainCMakefile(); @@ -169,7 +159,7 @@ protected: // in the rule to satisfy the make program. std::string EmptyRuleHackCommand; - bool ForceVerboseMakefiles; + bool NoRuleMessages; // Store per-target progress counters. struct TargetProgress diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 403507f..0b939af 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -19,6 +19,10 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator() { this->FindMakeProgramFile = "CMakeVS10FindMake.cmake"; + std::string vc10Express; + this->ExpressEdition = cmSystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0\\Setup\\VC;" + "ProductDir", vc10Express, cmSystemTools::KeyWOW64_32); } //---------------------------------------------------------------------------- @@ -63,6 +67,16 @@ void cmGlobalVisualStudio10Generator } //---------------------------------------------------------------------------- +const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() +{ + if(!this->PlatformToolset.empty()) + { + return this->PlatformToolset.c_str(); + } + return 0; +} + +//---------------------------------------------------------------------------- std::string cmGlobalVisualStudio10Generator::GetUserMacrosDirectory() { std::string base; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 219c36e..bef5642 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -54,6 +54,12 @@ public: cmMakefile *, bool optional); virtual void WriteSLNHeader(std::ostream& fout); + /** Is the installed VS an Express edition? */ + bool IsExpressEdition() const { return this->ExpressEdition; } + + /** The toolset name for the target platform. */ + const char* GetPlatformToolset(); + /** * Where does this version of Visual Studio look for macros for the * current user? Returns the empty string if this version of Visual @@ -70,5 +76,9 @@ public: { return "$(Configuration)";} protected: virtual const char* GetIDEVersion() { return "10.0"; } + + std::string PlatformToolset; +private: + bool ExpressEdition; }; #endif diff --git a/Source/cmGlobalVisualStudio10Win64Generator.cxx b/Source/cmGlobalVisualStudio10Win64Generator.cxx index 109b60d..8600777 100644 --- a/Source/cmGlobalVisualStudio10Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio10Win64Generator.cxx @@ -36,3 +36,52 @@ void cmGlobalVisualStudio10Win64Generator mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64"); mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64"); } + +//---------------------------------------------------------------------------- +bool cmGlobalVisualStudio10Win64Generator::Find64BitTools(cmMakefile* mf) +{ + if(!this->PlatformToolset.empty()) + { + return true; + } + // This edition does not come with 64-bit tools. Look for them. + // + // TODO: Detect available tools? x64\v100 exists but does not work? + // KHLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\4.0;VCTargetsPath + // c:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/Platforms/ + // {Itanium,Win32,x64}/PlatformToolsets/{v100,v90,Windows7.1SDK} + std::string winSDK_7_1; + if(cmSystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\" + "Windows\\v7.1;InstallationFolder", winSDK_7_1)) + { + cmOStringStream m; + m << "Found Windows SDK v7.1: " << winSDK_7_1; + mf->DisplayStatus(m.str().c_str(), -1); + this->PlatformToolset = "Windows7.1SDK"; + return true; + } + else + { + cmOStringStream e; + e << "Cannot enable 64-bit tools with Visual Studio 2010 Express.\n" + << "Install the Microsoft Windows SDK v7.1 to get 64-bit tools:\n" + << " http://msdn.microsoft.com/en-us/windows/bb980924.aspx"; + mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } +} + +//---------------------------------------------------------------------------- +void cmGlobalVisualStudio10Win64Generator +::EnableLanguage(std::vector<std::string> const& languages, + cmMakefile* mf, bool optional) +{ + if(this->IsExpressEdition() && !this->Find64BitTools(mf)) + { + return; + } + this->cmGlobalVisualStudio10Generator + ::EnableLanguage(languages, mf, optional); +} diff --git a/Source/cmGlobalVisualStudio10Win64Generator.h b/Source/cmGlobalVisualStudio10Win64Generator.h index 39c9d08..e6d3dc5 100644 --- a/Source/cmGlobalVisualStudio10Win64Generator.h +++ b/Source/cmGlobalVisualStudio10Win64Generator.h @@ -34,5 +34,8 @@ public: virtual void AddPlatformDefinitions(cmMakefile* mf); + bool Find64BitTools(cmMakefile* mf); + virtual void EnableLanguage(std::vector<std::string>const& languages, + cmMakefile *, bool optional); }; #endif diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 203ca77..fe44e20 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -197,8 +197,6 @@ void cmGlobalVisualStudio6Generator this->GetTargetSets(projectTargets, originalTargets, root, generators); OrderedTargetDependSet orderedProjectTargets(projectTargets); - std::string rootdir = root->GetMakefile()->GetStartOutputDirectory(); - rootdir += "/"; for(OrderedTargetDependSet::const_iterator tt = orderedProjectTargets.begin(); tt != orderedProjectTargets.end(); ++tt) diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index ba18687..2874952 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -110,7 +110,7 @@ void cmGlobalVisualStudio71Generator this->GetTargetSets(projectTargets, originalTargets, root, generators); OrderedTargetDependSet orderedProjectTargets(projectTargets); - this->WriteTargetsToSolution(fout, root, orderedProjectTargets); + this->WriteTargetsToSolution(fout, orderedProjectTargets); bool useFolderProperty = this->UseFolderProperty(); if (useFolderProperty) diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 2b9e5ba..eb84a2c 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -270,15 +270,14 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( std::ostream& fout, - cmLocalGenerator* root, OrderedTargetDependSet const& projectTargets) { - std::string rootdir = root->GetMakefile()->GetStartOutputDirectory(); - rootdir += "/"; for(OrderedTargetDependSet::const_iterator tt = projectTargets.begin(); tt != projectTargets.end(); ++tt) { cmTarget* target = *tt; + bool written = false; + // handle external vc project files const char* expath = target->GetProperty("EXTERNAL_MSPROJECT"); if(expath) @@ -287,6 +286,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( std::string location = expath; this->WriteExternalProject(fout, project.c_str(), location.c_str(), target->GetUtilities()); + written = true; } else { @@ -296,51 +296,50 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( { cmMakefile* tmf = target->GetMakefile(); std::string dir = tmf->GetStartOutputDirectory(); - dir = root->Convert(dir.c_str(), - cmLocalGenerator::START_OUTPUT); this->WriteProject(fout, vcprojName, dir.c_str(), *target); + written = true; + } + } - // Create "solution folder" information from FOLDER target property - // - if (this->UseFolderProperty()) + // Create "solution folder" information from FOLDER target property + // + if (written && this->UseFolderProperty()) + { + const char *targetFolder = target->GetProperty("FOLDER"); + if (targetFolder) + { + std::vector<cmsys::String> tokens = + cmSystemTools::SplitString(targetFolder, '/', false); + + std::string cumulativePath = ""; + + for(std::vector<cmsys::String>::iterator iter = tokens.begin(); + iter != tokens.end(); ++iter) { - const char *targetFolder = target->GetProperty("FOLDER"); - if (targetFolder) + if(!iter->size()) { - std::vector<cmsys::String> tokens = - cmSystemTools::SplitString(targetFolder, '/', false); - - std::string cumulativePath = ""; - - for(std::vector<cmsys::String>::iterator iter = tokens.begin(); - iter != tokens.end(); ++iter) - { - if(!iter->size()) - { - continue; - } - - if (cumulativePath.empty()) - { - cumulativePath = "CMAKE_FOLDER_GUID_" + *iter; - } - else - { - VisualStudioFolders[cumulativePath].insert( - cumulativePath + "/" + *iter); - - cumulativePath = cumulativePath + "/" + *iter; - } - - this->CreateGUID(cumulativePath.c_str()); - } - - if (!cumulativePath.empty()) - { - VisualStudioFolders[cumulativePath].insert(target->GetName()); - } + continue; } + + if (cumulativePath.empty()) + { + cumulativePath = "CMAKE_FOLDER_GUID_" + *iter; + } + else + { + VisualStudioFolders[cumulativePath].insert( + cumulativePath + "/" + *iter); + + cumulativePath = cumulativePath + "/" + *iter; + } + + this->CreateGUID(cumulativePath.c_str()); + } + + if (!cumulativePath.empty()) + { + VisualStudioFolders[cumulativePath].insert(target->GetName()); } } } @@ -386,7 +385,7 @@ void cmGlobalVisualStudio7Generator this->GetTargetSets(projectTargets, originalTargets, root, generators); OrderedTargetDependSet orderedProjectTargets(projectTargets); - this->WriteTargetsToSolution(fout, root, orderedProjectTargets); + this->WriteTargetsToSolution(fout, orderedProjectTargets); bool useFolderProperty = this->UseFolderProperty(); if (useFolderProperty) diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index b6c84e8..57c079d 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -118,7 +118,6 @@ protected: virtual void WriteTargetsToSolution( std::ostream& fout, - cmLocalGenerator* root, OrderedTargetDependSet const& projectTargets); virtual void WriteTargetDepends( std::ostream& fout, diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 7c65c32..2d080df 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -289,6 +289,28 @@ cmGlobalVisualStudio8Generator } //---------------------------------------------------------------------------- +bool cmGlobalVisualStudio8Generator::ComputeTargetDepends() +{ + // Skip over the cmGlobalVisualStudioGenerator implementation! + // We do not need the support that VS <= 7.1 needs. + return this->cmGlobalGenerator::ComputeTargetDepends(); +} + +//---------------------------------------------------------------------------- +void cmGlobalVisualStudio8Generator::WriteProjectDepends( + std::ostream& fout, const char*, const char*, cmTarget& t) +{ + TargetDependSet const& unordered = this->GetTargetDirectDepends(t); + OrderedTargetDependSet depends(unordered); + for(OrderedTargetDependSet::const_iterator i = depends.begin(); + i != depends.end(); ++i) + { + std::string guid = this->GetGUID((*i)->GetName()); + fout << "\t\t{" << guid << "} = {" << guid << "}\n"; + } +} + +//---------------------------------------------------------------------------- bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies( cmTarget& target) { diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index e0d5d80..e0913ed 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -78,6 +78,9 @@ protected: virtual void WriteProjectConfigurations(std::ostream& fout, const char* name, bool partOfDefaultBuild); + virtual bool ComputeTargetDepends(); + virtual void WriteProjectDepends(std::ostream& fout, const char* name, + const char* path, cmTarget &t); const char* ArchitectureId; }; diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index bae18a3..7696e6c 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -237,6 +237,59 @@ std::string cmGlobalVisualStudioGenerator::GetUserMacrosRegKeyBase() } //---------------------------------------------------------------------------- +void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget* target, + TargetSet& linked) +{ + if(linked.insert(target).second) + { + TargetDependSet const& depends = this->GetTargetDirectDepends(*target); + for(TargetDependSet::const_iterator di = depends.begin(); + di != depends.end(); ++di) + { + if(di->IsLink()) + { + this->FillLinkClosure(*di, linked); + } + } + } +} + +//---------------------------------------------------------------------------- +cmGlobalVisualStudioGenerator::TargetSet const& +cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmTarget* target) +{ + TargetSetMap::iterator i = this->TargetLinkClosure.find(target); + if(i == this->TargetLinkClosure.end()) + { + TargetSetMap::value_type entry(target, TargetSet()); + i = this->TargetLinkClosure.insert(entry).first; + this->FillLinkClosure(target, i->second); + } + return i->second; +} + +//---------------------------------------------------------------------------- +void cmGlobalVisualStudioGenerator::FollowLinkDepends( + cmTarget* target, std::set<cmTarget*>& linked) +{ + if(linked.insert(target).second && + target->GetType() == cmTarget::STATIC_LIBRARY) + { + // Static library targets do not list their link dependencies so + // we must follow them transitively now. + TargetDependSet const& depends = this->GetTargetDirectDepends(*target); + for(TargetDependSet::const_iterator di = depends.begin(); + di != depends.end(); ++di) + { + if(di->IsLink()) + { + this->FollowLinkDepends(*di, linked); + } + } + } +} + +//---------------------------------------------------------------------------- bool cmGlobalVisualStudioGenerator::ComputeTargetDepends() { if(!this->cmGlobalGenerator::ComputeTargetDepends()) @@ -269,51 +322,94 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) return; } VSDependSet& vsTargetDepend = this->VSTargetDepends[&target]; + // VS <= 7.1 has two behaviors that affect solution dependencies. + // + // (1) Solution-level dependencies between a linkable target and a + // library cause that library to be linked. We use an intermedite + // empty utility target to express the dependency. (VS 8 and above + // provide a project file "LinkLibraryDependencies" setting to + // choose whether to activate this behavior. We disable it except + // when linking external project files.) + // + // (2) We cannot let static libraries depend directly on targets to + // which they "link" because the librarian tool will copy the + // targets into the static library. While the work-around for + // behavior (1) would also avoid this, it would create a large + // number of extra utility targets for little gain. Instead, use + // the above work-around only for dependencies explicitly added by + // the add_dependencies() command. Approximate link dependencies by + // leaving them out for the static library itself but following them + // transitively for other targets. + + bool allowLinkable = (target.GetType() != cmTarget::STATIC_LIBRARY && + target.GetType() != cmTarget::SHARED_LIBRARY && + target.GetType() != cmTarget::MODULE_LIBRARY && + target.GetType() != cmTarget::EXECUTABLE); + + TargetDependSet const& depends = this->GetTargetDirectDepends(target); + + // Collect implicit link dependencies (target_link_libraries). + // Static libraries cannot depend on their link implementation + // due to behavior (2), but they do not really need to. + std::set<cmTarget*> linkDepends; if(target.GetType() != cmTarget::STATIC_LIBRARY) { - cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries(); - for(cmTarget::LinkLibraryVectorType::const_iterator j = libs.begin(); - j != libs.end(); ++j) + for(TargetDependSet::const_iterator di = depends.begin(); + di != depends.end(); ++di) { - if(j->first != target.GetName() && - this->FindTarget(0, j->first.c_str())) + cmTargetDepend dep = *di; + if(dep.IsLink()) { - vsTargetDepend.insert(j->first); + this->FollowLinkDepends(dep, linkDepends); } } } - std::set<cmStdString> const& utils = target.GetUtilities(); - for(std::set<cmStdString>::const_iterator i = utils.begin(); - i != utils.end(); ++i) + + // Collext explicit util dependencies (add_dependencies). + std::set<cmTarget*> utilDepends; + for(TargetDependSet::const_iterator di = depends.begin(); + di != depends.end(); ++di) { - if(*i != target.GetName()) + cmTargetDepend dep = *di; + if(dep.IsUtil()) { - std::string name = this->GetUtilityForTarget(target, i->c_str()); - vsTargetDepend.insert(name); + this->FollowLinkDepends(dep, utilDepends); } } -} -//---------------------------------------------------------------------------- -bool cmGlobalVisualStudioGenerator::CheckTargetLinks(cmTarget& target, - const char* name) -{ - // Return whether the given target links to a target with the given name. - if(target.GetType() == cmTarget::STATIC_LIBRARY) + // Collect all targets linked by this target so we can avoid + // intermediate targets below. + TargetSet linked; + if(target.GetType() != cmTarget::STATIC_LIBRARY) { - // Static libraries never link to anything. - return false; + linked = this->GetTargetLinkClosure(&target); } - cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries(); - for(cmTarget::LinkLibraryVectorType::const_iterator i = libs.begin(); - i != libs.end(); ++i) + + // Emit link dependencies. + for(std::set<cmTarget*>::iterator di = linkDepends.begin(); + di != linkDepends.end(); ++di) + { + cmTarget* dep = *di; + vsTargetDepend.insert(dep->GetName()); + } + + // Emit util dependencies. Possibly use intermediate targets. + for(std::set<cmTarget*>::iterator di = utilDepends.begin(); + di != utilDepends.end(); ++di) { - if(i->first == name) + cmTarget* dep = *di; + if(allowLinkable || !dep->IsLinkable() || linked.count(dep)) { - return true; + // Direct dependency allowed. + vsTargetDepend.insert(dep->GetName()); + } + else + { + // Direct dependency on linkable target not allowed. + // Use an intermediate utility target. + vsTargetDepend.insert(this->GetUtilityDepend(dep)); } } - return false; } //---------------------------------------------------------------------------- @@ -330,45 +426,6 @@ std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget* target) } //---------------------------------------------------------------------------- -std::string -cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target, - const char* name) -{ - if(!this->VSLinksDependencies()) - { - return name; - } - - // Possibly depend on an intermediate utility target to avoid - // linking. - if(target.GetType() == cmTarget::STATIC_LIBRARY || - target.GetType() == cmTarget::SHARED_LIBRARY || - target.GetType() == cmTarget::MODULE_LIBRARY || - target.GetType() == cmTarget::EXECUTABLE) - { - // The depender is a target that links. - if(cmTarget* depTarget = this->FindTarget(0, name)) - { - if(depTarget->GetType() == cmTarget::STATIC_LIBRARY || - depTarget->GetType() == cmTarget::SHARED_LIBRARY || - depTarget->GetType() == cmTarget::MODULE_LIBRARY) - { - // This utility dependency will cause an attempt to link. If - // the depender does not already link the dependee we need an - // intermediate target. - if(!this->CheckTargetLinks(target, name)) - { - return this->GetUtilityDepend(depTarget); - } - } - } - } - - // No special case. Just use the original dependency name. - return name; -} - -//---------------------------------------------------------------------------- #include <windows.h> //---------------------------------------------------------------------------- @@ -706,11 +763,22 @@ cmGlobalVisualStudioGenerator::TargetCompare //---------------------------------------------------------------------------- cmGlobalVisualStudioGenerator::OrderedTargetDependSet -::OrderedTargetDependSet(cmGlobalGenerator::TargetDependSet const& targets) +::OrderedTargetDependSet(TargetDependSet const& targets) { - for(cmGlobalGenerator::TargetDependSet::const_iterator ti = + for(TargetDependSet::const_iterator ti = targets.begin(); ti != targets.end(); ++ti) { this->insert(*ti); } } + +//---------------------------------------------------------------------------- +cmGlobalVisualStudioGenerator::OrderedTargetDependSet +::OrderedTargetDependSet(TargetSet const& targets) +{ + for(TargetSet::const_iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + this->insert(*ti); + } +} diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index c8ea339..bc96f4e 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -69,15 +69,12 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ virtual bool IsMultiConfig() { return true; } + class TargetSet: public std::set<cmTarget*> {}; struct TargetCompare { bool operator()(cmTarget const* l, cmTarget const* r) const; }; - class OrderedTargetDependSet: public std::multiset<cmTarget*, TargetCompare> - { - public: - OrderedTargetDependSet(cmGlobalGenerator::TargetDependSet const&); - }; + class OrderedTargetDependSet; protected: // Does this VS version link targets to each other if there are @@ -99,6 +96,24 @@ protected: std::string GetUtilityDepend(cmTarget* target); typedef std::map<cmTarget*, cmStdString> UtilityDependsMap; UtilityDependsMap UtilityDepends; +private: + void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked); + + class TargetSetMap: public std::map<cmTarget*, TargetSet> {}; + TargetSetMap TargetLinkClosure; + void FillLinkClosure(cmTarget* target, TargetSet& linked); + TargetSet const& GetTargetLinkClosure(cmTarget* target); +}; + +class cmGlobalVisualStudioGenerator::OrderedTargetDependSet: + public std::multiset<cmTargetDepend, + cmGlobalVisualStudioGenerator::TargetCompare> +{ +public: + typedef cmGlobalGenerator::TargetDependSet TargetDependSet; + typedef cmGlobalVisualStudioGenerator::TargetSet TargetSet; + OrderedTargetDependSet(TargetDependSet const&); + OrderedTargetDependSet(TargetSet const&); }; #endif diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 2f7bc44..29c2d06 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1334,11 +1334,13 @@ void cmGlobalXCodeGenerator cc.GetDepends().begin(); d != cc.GetDepends().end(); ++d) { - std::string dep = - this->CurrentLocalGenerator->GetRealDependency(d->c_str(), - configName); - makefileStream << "\\\n" << this - ->ConvertToRelativeForMake(dep.c_str()); + std::string dep; + if(this->CurrentLocalGenerator + ->GetRealDependency(d->c_str(), configName, dep)) + { + makefileStream << "\\\n" << + this->ConvertToRelativeForMake(dep.c_str()); + } } makefileStream << "\n"; diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index d2a07dc..a239e55 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -174,7 +174,8 @@ void cmLoadCacheCommand::CheckLine(const char* line) // Check one line of the cache file. std::string var; std::string value; - if(this->ParseEntry(line, var, value)) + cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; + if(cmCacheManager::ParseEntry(line, var, value, type)) { // Found a real entry. See if this one was requested. if(this->VariablesToRead.find(var) != this->VariablesToRead.end()) @@ -193,38 +194,3 @@ void cmLoadCacheCommand::CheckLine(const char* line) } } } - -//---------------------------------------------------------------------------- -bool cmLoadCacheCommand::ParseEntry(const char* entry, std::string& var, - std::string& value) -{ - // input line is: key:type=value - cmsys::RegularExpression reg("^([^:]*):([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$"); - // input line is: "key":type=value - cmsys::RegularExpression - regQuoted("^\"([^\"]*)\":([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$"); - bool flag = false; - if(regQuoted.find(entry)) - { - var = regQuoted.match(1); - value = regQuoted.match(3); - flag = true; - } - else if (reg.find(entry)) - { - var = reg.match(1); - value = reg.match(3); - flag = true; - } - - // if value is enclosed in single quotes ('foo') then remove them - // it is used to enclose trailing space or tab - if (flag && - value.size() >= 2 && - value[0] == '\'' && - value[value.size() - 1] == '\'') - { - value = value.substr(1, value.size() - 2); - } - return flag; -} diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h index b06d94d..8ecee4a 100644 --- a/Source/cmLoadCacheCommand.h +++ b/Source/cmLoadCacheCommand.h @@ -83,7 +83,6 @@ protected: bool ReadWithPrefix(std::vector<std::string> const& args); void CheckLine(const char* line); - bool ParseEntry(const char* entry, std::string& var, std::string& value); }; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 5bffd52..b7d694c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1818,8 +1818,9 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, } //---------------------------------------------------------------------------- -std::string cmLocalGenerator::GetRealDependency(const char* inName, - const char* config) +bool cmLocalGenerator::GetRealDependency(const char* inName, + const char* config, + std::string& dep) { // Older CMake code may specify the dependency using the target // output file rather than the target name. Such code would have @@ -1855,7 +1856,8 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, // it is a full path to a depend that has the same name // as a target but is in a different location so do not use // the target as the depend - return inName; + dep = inName; + return true; } } switch (target->GetType()) @@ -1869,15 +1871,16 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, // Get the location of the target's output file and depend on it. if(const char* location = target->GetLocation(config)) { - return location; + dep = location; + return true; } } break; case cmTarget::UTILITY: case cmTarget::GLOBAL_TARGET: - // Depending on a utility target may not work but just trust - // the user to have given a valid name. - return inName; + // A utility target has no file on which to depend. This was listed + // only to get the target-level dependency. + return false; case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_PROGRAMS: case cmTarget::INSTALL_DIRECTORY: @@ -1889,23 +1892,24 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, if(cmSystemTools::FileIsFullPath(inName)) { // This is a full path. Return it as given. - return inName; + dep = inName; + return true; } // Check for a source file in this directory that matches the // dependency. if(cmSourceFile* sf = this->Makefile->GetSource(inName)) { - name = sf->GetFullPath(); - return name; + dep = sf->GetFullPath(); + return true; } // Treat the name as relative to the source directory in which it // was given. - name = this->Makefile->GetCurrentDirectory(); - name += "/"; - name += inName; - return name; + dep = this->Makefile->GetCurrentDirectory(); + dep += "/"; + dep += inName; + return true; } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 43bf1e7..870ce36 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -158,14 +158,16 @@ public: /** Translate a dependency as given in CMake code to the name to appear in a generated build file. If the given name is that of + a utility target, returns false. If the given name is that of a CMake target it will be transformed to the real output location of that target for the given configuration. If the given name is the full path to a file it will be returned. Otherwise the name is treated as a relative path with respect to the source directory of this generator. This should only be used for dependencies of custom commands. */ - std::string GetRealDependency(const char* name, const char* config); - + bool GetRealDependency(const char* name, const char* config, + std::string& dep); + /** Translate a command as given in CMake code to the location of the executable if the command is the name of a CMake executable target. If that's not the case, just return the original name. */ diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index f04d0a0..15ae139 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -140,7 +140,7 @@ void cmLocalUnixMakefileGenerator3::Generate() // write the local Makefile this->WriteLocalMakefile(); - + // Write the cmake file with information for this directory. this->WriteDirectoryInformationFile(); } @@ -149,7 +149,7 @@ void cmLocalUnixMakefileGenerator3::Generate() void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets (std::vector<std::string>& targets) { - for (std::map<cmStdString, LocalObjectInfo>::iterator lo = + for (std::map<cmStdString, LocalObjectInfo>::iterator lo = this->LocalObjectFiles.begin(); lo != this->LocalObjectFiles.end(); ++lo) { @@ -188,10 +188,10 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() { ruleFileStream.SetCopyIfDifferent(true); } - + // write the all rules this->WriteLocalAllRules(ruleFileStream); - + // only write local targets unless at the top Keep track of targets already // listed. std::set<cmStdString> emittedTargets; @@ -203,7 +203,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() } else { - cmGlobalUnixMakefileGenerator3 *gg = + cmGlobalUnixMakefileGenerator3 *gg = static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); gg->WriteConvenienceRules(ruleFileStream,emittedTargets); } @@ -215,7 +215,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() // now write out the object rules // for each object file name - for (std::map<cmStdString, LocalObjectInfo>::iterator lo = + for (std::map<cmStdString, LocalObjectInfo>::iterator lo = this->LocalObjectFiles.begin(); lo != this->LocalObjectFiles.end(); ++lo) { @@ -261,7 +261,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() // add a help target as long as there isn;t a real target named help if(emittedTargets.insert("help").second) { - cmGlobalUnixMakefileGenerator3 *gg = + cmGlobalUnixMakefileGenerator3 *gg = static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); gg->WriteHelpRule(ruleFileStream,this); } @@ -353,7 +353,7 @@ void cmLocalUnixMakefileGenerator3 localName += "/rule"; commands.clear(); depends.clear(); - + // Build the target for this pass. std::string makefile2 = cmake::GetCMakeFilesDirectoryPostSlash(); makefile2 += "Makefile2"; @@ -364,7 +364,7 @@ void cmLocalUnixMakefileGenerator3 cmLocalGenerator::START_OUTPUT); this->WriteMakeRule(ruleFileStream, "Convenience name for target.", localName.c_str(), depends, commands, true); - + // Add a target with the canonical name (no prefix, suffix or path). if(localName != t->second.GetName()) { @@ -378,7 +378,7 @@ void cmLocalUnixMakefileGenerator3 std::string makefileName = this->GetRelativeTargetDirectory(t->second); makefileName += "/build.make"; // make sure the makefile name is suitable for a makefile - std::string makeTargetName = + std::string makeTargetName = this->GetRelativeTargetDirectory(t->second); makeTargetName += "/build"; localName = t->second.GetName(); @@ -647,7 +647,7 @@ cmLocalUnixMakefileGenerator3 makefileStream << "# The CMake executable.\n" << "CMAKE_COMMAND = " - << this->Convert(cmakecommand.c_str(), FULL, SHELL).c_str() + << this->Convert(cmakecommand.c_str(), FULL, SHELL).c_str() << "\n" << "\n"; makefileStream @@ -656,7 +656,7 @@ cmLocalUnixMakefileGenerator3 << this->Convert(cmakecommand.c_str(),FULL,SHELL).c_str() << " -E remove -f\n" << "\n"; - + if(const char* edit_cmd = this->Makefile->GetDefinition("CMAKE_EDIT_COMMAND")) { @@ -722,8 +722,7 @@ cmLocalUnixMakefileGenerator3 // "VERBOSE=1" to be added as a make variable which will change the // name of this special target. This gives a make-time choice to // the user. - if((this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) - || (gg->GetForceVerboseMakefiles())) + if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) { makefileStream << "# Produce verbose output by default.\n" @@ -872,7 +871,7 @@ cmLocalUnixMakefileGenerator3 { // Add a dependency on the rule file itself unless an option to skip // it is specifically enabled by the user or project. - const char* nodep = + const char* nodep = this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY"); if(!nodep || cmSystemTools::IsOff(nodep)) { @@ -903,9 +902,12 @@ cmLocalUnixMakefileGenerator3 d != cc.GetDepends().end(); ++d) { // Lookup the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency - (d->c_str(), this->ConfigurationName.c_str()); - depends.push_back(dep); + std::string dep; + if(this->GetRealDependency(d->c_str(), this->ConfigurationName.c_str(), + dep)) + { + depends.push_back(dep); + } } } @@ -969,7 +971,7 @@ cmLocalUnixMakefileGenerator3 { // Build the command line in a single string. const cmCustomCommandLine& commandLine = *cl; - std::string cmd = GetRealLocation(commandLine[0].c_str(), + std::string cmd = GetRealLocation(commandLine[0].c_str(), this->ConfigurationName.c_str()); if (cmd.size()) { @@ -1283,7 +1285,7 @@ cmLocalUnixMakefileGenerator3 // see if the variable has been defined before and return // the modified version of the variable - std::map<cmStdString, cmStdString>::iterator i = + std::map<cmStdString, cmStdString>::iterator i = this->MakeVariableMap.find(unmodified); if(i != this->MakeVariableMap.end()) { @@ -1404,7 +1406,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo, dirInfoFile += "/CMakeDirectoryInformation.cmake"; { int result; - if(!ftc->FileTimeCompare(internalDependFile.c_str(), + if(!ftc->FileTimeCompare(internalDependFile.c_str(), dirInfoFile.c_str(), &result) || result < 0) { if(verbose) @@ -1418,7 +1420,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo, needRescanDirInfo = true; } } - + // Check the implicit dependencies to see if they are up to date. // The build.make file may have explicit dependencies for the object // files but these will not affect the scanning process so they need @@ -1433,11 +1435,11 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo, // cmDependsC::Check() fills the vector validDependencies() with the // dependencies for those files where they are still valid, i.e. neither // the files themselves nor any files they depend on have changed. - // We don't do that if the CMakeDirectoryInformation.cmake file has + // We don't do that if the CMakeDirectoryInformation.cmake file has // changed, because then potentially all dependencies have changed. // This information is given later on to cmDependsC, which then only // rescans the files where it did not get valid dependencies via this - // dependency vector. This means that in the normal case, when only + // dependency vector. This means that in the normal case, when only // few or one file have been edited, then also only this one file is // actually scanned again, instead of all files for this target. needRescanDependencies = !checker.Check(dependFile.c_str(), @@ -1485,7 +1487,7 @@ cmLocalUnixMakefileGenerator3 { haveDirectoryInfo = true; } - + // Lookup useful directory information. if(haveDirectoryInfo) { @@ -1545,11 +1547,11 @@ cmLocalUnixMakefileGenerator3 this->WriteDisclaimer(ruleFileStream); this->WriteDisclaimer(internalRuleFileStream); - // for each language we need to scan, scan it + // for each language we need to scan, scan it const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"); std::vector<std::string> langs; cmSystemTools::ExpandListArgument(langStr, langs); - for (std::vector<std::string>::iterator li = + for (std::vector<std::string>::iterator li = langs.begin(); li != langs.end(); ++li) { // construct the checker @@ -1572,7 +1574,7 @@ cmLocalUnixMakefileGenerator3 scanner = new cmDependsJava(); } #endif - + if (scanner) { scanner->SetLocalGenerator(this); @@ -1686,25 +1688,25 @@ void cmLocalUnixMakefileGenerator3 cmLocalUnixMakefileGenerator3::EchoGlobal); // Global targets store their rules in pre- and post-build commands. - this->AppendCustomDepends(depends, + this->AppendCustomDepends(depends, glIt->second.GetPreBuildCommands()); - this->AppendCustomDepends(depends, + this->AppendCustomDepends(depends, glIt->second.GetPostBuildCommands()); - this->AppendCustomCommands(commands, + this->AppendCustomCommands(commands, glIt->second.GetPreBuildCommands(), &glIt->second, cmLocalGenerator::START_OUTPUT); - this->AppendCustomCommands(commands, + this->AppendCustomCommands(commands, glIt->second.GetPostBuildCommands(), &glIt->second, cmLocalGenerator::START_OUTPUT); std::string targetName = glIt->second.GetName(); - this->WriteMakeRule(ruleFileStream, targetString.c_str(), + this->WriteMakeRule(ruleFileStream, targetString.c_str(), targetName.c_str(), depends, commands, true); // Provide a "/fast" version of the target. depends.clear(); - if((targetName == "install") + if((targetName == "install") || (targetName == "install_local") || (targetName == "install_strip")) { @@ -1738,7 +1740,7 @@ void cmLocalUnixMakefileGenerator3 progressDir += cmake::GetCMakeFilesDirectory(); { cmOStringStream progCmd; - progCmd << + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; progCmd << this->Convert(progressDir.c_str(), cmLocalGenerator::FULL, @@ -1833,8 +1835,8 @@ void cmLocalUnixMakefileGenerator3 this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), cmLocalGenerator::START_OUTPUT); - this->WriteMakeRule(ruleFileStream, "clear depends", - "depend", + this->WriteMakeRule(ruleFileStream, "clear depends", + "depend", depends, commands, true); } @@ -2048,7 +2050,7 @@ cmLocalUnixMakefileGenerator3 cmd += "$(MAKE) -f "; cmd += this->Convert(makefile,NONE,SHELL); cmd += " "; - + // Pass down verbosity level. if(this->GetMakeSilentFlag().size()) { @@ -2125,7 +2127,7 @@ cmLocalUnixMakefileGenerator3 std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p) { - + // Split the path into its components. std::vector<std::string> components; cmSystemTools::SplitPath(p, components); @@ -2224,7 +2226,7 @@ void cmLocalUnixMakefileGenerator3 { return; } - + if(!this->UnixCD) { // On Windows we must perform each step separately and then change diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index eb4e4a4..b50c133 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -686,10 +686,12 @@ cmLocalVisualStudio6Generator ++d) { // Lookup the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency(d->c_str(), - config.c_str()); - fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); + std::string dep; + if(this->GetRealDependency(d->c_str(), config.c_str(), dep)) + { + fout << "\\\n\t" << + this->ConvertToOptionallyRelativeOutputPath(dep.c_str()); + } } fout << "\n"; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index cb34bb6..9a87cc4 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -669,6 +669,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.FixExceptionHandlingDefault(); 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")); @@ -1098,11 +1099,13 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") ) { - fout << "\t\t\t\tSubSystem=\"2\"\n"; + fout << "\t\t\t\tSubSystem=\"" + << (this->FortranProject? "subSystemWindows" : "2") << "\"\n"; } else { - fout << "\t\t\t\tSubSystem=\"1\"\n"; + fout << "\t\t\t\tSubSystem=\"" + << (this->FortranProject? "subSystemConsole" : "1") << "\"\n"; } std::string stackVar = "CMAKE_"; stackVar += linkLanguage; @@ -1621,9 +1624,12 @@ WriteCustomRule(std::ostream& fout, ++d) { // Get the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency(d->c_str(), i->c_str()); - fout << this->ConvertToXMLOutputPath(dep.c_str()) - << ";"; + std::string dep; + if(this->GetRealDependency(d->c_str(), i->c_str(), dep)) + { + fout << this->ConvertToXMLOutputPath(dep.c_str()) + << ";"; + } } } fout << "\"\n"; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index c6e34f8..ef81529 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1392,8 +1392,8 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target, cmOStringStream e; e << "Attempt to add link library \"" << lib << "\" to target \"" - << target << "\" which is not built by this project."; - cmSystemTools::Error(e.str().c_str()); + << target << "\" which is not built in this directory."; + this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); } } @@ -3786,6 +3786,12 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name) return imported->second; } + // Look for a target built in this directory. + if(cmTarget* t = this->FindTarget(name)) + { + return t; + } + // Look for a target built in this project. return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name); } diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index a5e319d..4426241 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -82,34 +82,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) { std::vector<std::string> commands; - std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath(); - std::string objTarget; - // Build list of dependencies. std::vector<std::string> depends; - for(std::vector<std::string>::const_iterator obj = this->Objects.begin(); - obj != this->Objects.end(); ++obj) - { - objTarget = relPath; - objTarget += *obj; - depends.push_back(objTarget); - } - - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends); - - // Add a dependency on the rule file itself. - this->LocalGenerator->AppendRuleDepend(depends, - this->BuildFileNameFull.c_str()); - - for(std::vector<std::string>::const_iterator obj = - this->ExternalObjects.begin(); - obj != this->ExternalObjects.end(); ++obj) - { - depends.push_back(*obj); - } - - // from here up is the same for exe or lib + this->AppendLinkDepends(depends); // Get the name of the executable to generate. std::string targetName; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index dff91fe..049a338 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -308,33 +308,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules // code duplication. std::vector<std::string> commands; - std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath(); - std::string objTarget; - // Build list of dependencies. std::vector<std::string> depends; - for(std::vector<std::string>::const_iterator obj = this->Objects.begin(); - obj != this->Objects.end(); ++obj) - { - objTarget = relPath; - objTarget += *obj; - depends.push_back(objTarget); - } + this->AppendLinkDepends(depends); - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends); - - // Add a dependency on the rule file itself. - this->LocalGenerator->AppendRuleDepend(depends, - this->BuildFileNameFull.c_str()); - - for(std::vector<std::string>::const_iterator obj - = this->ExternalObjects.begin(); - obj != this->ExternalObjects.end(); ++obj) - { - depends.push_back(*obj); - } - // Get the language to use for linking this library. const char* linkLanguage = this->Target->GetLinkerLanguage(this->ConfigName); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index d5d6585..9dcd8f1 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -849,7 +849,7 @@ cmMakefileTargetGenerator p_depends.push_back(relativeObj); this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, temp.c_str(), p_depends, no_commands, - true); + false); } //---------------------------------------------------------------------------- @@ -1507,6 +1507,50 @@ void cmMakefileTargetGenerator //---------------------------------------------------------------------------- void cmMakefileTargetGenerator +::AppendLinkDepends(std::vector<std::string>& depends) +{ + // Add dependencies on the compiled object files. + std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath(); + std::string objTarget; + for(std::vector<std::string>::const_iterator obj = this->Objects.begin(); + obj != this->Objects.end(); ++obj) + { + objTarget = relPath; + objTarget += *obj; + depends.push_back(objTarget); + } + + // Add dependencies on targets that must be built first. + this->AppendTargetDepends(depends); + + // Add a dependency on the rule file itself. + this->LocalGenerator->AppendRuleDepend(depends, + this->BuildFileNameFull.c_str()); + + // Add a dependency on the link definitions file, if any. + if(!this->ModuleDefinitionFile.empty()) + { + depends.push_back(this->ModuleDefinitionFile); + } + + // Add dependencies on the external object files. + for(std::vector<std::string>::const_iterator obj + = this->ExternalObjects.begin(); + obj != this->ExternalObjects.end(); ++obj) + { + depends.push_back(*obj); + } + + // Add user-specified dependencies. + if(const char* linkDepends = + this->Target->GetProperty("LINK_DEPENDS")) + { + cmSystemTools::ExpandListArgument(linkDepends, depends); + } +} + +//---------------------------------------------------------------------------- +void cmMakefileTargetGenerator ::CloseFileStreams() { delete this->BuildFileStream; @@ -1722,8 +1766,20 @@ const char* cmMakefileTargetGenerator::GetFortranModuleDirectory() //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) { + // Enable module output if necessary. + if(const char* modout_flag = + this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG")) + { + this->LocalGenerator->AppendFlags(flags, modout_flag); + } + // Add a module output directory flag if necessary. - if(const char* mod_dir = this->GetFortranModuleDirectory()) + const char* mod_dir = this->GetFortranModuleDirectory(); + if(!mod_dir) + { + mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); + } + if(mod_dir) { const char* moddir_flag = this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"); diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 4ee2b39..c9aede2 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -115,6 +115,9 @@ protected: // append intertarget dependencies void AppendTargetDepends(std::vector<std::string>& depends); + // Append link rule dependencies (objects, etc.). + void AppendLinkDepends(std::vector<std::string>& depends); + /** In order to support parallel builds for custom commands with multiple outputs the outputs are given a serial order, and only the first output actually has the build rule. Other outputs diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index bab08fe..949fcf5 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -608,7 +608,7 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const& return false; } int leftOverLength = intStringLength - begin; - if ( end < 0 || end > leftOverLength ) + if ( end < -1 || end > leftOverLength ) { cmOStringStream ostr; ostr << "end index: " << end << " is out of range " << 0 << " - " diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5380257..ef274b4 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -532,6 +532,18 @@ void cmTarget::DefineProperties(cmake *cm) "configurations explicitly."); cm->DefineProperty + ("LINK_DEPENDS", cmProperty::TARGET, + "Additional files on which a target binary depends for linking.", + "Specifies a semicolon-separated list of full-paths to files on which " + "the link rule for this target depends. " + "The target binary will be linked if any of the named files is newer " + "than it." + "\n" + "This property is ignored by non-Makefile generators. " + "It is intended to specify dependencies on \"linker scripts\" for " + "custom Makefile link rules."); + + cm->DefineProperty ("LINK_INTERFACE_LIBRARIES", cmProperty::TARGET, "List public interface libraries for a shared library or executable.", "By default linking to a shared library target transitively " @@ -1345,8 +1357,8 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) util = cmSystemTools::GetFilenameWithoutLastExtension(util); } - // Check for a non-imported target with this name. - if(cmTarget* t = this->GlobalGenerator->FindTarget(0, util.c_str())) + // Check for a target with this name. + if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str())) { // If we find the target and the dep was given as a full path, // then make sure it was not a full path to something else, and @@ -1394,8 +1406,8 @@ cmTargetTraceDependencies cit != cc.GetCommandLines().end(); ++cit) { std::string const& command = *cit->begin(); - // Look for a non-imported target with this name. - if(cmTarget* t = this->GlobalGenerator->FindTarget(0, command.c_str())) + // Check for a target with this name. + if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str())) { if(t->GetType() == cmTarget::EXECUTABLE) { @@ -1438,6 +1450,15 @@ cmTargetTraceDependencies //---------------------------------------------------------------------------- void cmTarget::TraceDependencies(const char* vsProjectFile) { + // CMake-generated targets have no dependencies to trace. Normally tracing + // would find nothing anyway, but when building CMake itself the "install" + // target command ends up referencing the "cmake" target but we do not + // really want the dependency because "install" depend on "all" anyway. + if(this->GetType() == cmTarget::GLOBAL_TARGET) + { + return; + } + // Use a helper object to trace the dependencies. cmTargetTraceDependencies tracer(this, this->Internal.Get(), vsProjectFile); tracer.Trace(); @@ -3184,6 +3205,7 @@ void cmTarget::GetLibraryNames(std::string& name, // the library version as the soversion. soversion = version; } + bool isApple = this->Makefile->IsOn("APPLE"); // Get the components of the library name. std::string prefix; @@ -3195,26 +3217,33 @@ void cmTarget::GetLibraryNames(std::string& name, name = prefix+base+suffix; // The library's soname. -#if defined(__APPLE__) - soName = prefix+base; -#else - soName = name; -#endif + if(isApple) + { + soName = prefix+base; + } + else + { + soName = name; + } if(soversion) { soName += "."; soName += soversion; } -#if defined(__APPLE__) - soName += suffix; -#endif + if(isApple) + { + soName += suffix; + } // The library's real name on disk. -#if defined(__APPLE__) - realName = prefix+base; -#else + if(isApple) + { + realName = prefix+base; + } + else + { realName = name; -#endif + } if(version) { realName += "."; @@ -3225,9 +3254,10 @@ void cmTarget::GetLibraryNames(std::string& name, realName += "."; realName += soversion; } -#if defined(__APPLE__) - realName += suffix; -#endif + if(isApple) + { + realName += suffix; + } // The import library name. if(this->GetType() == cmTarget::SHARED_LIBRARY || diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h new file mode 100644 index 0000000..258bacd --- /dev/null +++ b/Source/cmTargetDepend.h @@ -0,0 +1,48 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2010 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 cmTargetDepend_h +#define cmTargetDepend_h + +#include "cmStandardIncludes.h" + +class cmTarget; + +/** One edge in the global target dependency graph. + It may be marked as a 'link' or 'util' edge or both. */ +class cmTargetDepend +{ + cmTarget* Target; + + // The set order depends only on the Target, so we use + // mutable members to acheive a map with set syntax. + mutable bool Link; + mutable bool Util; +public: + cmTargetDepend(cmTarget* t): Target(t), Link(false), Util(false) {} + operator cmTarget*() const { return this->Target; } + cmTarget* operator->() const { return this->Target; } + cmTarget& operator*() const { return *this->Target; } + friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r) + { return l.Target < r.Target; } + void SetType(bool strong) const + { + if(strong) { this->Util = true; } + else { this->Link = true; } + } + bool IsLink() const { return this->Link; } + bool IsUtil() const { return this->Util; } +}; + +/** Unordered set of (direct) dependencies of a target. */ +class cmTargetDependSet: public std::set<cmTargetDepend> {}; + +#endif diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index 43a0d7c..ce57df7 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -62,6 +62,10 @@ public: " target_link_libraries(<target> [item1 [item2 [...]]]\n" " [[debug|optimized|general] <item>] ...)\n" "Specify libraries or flags to use when linking a given target. " + "The named <target> must have been created in the current directory " + "by a command such as add_executable or add_library. " + "The remaining arguments specify library names or flags." + "\n" "If a library name matches that of another target in the project " "a dependency will automatically be added in the build system to make " "sure the library being linked is up-to-date before the target links. " diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index 4e9b973..c25a8b6 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -196,4 +196,10 @@ void cmTest::DefineProperties(cmake *cm) "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."); + + cm->DefineProperty + ("WORKING_DIRECTORY", cmProperty::TEST, + "The directory from which the test executable will be called.", + "If this is not set it is called from the directory the test executable " + "is located in."); } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 524be8b..f78aeec 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -244,6 +244,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() { + cmGlobalVisualStudio10Generator* gg = + static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); std::vector<std::string> *configs = static_cast<cmGlobalVisualStudio7Generator *> (this->GlobalGenerator)->GetConfigurations(); @@ -291,6 +293,13 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() { this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2); } + if(const char* toolset = gg->GetPlatformToolset()) + { + std::string pts = "<PlatformToolset>"; + pts += toolset; + pts += "</PlatformToolset>\n"; + this->WriteString(pts.c_str(), 2); + } this->WriteString("</PropertyGroup>\n", 1); } } @@ -386,10 +395,12 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, d != command.GetDepends().end(); ++d) { - std::string dep = this->LocalGenerator-> - GetRealDependency(d->c_str(), i->c_str()); - this->ConvertToWindowsSlash(dep); - (*this->BuildFileStream ) << ";" << dep; + std::string dep; + if(this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep)) + { + this->ConvertToWindowsSlash(dep); + (*this->BuildFileStream ) << ";" << dep; + } } (*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n"; this->WritePlatformConfigTag("Outputs", i->c_str(), 3); diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 972af95..f1bad9c 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -45,6 +45,10 @@ cmVisualStudioGeneratorOptions // Slash options are allowed for VS. this->AllowSlash = true; + + this->FortranRuntimeDebug = false; + this->FortranRuntimeDLL = false; + this->FortranRuntimeMT = false; } //---------------------------------------------------------------------------- @@ -133,8 +137,55 @@ void cmVisualStudioGeneratorOptions::Parse(const char* flags) } //---------------------------------------------------------------------------- +void cmVisualStudioGeneratorOptions::ParseFinish() +{ + if(this->CurrentTool == FortranCompiler) + { + // "RuntimeLibrary" attribute values: + // "rtMultiThreaded", "0", /threads /libs:static + // "rtMultiThreadedDLL", "2", /threads /libs:dll + // "rtMultiThreadedDebug", "1", /threads /dbglibs /libs:static + // "rtMultiThreadedDebugDLL", "3", /threads /dbglibs /libs:dll + // These seem unimplemented by the IDE: + // "rtSingleThreaded", "4", /libs:static + // "rtSingleThreadedDLL", "10", /libs:dll + // "rtSingleThreadedDebug", "5", /dbglibs /libs:static + // "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll + std::string rl = "rtMultiThreaded"; + rl += this->FortranRuntimeDebug? "Debug" : ""; + rl += this->FortranRuntimeDLL? "DLL" : ""; + this->FlagMap["RuntimeLibrary"] = rl; + } +} + +//---------------------------------------------------------------------------- void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag) { + // Look for Intel Fortran flags that do not map well in the flag table. + if(this->CurrentTool == FortranCompiler) + { + if(strcmp(flag, "/dbglibs") == 0) + { + this->FortranRuntimeDebug = true; + return; + } + if(strcmp(flag, "/threads") == 0) + { + this->FortranRuntimeMT = true; + return; + } + if(strcmp(flag, "/libs:dll") == 0) + { + this->FortranRuntimeDLL = true; + return; + } + if(strcmp(flag, "/libs:static") == 0) + { + this->FortranRuntimeDLL = false; + return; + } + } + // This option is not known. Store it in the output flags. this->FlagString += " "; this->FlagString += diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index f7d1a02..8619ba0 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -39,6 +39,7 @@ public: // Store options from command line flags. void Parse(const char* flags); + void ParseFinish(); // Fix the ExceptionHandling option to default to off. void FixExceptionHandlingDefault(); @@ -67,6 +68,10 @@ private: Tool CurrentTool; cmVisualStudio10TargetGenerator* TargetGenerator; + bool FortranRuntimeDebug; + bool FortranRuntimeDLL; + bool FortranRuntimeMT; + virtual void StoreUnknownFlag(const char* flag); }; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 0d1c4ef..bab0aaf 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -374,8 +374,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) } std::string var, value; cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; - if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type) || - cmCacheManager::ParseEntry(entry.c_str(), var, value)) + if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type)) { this->CacheManager->AddCacheEntry(var.c_str(), value.c_str(), "No help, variable specified on the command line.", type); @@ -3864,6 +3863,10 @@ int cmake::VisualStudioLink(std::vector<std::string>& args, int type) { hasIncremental = true; } + if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL") == 0) + { + hasIncremental = true; + } if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0) { hasManifest = false; diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index bcc7a96..a35a01f 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -61,6 +61,8 @@ # If not given the install rules # will not be in any component. # +# KWSYS_INSTALL_EXPORT_NAME = The EXPORT option value for install(TARGETS) calls. +# # Example: # # SET(KWSYS_INSTALL_BIN_DIR bin) @@ -236,6 +238,9 @@ IF(COMMAND INSTALL) # Setup library install rules. SET(KWSYS_INSTALL_LIBRARY_RULE) IF(KWSYS_INSTALL_LIB_DIR) + IF(KWSYS_INSTALL_EXPORT_NAME) + LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME}) + ENDIF() # Install the shared library to the lib directory. SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 936c1f7..4818ce9 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -3304,28 +3304,37 @@ bool SystemInformationImplementation::QueryOSInformation() { case VER_PLATFORM_WIN32_NT: // Test for the product. - if (osvi.dwMajorVersion <= 4) + if (osvi.dwMajorVersion <= 4) { this->OSRelease = "NT"; } - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { this->OSRelease = "2000"; } - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + { + this->OSRelease = "XP"; + } + // XP Professional x64 + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { this->OSRelease = "XP"; } #ifdef VER_NT_WORKSTATION // Test for product type. - if (bOsVersionInfoEx) + if (bOsVersionInfoEx) { - if (osvi.wProductType == VER_NT_WORKSTATION) + if (osvi.wProductType == VER_NT_WORKSTATION) { - if (osvi.dwMajorVersion == 6) + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) { this->OSRelease = "Vista"; } + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) + { + this->OSRelease = "7"; + } // VER_SUITE_PERSONAL may not be defined #ifdef VER_SUITE_PERSONAL else diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 8aa99eb..60d6869 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -378,9 +378,7 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char kwsys_stl::string::size_type endpos = pathEnv.find(pathSep, start); if(endpos != kwsys_stl::string::npos) { - kwsys_stl::string convertedPath; - Realpath(pathEnv.substr(start, endpos-start).c_str(), convertedPath); - path.push_back(convertedPath); + path.push_back(pathEnv.substr(start, endpos-start)); start = endpos+1; } else @@ -1642,7 +1640,7 @@ kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path) kwsys_stl::string ret = path; // remove // except at the beginning might be a cygwin drive - kwsys_stl::string::size_type pos=0; + kwsys_stl::string::size_type pos=1; while((pos = ret.find("//", pos)) != kwsys_stl::string::npos) { ret.erase(pos, 1); diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index a4306a5..71d177d 100644 --- a/Source/kwsys/kwsysDateStamp.cmake +++ b/Source/kwsys/kwsysDateStamp.cmake @@ -15,7 +15,7 @@ SET(KWSYS_DATE_STAMP_YEAR 2010) # KWSys version date month component. Format is MM. -SET(KWSYS_DATE_STAMP_MONTH 10) +SET(KWSYS_DATE_STAMP_MONTH 12) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 31) +SET(KWSYS_DATE_STAMP_DAY 16) diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index ad35c34..c0e74af 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -297,7 +297,7 @@ bool CheckStringOperations() if (kwsys::SystemTools::ConvertToUnixOutputPath ("//Local Mojo/Hex Power Pack/Iffy Voodoo") != - "/Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo") + "//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo") { kwsys_ios::cerr << "Problem with ConvertToUnixOutputPath " |