ソースを参照

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
Deniz Bahadir 8 年 前
コミット
4e7f67383f
24 ファイル変更97 行追加75 行削除
  1. 7 6
      Help/command/add_executable.rst
  2. 6 5
      Help/command/add_library.rst
  3. 6 0
      Help/release/dev/defer-target-source-check.rst
  4. 1 7
      Source/cmAddExecutableCommand.cxx
  5. 0 8
      Source/cmAddLibraryCommand.cxx
  6. 42 0
      Source/cmGlobalGenerator.cxx
  7. 2 0
      Source/cmGlobalGenerator.h
  8. 1 1
      Tests/RunCMake/add_executable/NoSources-stderr.txt
  9. 1 8
      Tests/RunCMake/add_executable/NoSourcesButLinkObjects-stderr.txt
  10. 0 1
      Tests/RunCMake/add_executable/OnlyObjectSources-result.txt
  11. 0 11
      Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt
  12. 4 3
      Tests/RunCMake/add_library/MODULEwithNoSources-stderr.txt
  13. 4 3
      Tests/RunCMake/add_library/MODULEwithNoSourcesButLinkObjects-stderr.txt
  14. 0 1
      Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt
  15. 1 1
      Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt
  16. 4 2
      Tests/RunCMake/add_library/OBJECTwithNoSources-stderr.txt
  17. 1 2
      Tests/RunCMake/add_library/OBJECTwithNoSourcesButLinkObjects-stderr.txt
  18. 1 2
      Tests/RunCMake/add_library/OBJECTwithOnlyObjectSources-stderr.txt
  19. 4 3
      Tests/RunCMake/add_library/SHAREDwithNoSources-stderr.txt
  20. 4 3
      Tests/RunCMake/add_library/SHAREDwithNoSourcesButLinkObjects-stderr.txt
  21. 0 1
      Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt
  22. 4 3
      Tests/RunCMake/add_library/STATICwithNoSources-stderr.txt
  23. 4 3
      Tests/RunCMake/add_library/STATICwithNoSourcesButLinkObjects-stderr.txt
  24. 0 1
      Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt

+ 7 - 6
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

+ 6 - 5
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

+ 6 - 0
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`.

+ 1 - 7
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);

+ 0 - 8
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);

+ 42 - 0
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.

+ 2 - 0
Source/cmGlobalGenerator.h

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

+ 1 - 1
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\)$

+ 1 - 8
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\)$

+ 0 - 1
Tests/RunCMake/add_executable/OnlyObjectSources-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 11
Tests/RunCMake/add_executable/OnlyObjectSources-stderr.txt

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

+ 4 - 3
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\)$

+ 4 - 3
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\)$

+ 0 - 1
Tests/RunCMake/add_library/MODULEwithOnlyObjectSources-stderr.txt

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

+ 1 - 1
Tests/RunCMake/add_library/OBJECTwithNoSources-result.txt

@@ -1 +1 @@
-.
+1

+ 4 - 2
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\)$

+ 1 - 2
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\):

+ 1 - 2
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:
 
     [^

+ 4 - 3
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\)$

+ 4 - 3
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\)$

+ 0 - 1
Tests/RunCMake/add_library/SHAREDwithOnlyObjectSources-stderr.txt

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

+ 4 - 3
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\)$

+ 4 - 3
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\)$

+ 0 - 1
Tests/RunCMake/add_library/STATICwithOnlyObjectSources-stderr.txt

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