diff options
26 files changed, 283 insertions, 188 deletions
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index ed8f598..24048ed 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -100,6 +100,10 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_YASM "--version") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_YASM "(yasm)") + list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS ADSP) + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_ADSP "-version") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_ADSP "Analog Devices") + include(CMakeDetermineCompilerId) set(userflags) CMAKE_DETERMINE_COMPILER_ID_VENDOR(ASM${ASM_DIALECT} "${userflags}") diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake index e04ab1c..d8297d9 100644 --- a/Modules/CheckIPOSupported.cmake +++ b/Modules/CheckIPOSupported.cmake @@ -26,7 +26,7 @@ property. Set ``<output>`` variable with details about any error. ``LANGUAGES <lang>...`` Specify languages whose compilers to check. - Languages ``C`` and ``CXX`` are supported. + Languages ``C``, ``CXX``, and ``Fortran`` are supported. It makes no sense to use this module when :policy:`CMP0069` is set to ``OLD`` so module will return error in this case. See policy :policy:`CMP0069` for details. diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 0decbb5..0a31ac2 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -585,6 +585,18 @@ mark_as_advanced( CUDA_SEPARABLE_COMPILATION ) +# Single config generators like Makefiles or Ninja don't usually have +# CMAKE_CONFIGURATION_TYPES defined (but note that it can be defined if set by +# projects or developers). Even CMAKE_BUILD_TYPE might not be defined for +# single config generators (and should not be defined for multi-config +# generators). To ensure we get a complete superset of all possible +# configurations, we combine CMAKE_CONFIGURATION_TYPES, CMAKE_BUILD_TYPE and +# all of the standard configurations, then weed out duplicates with +# list(REMOVE_DUPLICATES). Looping over the unique set then ensures we have +# each configuration-specific set of nvcc flags defined and marked as advanced. +set(CUDA_configuration_types ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE} Debug MinSizeRel Release RelWithDebInfo) +list(REMOVE_DUPLICATES CUDA_configuration_types) + ############################################################################### ############################################################################### # Locate CUDA, Set Build Type, etc. diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 79d0e6b..3666d5c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 10) -set(CMake_VERSION_PATCH 20180130) +set(CMake_VERSION_PATCH 20180131) #set(CMake_VERSION_RC 1) diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 06d13ba..330b747 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -166,6 +166,10 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE}) target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES}) +if(WIN32) + target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>) +endif() + # cmake-gui has not been updated for `include-what-you-use`. # Block the tool until this is done. set_target_properties(cmake-gui PROPERTIES diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 50ebfa1..5a43f2e 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmLocalCommonGenerator.h" +#include <utility> #include <vector> #include "cmGeneratorTarget.h" @@ -76,3 +77,17 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( return flags; } + +void cmLocalCommonGenerator::ComputeObjectFilenames( + std::map<cmSourceFile const*, std::string>& mapping, + cmGeneratorTarget const* gt) +{ + // Determine if these object files should use a custom extension + char const* custom_ext = gt->GetCustomObjectExtension(); + for (auto& si : mapping) { + cmSourceFile const* sf = si.first; + bool keptSourceExtension; + si.second = this->GetObjectFileNameWithoutTarget( + *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext); + } +} diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h index a60573c..7b8e6fe 100644 --- a/Source/cmLocalCommonGenerator.h +++ b/Source/cmLocalCommonGenerator.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <map> #include <string> #include "cmLocalGenerator.h" @@ -12,6 +13,7 @@ class cmGeneratorTarget; class cmGlobalGenerator; class cmMakefile; +class cmSourceFile; /** \class cmLocalCommonGenerator * \brief Common infrastructure for Makefile and Ninja local generators. @@ -30,6 +32,10 @@ public: std::string GetTargetFortranFlags(cmGeneratorTarget const* target, std::string const& config) override; + void ComputeObjectFilenames( + std::map<cmSourceFile const*, std::string>& mapping, + cmGeneratorTarget const* gt = nullptr) override; + protected: std::string WorkingDirectory; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 859aa44..afdcc84 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -553,14 +553,13 @@ void cmLocalGenerator::GenerateInstallRules() void cmLocalGenerator::AddGeneratorTarget(cmGeneratorTarget* gt) { this->GeneratorTargets.push_back(gt); - this->GeneratorTargetSearchIndex.insert( - std::pair<std::string, cmGeneratorTarget*>(gt->GetName(), gt)); + this->GeneratorTargetSearchIndex.emplace(gt->GetName(), gt); this->GlobalGenerator->IndexGeneratorTarget(gt); } void cmLocalGenerator::AddImportedGeneratorTarget(cmGeneratorTarget* gt) { - this->ImportedGeneratorTargets.push_back(gt); + this->ImportedGeneratorTargets.emplace(gt->GetName(), gt); this->GlobalGenerator->IndexGeneratorTarget(gt); } @@ -569,22 +568,6 @@ void cmLocalGenerator::AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt) this->OwnedImportedGeneratorTargets.push_back(gt); } -struct NamedGeneratorTargetFinder -{ - NamedGeneratorTargetFinder(std::string const& name) - : Name(name) - { - } - - bool operator()(cmGeneratorTarget* tgt) - { - return tgt->GetName() == this->Name; - } - -private: - std::string Name; -}; - cmGeneratorTarget* cmLocalGenerator::FindLocalNonAliasGeneratorTarget( const std::string& name) const { @@ -1395,11 +1378,10 @@ void cmLocalGenerator::AddLanguageFlagsForLinking( cmGeneratorTarget* cmLocalGenerator::FindGeneratorTargetToUse( const std::string& name) const { - std::vector<cmGeneratorTarget*>::const_iterator imported = std::find_if( - this->ImportedGeneratorTargets.begin(), - this->ImportedGeneratorTargets.end(), NamedGeneratorTargetFinder(name)); + GeneratorTargetMap::const_iterator imported = + this->ImportedGeneratorTargets.find(name); if (imported != this->ImportedGeneratorTargets.end()) { - return *imported; + return imported->second; } if (cmGeneratorTarget* t = this->FindLocalNonAliasGeneratorTarget(name)) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index a66fa6e..58bbe77 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -139,11 +139,6 @@ public: return this->GeneratorTargets; } - const std::vector<cmGeneratorTarget*>& GetImportedGeneratorTargets() const - { - return this->ImportedGeneratorTargets; - } - void AddGeneratorTarget(cmGeneratorTarget* gt); void AddImportedGeneratorTarget(cmGeneratorTarget* gt); void AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt); @@ -394,7 +389,7 @@ protected: std::vector<cmGeneratorTarget*> GeneratorTargets; std::set<cmGeneratorTarget const*> WarnCMP0063; - std::vector<cmGeneratorTarget*> ImportedGeneratorTargets; + GeneratorTargetMap ImportedGeneratorTargets; std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets; std::map<std::string, std::string> AliasTargets; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 2d969d2..8c889fc 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -246,20 +246,6 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os) os << "\n"; } -void cmLocalNinjaGenerator::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, - cmGeneratorTarget const* gt) -{ - // Determine if these object files should use a custom extension - char const* custom_ext = gt->GetCustomObjectExtension(); - for (auto& si : mapping) { - cmSourceFile const* sf = si.first; - bool keptSourceExtension; - si.second = this->GetObjectFileNameWithoutTarget( - *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext); - } -} - void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index bb16899..95d8a61 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -23,7 +23,6 @@ class cmGlobalGenerator; class cmGlobalNinjaGenerator; class cmMakefile; class cmRulePlaceholderExpander; -class cmSourceFile; class cmake; /** @@ -74,10 +73,6 @@ public: void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps); - void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, - cmGeneratorTarget const* gt = nullptr) override; - protected: std::string ConvertToIncludeReference( std::string const& path, diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index ff3fcfd..12682a7 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -150,20 +150,6 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath() } } -void cmLocalUnixMakefileGenerator3::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, - cmGeneratorTarget const* gt) -{ - // Determine if these object files should use a custom extension - char const* custom_ext = gt->GetCustomObjectExtension(); - for (auto& si : mapping) { - cmSourceFile const* sf = si.first; - bool keptSourceExtension; - si.second = this->GetObjectFileNameWithoutTarget( - *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext); - } -} - void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles( std::map<std::string, LocalObjectInfo>& localObjectFiles) { diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 86c5aab..2d580d5 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -19,7 +19,6 @@ class cmCustomCommandGenerator; class cmGeneratorTarget; class cmGlobalGenerator; class cmMakefile; -class cmSourceFile; /** \class cmLocalUnixMakefileGenerator3 * \brief Write a LocalUnix makefiles. @@ -252,10 +251,6 @@ protected: private: std::string MaybeConvertWatcomShellCommand(std::string const& cmd); - void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, - cmGeneratorTarget const* gt = nullptr) override; - friend class cmMakefileTargetGenerator; friend class cmMakefileExecutableTargetGenerator; friend class cmMakefileLibraryTargetGenerator; diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 69983a8..87ecc56 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -2,19 +2,21 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSourceGroupCommand.h" +#include <algorithm> #include <set> -#include <sstream> #include <stddef.h> +#include <utility> #include "cmMakefile.h" #include "cmSourceGroup.h" #include "cmSystemTools.h" namespace { -const size_t RootIndex = 1; -const size_t FilesWithoutPrefixKeywordIndex = 2; -const size_t FilesWithPrefixKeywordIndex = 4; -const size_t PrefixKeywordIndex = 2; +const std::string kTreeOptionName = "TREE"; +const std::string kPrefixOptionName = "PREFIX"; +const std::string kFilesOptionName = "FILES"; +const std::string kRegexOptionName = "REGULAR_EXPRESSION"; +const std::string kSourceGroupOptionName = "<sg_name>"; std::vector<std::string> tokenizePath(const std::string& path) { @@ -71,14 +73,13 @@ std::string prepareFilePathForTree(const std::string& path, } std::vector<std::string> prepareFilesPathsForTree( - std::vector<std::string>::const_iterator begin, - std::vector<std::string>::const_iterator end, + const std::vector<std::string>& filesPaths, const std::string& currentSourceDir) { std::vector<std::string> prepared; - for (; begin != end; ++begin) { - prepared.push_back(prepareFilePathForTree(*begin, currentSourceDir)); + for (auto const& filePath : filesPaths) { + prepared.push_back(prepareFilePathForTree(filePath, currentSourceDir)); } return prepared; @@ -121,6 +122,57 @@ bool addFilesToItsSourceGroups(const std::string& root, class cmExecutionStatus; // cmSourceGroupCommand +cmSourceGroupCommand::ExpectedOptions +cmSourceGroupCommand::getExpectedOptions() const +{ + ExpectedOptions options; + + options.push_back(kTreeOptionName); + options.push_back(kPrefixOptionName); + options.push_back(kFilesOptionName); + options.push_back(kRegexOptionName); + + return options; +} + +bool cmSourceGroupCommand::isExpectedOption( + const std::string& argument, const ExpectedOptions& expectedOptions) +{ + return std::find(expectedOptions.begin(), expectedOptions.end(), argument) != + expectedOptions.end(); +} + +void cmSourceGroupCommand::parseArguments( + const std::vector<std::string>& args, + cmSourceGroupCommand::ParsedArguments& parsedArguments) +{ + const ExpectedOptions expectedOptions = getExpectedOptions(); + size_t i = 0; + + // at this point we know that args vector is not empty + + // if first argument is not one of expected options it's source group name + if (!isExpectedOption(args[0], expectedOptions)) { + // get source group name and go to next argument + parsedArguments[kSourceGroupOptionName].push_back(args[0]); + ++i; + } + + for (; i < args.size();) { + // get current option and increment index to go to next argument + const std::string& currentOption = args[i++]; + + // create current option entry in parsed arguments + std::vector<std::string>& currentOptionArguments = + parsedArguments[currentOption]; + + // collect option arguments while we won't find another expected option + while (i < args.size() && !isExpectedOption(args[i], expectedOptions)) { + currentOptionArguments.push_back(args[i++]); + } + } +} + bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { @@ -129,114 +181,98 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, return false; } - if (args[0] == "TREE") { - std::string error; + // If only two arguments are given, the pre-1.8 version of the + // command is being invoked. + if (args.size() == 2 && args[1] != "FILES") { + cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); - if (!processTree(args, error)) { - this->SetError(error); + if (!sg) { + this->SetError("Could not create or find source group"); return false; } + sg->SetGroupRegex(args[1].c_str()); return true; } - cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); + ParsedArguments parsedArguments; + std::string errorMsg; - if (!sg) { - this->SetError("Could not create or find source group"); + parseArguments(args, parsedArguments); + + if (!checkArgumentsPreconditions(parsedArguments, errorMsg)) { return false; } - // If only two arguments are given, the pre-1.8 version of the - // command is being invoked. - if (args.size() == 2 && args[1] != "FILES") { - sg->SetGroupRegex(args[1].c_str()); - return true; - } - // Process arguments. - bool doingFiles = false; - for (unsigned int i = 1; i < args.size(); ++i) { - if (args[i] == "REGULAR_EXPRESSION") { - // Next argument must specify the regex. - if (i + 1 < args.size()) { - ++i; - sg->SetGroupRegex(args[i].c_str()); - } else { - this->SetError("REGULAR_EXPRESSION argument given without a regex."); - return false; - } - doingFiles = false; - } else if (args[i] == "FILES") { - // Next arguments will specify files. - doingFiles = true; - } else if (doingFiles) { - // Convert name to full path and add to the group's list. - std::string src = args[i]; + if (parsedArguments.find(kTreeOptionName) != parsedArguments.end()) { + if (!processTree(parsedArguments, errorMsg)) { + this->SetError(errorMsg); + return false; + } + } else { + if (parsedArguments.find(kSourceGroupOptionName) == + parsedArguments.end()) { + this->SetError("Missing source group name."); + return false; + } + + cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); + + if (!sg) { + this->SetError("Could not create or find source group"); + return false; + } + + // handle regex + if (parsedArguments.find(kRegexOptionName) != parsedArguments.end()) { + const std::string& sgRegex = parsedArguments[kRegexOptionName].front(); + sg->SetGroupRegex(sgRegex.c_str()); + } + + // handle files + const std::vector<std::string>& filesArguments = + parsedArguments[kFilesOptionName]; + for (auto const& filesArg : filesArguments) { + std::string src = filesArg; if (!cmSystemTools::FileIsFullPath(src.c_str())) { src = this->Makefile->GetCurrentSourceDirectory(); src += "/"; - src += args[i]; + src += filesArg; } src = cmSystemTools::CollapseFullPath(src); sg->AddGroupFile(src); - } else { - std::ostringstream err; - err << "Unknown argument \"" << args[i] << "\". " - << "Perhaps the FILES keyword is missing.\n"; - this->SetError(err.str()); - return false; } } return true; } -bool cmSourceGroupCommand::checkTreeArgumentsPreconditions( - const std::vector<std::string>& args, std::string& errorMsg) const +bool cmSourceGroupCommand::checkArgumentsPreconditions( + const ParsedArguments& parsedArguments, std::string& errorMsg) const { - if (args.size() == 1) { - errorMsg = "TREE argument given without a root."; - return false; - } - - if (args.size() < 3) { - errorMsg = "Missing FILES arguments."; - return false; - } - - if (args[FilesWithoutPrefixKeywordIndex] != "FILES" && - args[PrefixKeywordIndex] != "PREFIX") { - errorMsg = "Unknown argument \"" + args[2] + - "\". Perhaps the FILES keyword is missing.\n"; - return false; - } - - if (args[PrefixKeywordIndex] == "PREFIX" && - (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) { - errorMsg = "Missing FILES arguments."; + if (!checkSingleParameterArgumentPreconditions(kPrefixOptionName, + parsedArguments, errorMsg) || + !checkSingleParameterArgumentPreconditions(kTreeOptionName, + parsedArguments, errorMsg) || + !checkSingleParameterArgumentPreconditions(kRegexOptionName, + parsedArguments, errorMsg)) { return false; } return true; } -bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args, +bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, std::string& errorMsg) { - if (!checkTreeArgumentsPreconditions(args, errorMsg)) { - return false; - } - - const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]); - std::string prefix; - size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1; - if (args[PrefixKeywordIndex] == "PREFIX") { - prefix = args[PrefixKeywordIndex + 1]; - filesBegin = FilesWithPrefixKeywordIndex + 1; - } + const std::string root = + cmSystemTools::CollapseFullPath(parsedArguments[kTreeOptionName].front()); + std::string prefix = parsedArguments[kPrefixOptionName].empty() + ? "" + : parsedArguments[kPrefixOptionName].front(); const std::vector<std::string> filesVector = - prepareFilesPathsForTree(args.begin() + filesBegin, args.end(), + prepareFilesPathsForTree(parsedArguments[kFilesOptionName], this->Makefile->GetCurrentSourceDirectory()); if (!rootIsPrefix(root, filesVector, errorMsg)) { @@ -253,3 +289,25 @@ bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args, return true; } + +bool cmSourceGroupCommand::checkSingleParameterArgumentPreconditions( + const std::string& argument, const ParsedArguments& parsedArguments, + std::string& errorMsg) const +{ + ParsedArguments::const_iterator foundArgument = + parsedArguments.find(argument); + if (foundArgument != parsedArguments.end()) { + const std::vector<std::string>& optionArguments = foundArgument->second; + + if (optionArguments.empty()) { + errorMsg = argument + " argument given without an argument."; + return false; + } + if (optionArguments.size() > 1) { + errorMsg = "too many arguments passed to " + argument + "."; + return false; + } + } + + return true; +} diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index ed02ca5..ec5ad32 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <map> #include <string> #include <vector> @@ -34,10 +35,24 @@ public: cmExecutionStatus& status) override; private: - bool processTree(const std::vector<std::string>& args, - std::string& errorMsg); - bool checkTreeArgumentsPreconditions(const std::vector<std::string>& args, - std::string& errorMsg) const; + typedef std::map<std::string, std::vector<std::string>> ParsedArguments; + typedef std::vector<std::string> ExpectedOptions; + + ExpectedOptions getExpectedOptions() const; + + bool isExpectedOption(const std::string& argument, + const ExpectedOptions& expectedOptions); + + void parseArguments(const std::vector<std::string>& args, + cmSourceGroupCommand::ParsedArguments& parsedArguments); + + bool processTree(ParsedArguments& parsedArguments, std::string& errorMsg); + + bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, + std::string& errorMsg) const; + bool checkSingleParameterArgumentPreconditions( + const std::string& argument, const ParsedArguments& parsedArguments, + std::string& errorMsg) const; }; #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index e15e833..9115eb7 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2078,9 +2078,15 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( (*this->BuildFileStream) << firstString; firstString = ""; hasFlags = true; - this->WriteString("<ObjectFileName>", 3); - (*this->BuildFileStream) << "$(IntDir)/" << objectName - << "</ObjectFileName>\n"; + if (lang == "CUDA") { + this->WriteString("<CompileOut>", 3); + (*this->BuildFileStream) << "$(IntDir)/" << objectName + << "</CompileOut>\n"; + } else { + this->WriteString("<ObjectFileName>", 3); + (*this->BuildFileStream) << "$(IntDir)/" << objectName + << "</ObjectFileName>\n"; + } } for (std::string const& config : this->Configurations) { std::string configUpper = cmSystemTools::UpperCase(config); @@ -2169,9 +2175,9 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( clOptions.AddIncludes(includeList); clOptions.SetConfiguration(config.c_str()); clOptions.PrependInheritedString("AdditionalOptions"); - clOptions.OutputFlagMap(*this->BuildFileStream, " "); clOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, " ", "\n", lang); + clOptions.OutputFlagMap(*this->BuildFileStream, " "); clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", "\n", lang); } @@ -2535,9 +2541,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( } this->WriteString("<ClCompile>\n", 2); clOptions.PrependInheritedString("AdditionalOptions"); - clOptions.OutputFlagMap(*this->BuildFileStream, " "); clOptions.OutputAdditionalIncludeDirectories( *this->BuildFileStream, " ", "\n", this->LangForClCompile); + clOptions.OutputFlagMap(*this->BuildFileStream, " "); clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", "\n", this->LangForClCompile); @@ -2688,6 +2694,11 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddFlag("GPUDebugInfo", "false"); } + // The extension on object libraries the CUDA gives isn't + // consistent with how MSVC generates object libraries for C+, so set + // the default to not have any extension + cudaOptions.AddFlag("CompileOut", "$(IntDir)%(Filename).obj"); + bool notPtx = true; if (this->GeneratorTarget->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { cudaOptions.AddFlag("GenerateRelocatableDeviceCode", "true"); diff --git a/Tests/Cuda/ObjectLibrary/CMakeLists.txt b/Tests/Cuda/ObjectLibrary/CMakeLists.txt index 276dc92..da5fb87 100644 --- a/Tests/Cuda/ObjectLibrary/CMakeLists.txt +++ b/Tests/Cuda/ObjectLibrary/CMakeLists.txt @@ -1,15 +1,18 @@ cmake_minimum_required(VERSION 3.7) project (CudaObjectLibrary CUDA CXX) #Goal for this example: - -#build a object files some with cuda and some without than -#embed these into an executable +# +#Build C++ and CUDA object files and than use them to make an executable +#Make sure that CMake logic to handle object output when multiple files +#with the same name works +add_subdirectory(Conflicts) add_library(CudaMixedObjectLib OBJECT static.cu static.cpp) add_executable(CudaObjectLibrary main.cpp - $<TARGET_OBJECTS:CudaMixedObjectLib>) + $<TARGET_OBJECTS:CudaMixedObjectLib> + $<TARGET_OBJECTS:CudaConflicts>) if(APPLE) # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. diff --git a/Tests/Cuda/ObjectLibrary/Conflicts/CMakeLists.txt b/Tests/Cuda/ObjectLibrary/Conflicts/CMakeLists.txt new file mode 100644 index 0000000..1602f8a --- /dev/null +++ b/Tests/Cuda/ObjectLibrary/Conflicts/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_library(CudaConflicts OBJECT static.cu) diff --git a/Tests/Cuda/ObjectLibrary/Conflicts/static.cu b/Tests/Cuda/ObjectLibrary/Conflicts/static.cu new file mode 100644 index 0000000..586e8c6 --- /dev/null +++ b/Tests/Cuda/ObjectLibrary/Conflicts/static.cu @@ -0,0 +1,17 @@ + +#include <cuda.h> +#include <cuda_runtime.h> +#include <iostream> + +int __host__ cu2_sq_func(int x) +{ + cudaError_t err; + int nDevices = 0; + err = cudaGetDeviceCount(&nDevices); + if (err != cudaSuccess) { + std::cerr << "nDevices: " << nDevices << std::endl; + std::cerr << "err: " << err << std::endl; + return 1; + } + return x * x; +} diff --git a/Tests/Cuda/ObjectLibrary/main.cpp b/Tests/Cuda/ObjectLibrary/main.cpp index 4d2f890..e28f088 100644 --- a/Tests/Cuda/ObjectLibrary/main.cpp +++ b/Tests/Cuda/ObjectLibrary/main.cpp @@ -1,22 +1,18 @@ #include <iostream> -int static_func(int); -int file1_sq_func(int); +int cpp_sq_func(int); +int cu1_sq_func(int); +int cu2_sq_func(int); -int test_functions() +bool test_functions() { - return file1_sq_func(static_func(42)); + return (cu1_sq_func(42) == cpp_sq_func(42)) && + (cu2_sq_func(42) == cpp_sq_func(42)); } int main(int argc, char** argv) { - if (test_functions() == 1) { - return 1; - } - std::cout - << "this executable doesn't use cuda code, just call methods defined" - << std::endl; - std::cout << "in object files that have cuda code" << std::endl; - return 0; + int result = test_functions() ? 0 : 1; + return result; } diff --git a/Tests/Cuda/ObjectLibrary/static.cpp b/Tests/Cuda/ObjectLibrary/static.cpp index 6db1f91..527f7f5 100644 --- a/Tests/Cuda/ObjectLibrary/static.cpp +++ b/Tests/Cuda/ObjectLibrary/static.cpp @@ -1,6 +1,6 @@ int file1_sq_func(int); -int static_func(int x) +int cpp_sq_func(int x) { - return file1_sq_func(x); + return x * x; } diff --git a/Tests/Cuda/ObjectLibrary/static.cu b/Tests/Cuda/ObjectLibrary/static.cu index aa35729..37bb839 100644 --- a/Tests/Cuda/ObjectLibrary/static.cu +++ b/Tests/Cuda/ObjectLibrary/static.cu @@ -3,7 +3,7 @@ #include <cuda_runtime.h> #include <iostream> -int __host__ file1_sq_func(int x) +int __host__ cu1_sq_func(int x) { cudaError_t err; int nDevices = 0; @@ -13,9 +13,5 @@ int __host__ file1_sq_func(int x) std::cerr << "err: " << err << std::endl; return 1; } - std::cout << "this library uses cuda code" << std::endl; - std::cout << "you have " << nDevices << " devices that support cuda" - << std::endl; - return x * x; } diff --git a/Tests/SourceGroups/CMakeLists.txt b/Tests/SourceGroups/CMakeLists.txt index 4e4a030..813774d 100644 --- a/Tests/SourceGroups/CMakeLists.txt +++ b/Tests/SourceGroups/CMakeLists.txt @@ -39,9 +39,15 @@ set(tree_files_without_prefix ${root}/sub1/tree_bar.c set(tree_files_with_prefix ${root}/tree_prefix_foo.c tree_prefix_bar.c) +set(tree_files_with_empty_prefix ${root}/tree_empty_prefix_foo.c + tree_empty_prefix_bar.c) + source_group(TREE ${root} FILES ${tree_files_without_prefix}) -source_group(TREE ${root} PREFIX tree_root/subgroup FILES ${tree_files_with_prefix}) +source_group(FILES ${tree_files_with_prefix} PREFIX tree_root/subgroup TREE ${root}) + +source_group(PREFIX "" FILES ${tree_files_with_empty_prefix} TREE ${root}) add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c - ${tree_files_with_prefix} ${tree_files_without_prefix} README.txt) + ${tree_files_with_prefix} ${tree_files_without_prefix} + ${tree_files_with_empty_prefix} README.txt) diff --git a/Tests/SourceGroups/main.c b/Tests/SourceGroups/main.c index 4d84cf2..87225f5 100644 --- a/Tests/SourceGroups/main.c +++ b/Tests/SourceGroups/main.c @@ -7,6 +7,8 @@ extern int barbar(void); extern int baz(void); extern int tree_prefix_foo(void); extern int tree_prefix_bar(void); +extern int tree_empty_prefix_foo(void); +extern int tree_empty_prefix_bar(void); extern int tree_bar(void); extern int tree_foobar(void); extern int tree_baz(void); @@ -17,8 +19,9 @@ int main() foobar(), barbar(), baz()); printf("tree_prefix_foo: %d tree_prefix_bar: %d tree_bar: %d tree_foobar: " - "%d tree_baz: %d\n", + "%d tree_baz: %d tree_empty_prefix_foo: %d " + "tree_empty_prefix_bar: %d\n", tree_prefix_foo(), tree_prefix_bar(), tree_bar(), tree_foobar(), - tree_baz()); + tree_baz(), tree_empty_prefix_foo(), tree_empty_prefix_bar()); return 0; } diff --git a/Tests/SourceGroups/tree_empty_prefix_bar.c b/Tests/SourceGroups/tree_empty_prefix_bar.c new file mode 100644 index 0000000..d974c6e --- /dev/null +++ b/Tests/SourceGroups/tree_empty_prefix_bar.c @@ -0,0 +1,4 @@ +int tree_empty_prefix_bar(void) +{ + return 66; +} diff --git a/Tests/SourceGroups/tree_empty_prefix_foo.c b/Tests/SourceGroups/tree_empty_prefix_foo.c new file mode 100644 index 0000000..277cbd4 --- /dev/null +++ b/Tests/SourceGroups/tree_empty_prefix_foo.c @@ -0,0 +1,4 @@ +int tree_empty_prefix_foo(void) +{ + return 6; +} |