Browse Source

Merge branch 'target-sources-error-conditions' into release

Brad King 11 years ago
parent
commit
58d3898083

+ 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
 ``<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"
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`

+ 4 - 0
Help/prop_tgt/INTERFACE_SOURCES.rst

@@ -9,6 +9,10 @@ targets can add entries to their own :prop_tgt:`SOURCES` property
 such as ``$<TARGET_PROPERTY:foo,INTERFACE_SOURCES>`` to use the
 sources specified in the interface of ``foo``.
 
+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"
 with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(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)
     {
     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);
 
     te->AppendBuildInterfaceIncludes();

+ 11 - 0
Source/cmExportInstallFileGenerator.cxx

@@ -123,6 +123,17 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
     {
     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
                               || 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
       it = entries.begin(), end = entries.end(); it != end; ++it)
     {
+    cmLinkImplItem const& item = (*it)->LinkImplItem;
+    std::string const& targetName = item;
     std::vector<std::string> entrySources;
     cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
                                               config,
@@ -667,11 +669,10 @@ static bool processSources(cmTarget const* tgt,
         i != entrySources.end(); ++i)
       {
       std::string& src = *i;
-
       cmSourceFile* sf = mf->GetOrCreateSource(src);
       std::string e;
-      src = sf->GetFullPath(&e);
-      if(src.empty())
+      std::string fullPath = sf->GetFullPath(&e);
+      if(fullPath.empty())
         {
         if(!e.empty())
           {
@@ -681,6 +682,25 @@ static bool processSources(cmTarget const* tgt,
           }
         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;
     for(std::vector<std::string>::iterator

+ 3 - 3
Tests/ConfigSources/CMakeLists.txt

@@ -5,9 +5,9 @@ project(ConfigSources)
 
 add_library(iface INTERFACE)
 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

+ 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)
 set_property(TARGET iface PROPERTY INTERFACE_SOURCES
-  empty_1.cpp
+  "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.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()
 
 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)
 
 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)
 target_link_libraries(SourcesProperty iface)