diff options
author | Deniz Bahadir <dbahadir@benocs.com> | 2017-10-19 14:31:10 +0200 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-10-24 08:14:47 -0400 |
commit | 4e7f67383f297d708efbb6640c9bee188a127d4e (patch) | |
tree | 4aba6cacdf3974f6bfbb4cb5908a37011a5ed33c | |
parent | 6e4e7c6547fb4d379d564340d015af20e4a4e892 (diff) | |
download | cmake-4e7f67383f297d708efbb6640c9bee188a127d4e.tar.gz |
Defer check for sources within a target until generation.
The `add_library` and `add_executable` commands can now be called with
no source-files and won't generate a warning or error message, as long
as source-files will be added later via the `target_sources` command.
If during the generation step still no sources are associated with
targets created by such calls a useful error message will be generated
and generation fails.
Targets of type `INTERFACE_LIBRARY`, `UTILITY` or `GLOBAL_TARGET` are
excluded from this check because we do not need sources for these target
types during generation.
Fixes: #16872
24 files changed, 97 insertions, 75 deletions
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst index c088796e43..6763620b80 100644 --- a/Help/command/add_executable.rst +++ b/Help/command/add_executable.rst @@ -7,14 +7,15 @@ Add an executable to the project using the specified source files. add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] - source1 [source2 ...]) + [source1] [source2 ...]) Adds an executable target called ``<name>`` to be built from the source -files listed in the command invocation. The ``<name>`` corresponds to the -logical target name and must be globally unique within a project. The -actual file name of the executable built is constructed based on -conventions of the native platform (such as ``<name>.exe`` or just -``<name>``). +files listed in the command invocation. (The source files can be omitted +here if they are added later using :command:`target_sources`.) The +``<name>`` corresponds to the logical target name and must be globally +unique within a project. The actual file name of the executable built is +constructed based on conventions of the native platform (such as +``<name>.exe`` or just ``<name>``). By default the executable file will be created in the build tree directory corresponding to the source tree directory in which the diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst index de5335efff..78b316d2ed 100644 --- a/Help/command/add_library.rst +++ b/Help/command/add_library.rst @@ -14,13 +14,14 @@ Normal Libraries add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] - source1 [source2 ...]) + [source1] [source2 ...]) Adds a library target called ``<name>`` to be built from the source files -listed in the command invocation. The ``<name>`` corresponds to the -logical target name and must be globally unique within a project. The -actual file name of the library built is constructed based on -conventions of the native platform (such as ``lib<name>.a`` or +listed in the command invocation. (The source files can be omitted here +if they are added later using :command:`target_sources`.) The ``<name>`` +corresponds to the logical target name and must be globally unique within +a project. The actual file name of the library built is constructed based +on conventions of the native platform (such as ``lib<name>.a`` or ``<name>.lib``). ``STATIC``, ``SHARED``, or ``MODULE`` may be given to specify the type of diff --git a/Help/release/dev/defer-target-source-check.rst b/Help/release/dev/defer-target-source-check.rst new file mode 100644 index 0000000000..65f5488271 --- /dev/null +++ b/Help/release/dev/defer-target-source-check.rst @@ -0,0 +1,6 @@ +defer-target-source-check +------------------------- + +* :command:`add_library` and :command:`add_executable` commands can now be + called without any sources and will not complain as long as sources will + be added later via :command:`target_sources`. diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index 1d0376fe04..262e3a1356 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -18,7 +18,7 @@ class cmExecutionStatus; bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { - if (args.size() < 2) { + if (args.empty()) { this->SetError("called with incorrect number of arguments"); return false; } @@ -191,12 +191,6 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, } } - if (s == args.end()) { - this->SetError( - "called with incorrect number of arguments, no sources provided"); - return false; - } - std::vector<std::string> srclists(s, args.end()); cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists, excludeFromAll); diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index ebf17632a3..31c2ecfcec 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -362,14 +362,6 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, return true; } - if (s == args.end()) { - std::string msg = "You have called ADD_LIBRARY for library "; - msg += args[0]; - msg += " without any source files. This typically indicates a problem "; - msg += "with your CMakeLists.txt file"; - cmSystemTools::Message(msg.c_str(), "Warning"); - } - srclists.insert(srclists.end(), s, args.end()); this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 38669c9ab4..000309f1df 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -261,6 +261,43 @@ void cmGlobalGenerator::ForceLinkerLanguages() { } +bool cmGlobalGenerator::CheckTargetsForMissingSources() const +{ + bool failed = false; + for (cmLocalGenerator* localGen : this->LocalGenerators) { + const std::vector<cmGeneratorTarget*>& targets = + localGen->GetGeneratorTargets(); + + for (cmGeneratorTarget* target : targets) { + if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET || + target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY || + target->GetType() == cmStateEnums::TargetType::UTILITY) { + continue; + } + + std::vector<std::string> configs; + target->Makefile->GetConfigurations(configs); + std::vector<cmSourceFile*> srcs; + if (configs.empty()) { + target->GetSourceFiles(srcs, ""); + } else { + for (std::vector<std::string>::const_iterator ci = configs.begin(); + ci != configs.end() && srcs.empty(); ++ci) { + target->GetSourceFiles(srcs, *ci); + } + } + if (srcs.empty()) { + std::ostringstream e; + e << "No SOURCES given to target: " << target->GetName(); + this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, e.str(), + target->GetBacktrace()); + failed = true; + } + } + } + return failed; +} + bool cmGlobalGenerator::IsExportedTargetsFile( const std::string& filename) const { @@ -1292,6 +1329,11 @@ bool cmGlobalGenerator::Compute() localGen->TraceDependencies(); } + // Make sure that all (non-imported) targets have source files added! + if (this->CheckTargetsForMissingSources()) { + return false; + } + this->ForceLinkerLanguages(); // Compute the manifest of main targets generated. diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 04e9dc16e9..1f90ecf044 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -539,6 +539,8 @@ private: virtual void ForceLinkerLanguages(); + bool CheckTargetsForMissingSources() const; + void CreateLocalGenerators(); void CheckCompilerIdCompatibility(cmMakefile* mf, diff --git a/Tests/RunCMake/add_executable/NoSources-stderr.txt b/Tests/RunCMake/add_executable/NoSources-stderr.txt index 5985905951..4fcfd49918 100644 --- a/Tests/RunCMake/add_executable/NoSources-stderr.txt +++ b/Tests/RunCMake/add_executable/NoSources-stderr.txt @@ -1,4 +1,4 @@ ^CMake Error at NoSources.cmake:[0-9]+ \(add_executable\): - add_executable called with incorrect number of arguments + No SOURCES given to target: TestExeWithoutSources Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt index c8afadb06d..5561daa398 100644 --- a/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt +++ b/Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt @@ -1,11 +1,4 @@ ^CMake Error at NoSourcesButLinkObjects.cmake:[0-9]+ \(add_executable\): - add_executable called with incorrect number of arguments -Call Stack \(most recent call first\): - CMakeLists.txt:[0-9]+ \(include\) - - -CMake Error at NoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\): - Cannot specify link libraries for target \"TestExeWithoutSources\" which is - not built by this project. + No SOURCES given to target: TestExeWithoutSources Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_executable/OnlyObjectSources-result.txt b/Tests/RunCMake/add_executable/OnlyObjectSources-result.txt deleted file mode 100644 index d00491fd7e..0000000000 --- a/Tests/RunCMake/add_executable/OnlyObjectSources-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt b/Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt deleted file mode 100644 index ea72d5dea7..0000000000 --- a/Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt +++ /dev/null @@ -1,11 +0,0 @@ -^CMake Error at OnlyObjectSources.cmake:[0-9]+ \(add_executable\): - add_executable called with incorrect number of arguments -Call Stack \(most recent call first\): - CMakeLists.txt:[0-9]+ \(include\) - - -CMake Error at OnlyObjectSources.cmake:[0-9]+ \(target_sources\): - Cannot specify sources for target \"TestExeWithoutSources\" which is not - built by this project. -Call Stack \(most recent call first\): - CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt b/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt index 5cf0b1e8dc..41da381016 100644 --- a/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt +++ b/Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt @@ -1,3 +1,4 @@ -^You have called ADD_LIBRARY for library TestModuleLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: CMake can not determine linker language for target: TestModuleLibWithoutSources)+( -CMake Error: Cannot determine link language for target \"TestModuleLibWithoutSources\".)?$ +^CMake Error at MODULEwithNoSources.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestModuleLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt index 951594a563..67dd87c3fc 100644 --- a/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt +++ b/Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt @@ -1,3 +1,4 @@ -^You have called ADD_LIBRARY for library TestModuleLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: CMake can not determine linker language for target: TestModuleLibWithoutSources)+( -CMake Error: Cannot determine link language for target \"TestModuleLibWithoutSources\".)*$ +^CMake Error at MODULEwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestModuleLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt deleted file mode 100644 index de837554e5..0000000000 --- a/Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^You have called ADD_LIBRARY for library TestModuleLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file$ diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt b/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt index 9c558e357c..d00491fd7e 100644 --- a/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt +++ b/Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt @@ -1 +1 @@ -. +1 diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt index 099ec4fadf..20d3a8a847 100644 --- a/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt +++ b/Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt @@ -1,2 +1,4 @@ -^You have called ADD_LIBRARY for library TestObjectLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: CMake can not determine linker language for target: TestObjectLibWithoutSources)*$ +^CMake Error at OBJECTwithNoSources.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestObjectLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt index 8f20096167..cd6f1e0528 100644 --- a/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt +++ b/Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt @@ -1,5 +1,4 @@ -^You have called ADD_LIBRARY for library TestObjectLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file -CMake Error at OBJECTwithNoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\): +^CMake Error at OBJECTwithNoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\): Object library target \"TestObjectLibWithoutSources\" may not link to anything. Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt index f9cbf6b7da..77a72f1097 100644 --- a/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt +++ b/Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt @@ -1,5 +1,4 @@ -^You have called ADD_LIBRARY for library TestObjectLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file -CMake Error at OBJECTwithOnlyObjectSources.cmake:[0-9]+ \(add_library\): +^CMake Error at OBJECTwithOnlyObjectSources.cmake:[0-9]+ \(add_library\): OBJECT library \"TestObjectLibWithoutSources\" contains: [^ diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt index 228d1cc95a..5cedd62d0b 100644 --- a/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt +++ b/Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt @@ -1,3 +1,4 @@ -^You have called ADD_LIBRARY for library TestSharedLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: CMake can not determine linker language for target: TestSharedLibWithoutSources)+( -CMake Error: Cannot determine link language for target \"TestSharedLibWithoutSources\".)*$ +^CMake Error at SHAREDwithNoSources.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestSharedLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt index 228d1cc95a..d621e76774 100644 --- a/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt +++ b/Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt @@ -1,3 +1,4 @@ -^You have called ADD_LIBRARY for library TestSharedLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: CMake can not determine linker language for target: TestSharedLibWithoutSources)+( -CMake Error: Cannot determine link language for target \"TestSharedLibWithoutSources\".)*$ +^CMake Error at SHAREDwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestSharedLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt deleted file mode 100644 index ec350cd44d..0000000000 --- a/Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^You have called ADD_LIBRARY for library TestSharedLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file$ diff --git a/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt b/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt index 830eb221f7..10b211280b 100644 --- a/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt +++ b/Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt @@ -1,3 +1,4 @@ -^You have called ADD_LIBRARY for library TestStaticLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: Cannot determine link language for target \"TestStaticLibWithoutSources\".)?( -CMake Error: CMake can not determine linker language for target: TestStaticLibWithoutSources)+$ +^CMake Error at STATICwithNoSources.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestStaticLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt index 830eb221f7..33c23b2f3c 100644 --- a/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt +++ b/Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt @@ -1,3 +1,4 @@ -^You have called ADD_LIBRARY for library TestStaticLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file( -CMake Error: Cannot determine link language for target \"TestStaticLibWithoutSources\".)?( -CMake Error: CMake can not determine linker language for target: TestStaticLibWithoutSources)+$ +^CMake Error at STATICwithNoSourcesButLinkObjects.cmake:[0-9]+ \(add_library\): + No SOURCES given to target: TestStaticLibWithoutSources +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt deleted file mode 100644 index 5cd10d4fc8..0000000000 --- a/Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^You have called ADD_LIBRARY for library TestStaticLibWithoutSources without any source files. This typically indicates a problem with your CMakeLists.txt file$ |