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
This commit is contained in:
Deniz Bahadir 2017-10-19 14:31:10 +02:00 committed by Brad King
parent 6e4e7c6547
commit 4e7f67383f
24 changed files with 97 additions and 75 deletions

View File

@ -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

View File

@ -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

View File

@ -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`.

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -539,6 +539,8 @@ private:
virtual void ForceLinkerLanguages();
bool CheckTargetsForMissingSources() const;
void CreateLocalGenerators();
void CheckCompilerIdCompatibility(cmMakefile* mf,

View File

@ -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\)$

View File

@ -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\)$

View File

@ -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\)$

View File

@ -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\)$

View File

@ -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\)$

View File

@ -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$

View File

@ -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\)$

View File

@ -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\):

View File

@ -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:
[^

View File

@ -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\)$

View File

@ -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\)$

View File

@ -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$

View File

@ -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\)$

View File

@ -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\)$

View File

@ -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$