فهرست منبع

Merge topic 'target-sources-error-conditions'

8a75c7ef Help: Document the export limitation of INTERFACE_SOURCES.
e1348056 Export: Disallow export of targets with INTERFACE_SOURCES
bb5905bb cmTarget: Don't allow relative paths in INTERFACE_SOURCES
Brad King 11 سال پیش
والد
کامیت
8e75f1d2fa

+ 4 - 0
Help/command/target_sources.rst

@@ -22,6 +22,10 @@ items will populate the :prop_tgt:`SOURCES` property of
 following arguments specify sources.  Repeated calls for the same
 following arguments specify sources.  Repeated calls for the same
 ``<target>`` append items in the order called.
 ``<target>`` append items in the order called.
 
 
+Targets with :prop_tgt:`INTERFACE_SOURCES` may not be exported with the
+:command:`export` or :command:`install(EXPORT)` commands. This limitation may be
+lifted in a future version of CMake.
+
 Arguments to ``target_sources`` may use "generator expressions"
 Arguments to ``target_sources`` may use "generator expressions"
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`

+ 4 - 0
Help/prop_tgt/INTERFACE_SOURCES.rst

@@ -12,6 +12,10 @@ When target dependencies are specified using :command:`target_link_libraries`,
 CMake will read this property from all target dependencies to determine the
 CMake will read this property from all target dependencies to determine the
 sources of the consumer.
 sources of the consumer.
 
 
+Targets with ``INTERFACE_SOURCES`` may not be exported with the
+:command:`export` or :command:`install(EXPORT)` commands. This limitation may be
+lifted in a future version of CMake.
+
 Contents of ``INTERFACE_SOURCES`` may use "generator expressions"
 Contents of ``INTERFACE_SOURCES`` may use "generator expressions"
 with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
 with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`

+ 10 - 0
Source/cmExportBuildFileGenerator.cxx

@@ -68,6 +68,16 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
       tei != this->Exports.end(); ++tei)
       tei != this->Exports.end(); ++tei)
     {
     {
     cmTarget* te = *tei;
     cmTarget* te = *tei;
+    if (te->GetProperty("INTERFACE_SOURCES"))
+      {
+      cmOStringStream e;
+      e << "Target \""
+        << te->GetName()
+        << "\" has a populated INTERFACE_SOURCES property.  This is not "
+          "currently supported.";
+      cmSystemTools::Error(e.str().c_str());
+      return false;
+      }
     this->GenerateImportTargetCode(os, te);
     this->GenerateImportTargetCode(os, te);
 
 
     te->AppendBuildInterfaceIncludes();
     te->AppendBuildInterfaceIncludes();

+ 11 - 0
Source/cmExportInstallFileGenerator.cxx

@@ -123,6 +123,17 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
     {
     {
     cmTarget* te = (*tei)->Target;
     cmTarget* te = (*tei)->Target;
 
 
+    if (te->GetProperty("INTERFACE_SOURCES"))
+      {
+      cmOStringStream e;
+      e << "Target \""
+        << te->GetName()
+        << "\" has a populated INTERFACE_SOURCES property.  This is not "
+          "currently supported.";
+      cmSystemTools::Error(e.str().c_str());
+      return false;
+      }
+
     requiresConfigFiles = requiresConfigFiles
     requiresConfigFiles = requiresConfigFiles
                               || te->GetType() != cmTarget::INTERFACE_LIBRARY;
                               || te->GetType() != cmTarget::INTERFACE_LIBRARY;
 
 

+ 23 - 3
Source/cmTarget.cxx

@@ -649,6 +649,8 @@ static bool processSources(cmTarget const* tgt,
   for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
   for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
       it = entries.begin(), end = entries.end(); it != end; ++it)
       it = entries.begin(), end = entries.end(); it != end; ++it)
     {
     {
+    cmLinkImplItem const& item = (*it)->LinkImplItem;
+    std::string const& targetName = item;
     std::vector<std::string> entrySources;
     std::vector<std::string> entrySources;
     cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
     cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
                                               config,
                                               config,
@@ -667,11 +669,10 @@ static bool processSources(cmTarget const* tgt,
         i != entrySources.end(); ++i)
         i != entrySources.end(); ++i)
       {
       {
       std::string& src = *i;
       std::string& src = *i;
-
       cmSourceFile* sf = mf->GetOrCreateSource(src);
       cmSourceFile* sf = mf->GetOrCreateSource(src);
       std::string e;
       std::string e;
-      src = sf->GetFullPath(&e);
-      if(src.empty())
+      std::string fullPath = sf->GetFullPath(&e);
+      if(fullPath.empty())
         {
         {
         if(!e.empty())
         if(!e.empty())
           {
           {
@@ -681,6 +682,25 @@ static bool processSources(cmTarget const* tgt,
           }
           }
         return contextDependent;
         return contextDependent;
         }
         }
+
+      if (!targetName.empty() && !cmSystemTools::FileIsFullPath(src.c_str()))
+        {
+        cmOStringStream err;
+        if (!targetName.empty())
+          {
+          err << "Target \"" << targetName << "\" contains relative "
+            "path in its INTERFACE_SOURCES:\n"
+            "  \"" << src << "\"";
+          }
+        else
+          {
+          err << "Found relative path while evaluating sources of "
+          "\"" << tgt->GetName() << "\":\n  \"" << src << "\"\n";
+          }
+        tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, err.str());
+        return contextDependent;
+        }
+      src = fullPath;
       }
       }
     std::string usedSources;
     std::string usedSources;
     for(std::vector<std::string>::iterator
     for(std::vector<std::string>::iterator

+ 3 - 3
Tests/ConfigSources/CMakeLists.txt

@@ -5,9 +5,9 @@ project(ConfigSources)
 
 
 add_library(iface INTERFACE)
 add_library(iface INTERFACE)
 set_property(TARGET iface PROPERTY INTERFACE_SOURCES
 set_property(TARGET iface PROPERTY INTERFACE_SOURCES
-  iface_src.cpp
-  $<$<CONFIG:Debug>:iface_debug_src.cpp>
-  $<$<CONFIG:Release>:does_not_exist.cpp>
+  "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
+  "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp>"
+  "$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist.cpp>"
 )
 )
 
 
 add_executable(ConfigSources
 add_executable(ConfigSources

+ 1 - 0
Tests/RunCMake/TargetSources/ExportBuild-result.txt

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

+ 1 - 0
Tests/RunCMake/TargetSources/ExportBuild-stderr.txt

@@ -0,0 +1 @@
+CMake Error: Target "iface" has a populated INTERFACE_SOURCES property.  This is not currently supported.

+ 5 - 0
Tests/RunCMake/TargetSources/ExportBuild.cmake

@@ -0,0 +1,5 @@
+
+add_library(iface INTERFACE)
+target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp")
+
+export(TARGETS iface FILE ${CMAKE_CURRENT_BINARY_DIR}/targets.cmake)

+ 1 - 0
Tests/RunCMake/TargetSources/ExportInstall-result.txt

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

+ 1 - 0
Tests/RunCMake/TargetSources/ExportInstall-stderr.txt

@@ -0,0 +1 @@
+CMake Error: Target "iface" has a populated INTERFACE_SOURCES property.  This is not currently supported.

+ 6 - 0
Tests/RunCMake/TargetSources/ExportInstall.cmake

@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp")
+
+install(TARGETS iface EXPORT exp)
+install(EXPORT exp DESTINATION cmake)

+ 1 - 1
Tests/RunCMake/TargetSources/OriginDebug.cmake

@@ -7,7 +7,7 @@ set(CMAKE_DEBUG_TARGET_PROPERTIES SOURCES)
 
 
 add_library(iface INTERFACE)
 add_library(iface INTERFACE)
 set_property(TARGET iface PROPERTY INTERFACE_SOURCES
 set_property(TARGET iface PROPERTY INTERFACE_SOURCES
-  empty_1.cpp
+  "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp"
 )
 )
 
 
 add_library(OriginDebug empty_2.cpp)
 add_library(OriginDebug empty_2.cpp)

+ 1 - 0
Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt

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

+ 4 - 0
Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error in CMakeLists.txt:
+  Target "iface" contains relative path in its INTERFACE_SOURCES:
+
+    "empty_1.cpp"

+ 6 - 0
Tests/RunCMake/TargetSources/RelativePathInInterface.cmake

@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+target_sources(iface INTERFACE empty_1.cpp)
+
+add_executable(main main.cpp)
+target_link_libraries(main iface)

+ 3 - 0
Tests/RunCMake/TargetSources/RunCMakeTest.cmake

@@ -8,3 +8,6 @@ else()
 endif()
 endif()
 
 
 run_cmake(CMP0026-LOCATION)
 run_cmake(CMP0026-LOCATION)
+run_cmake(RelativePathInInterface)
+run_cmake(ExportBuild)
+run_cmake(ExportInstall)

+ 5 - 0
Tests/RunCMake/TargetSources/main.cpp

@@ -0,0 +1,5 @@
+
+int main()
+{
+  return 0;
+}

+ 3 - 1
Tests/SourcesProperty/CMakeLists.txt

@@ -4,7 +4,9 @@ cmake_minimum_required(VERSION 3.0)
 project(SourcesProperty)
 project(SourcesProperty)
 
 
 add_library(iface INTERFACE)
 add_library(iface INTERFACE)
-set_property(TARGET iface PROPERTY INTERFACE_SOURCES iface.cpp)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES
+  "${CMAKE_CURRENT_SOURCE_DIR}/iface.cpp"
+)
 
 
 add_executable(SourcesProperty main.cpp)
 add_executable(SourcesProperty main.cpp)
 target_link_libraries(SourcesProperty iface)
 target_link_libraries(SourcesProperty iface)