Commit 435c9128 authored by Stephen Kelly's avatar Stephen Kelly Committed by Brad King

export: Add support for INTERFACE_LIBRARY targets

parent fe732264
......@@ -220,6 +220,16 @@ bool cmAddLibraryCommand
);
return true;
}
if(type == cmTarget::INTERFACE_LIBRARY)
{
if (!cmGeneratorExpression::IsValidTargetName(libName))
{
cmOStringStream e;
e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
this->SetError(e.str().c_str());
return false;
}
}
// Make sure the target does not already exist.
if(this->Makefile->FindTargetToUse(libName.c_str()))
......
......@@ -99,6 +99,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
{
case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::INTERFACE_LIBRARY:
case cmTarget::UNKNOWN_LIBRARY:
break;
case cmTarget::EXECUTABLE:
......
......@@ -47,6 +47,10 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
}
return false;
}
if (te->GetType() == cmTarget::INTERFACE_LIBRARY)
{
this->GenerateRequiredCMakeVersion(os, "2.8.12.20131007"); // 2.8.13
}
}
this->GenerateExpectedTargetsCode(os, expectedTargets);
......@@ -118,16 +122,22 @@ cmExportBuildFileGenerator
// Collect import properties for this target.
cmTarget* target = *tei;
ImportPropertyMap properties;
this->SetImportLocationProperty(config, suffix, target, properties);
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
this->SetImportLocationProperty(config, suffix, target, properties);
}
if(!properties.empty())
{
// Get the rest of the target details.
this->SetImportDetailProperties(config, suffix,
target, properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::BuildInterface,
target, properties, missingTargets);
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
this->SetImportDetailProperties(config, suffix,
target, properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::BuildInterface,
target, properties, missingTargets);
}
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
......
......@@ -130,7 +130,8 @@ bool cmExportCommand
if((target->GetType() == cmTarget::EXECUTABLE) ||
(target->GetType() == cmTarget::STATIC_LIBRARY) ||
(target->GetType() == cmTarget::SHARED_LIBRARY) ||
(target->GetType() == cmTarget::MODULE_LIBRARY))
(target->GetType() == cmTarget::MODULE_LIBRARY) ||
(target->GetType() == cmTarget::INTERFACE_LIBRARY))
{
targets.push_back(target);
}
......
......@@ -378,11 +378,14 @@ void getCompatibleInterfaceProperties(cmTarget *target,
if (!info)
{
cmMakefile* mf = target->GetMakefile();
cmOStringStream e;
e << "Exporting the target \"" << target->GetName() << "\" is not "
"allowed since its linker language cannot be determined";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
cmMakefile* mf = target->GetMakefile();
cmOStringStream e;
e << "Exporting the target \"" << target->GetName() << "\" is not "
"allowed since its linker language cannot be determined";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
}
return;
}
......@@ -887,6 +890,9 @@ cmExportFileGenerator
case cmTarget::UNKNOWN_LIBRARY:
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
break;
case cmTarget::INTERFACE_LIBRARY:
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
break;
default: // should never happen
break;
}
......
......@@ -6164,7 +6164,8 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
const char* loc = 0;
const char* imp = 0;
std::string suffix;
if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
if (this->GetType() != INTERFACE_LIBRARY &&
!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
{
return;
}
......
......@@ -426,3 +426,5 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
NAMESPACE bld_
APPEND FILE ExportBuildTree.cmake
)
add_subdirectory(Interface)
add_library(headeronly INTERFACE)
set_property(TARGET headeronly PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/headeronly>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/headeronly>"
)
set_property(TARGET headeronly PROPERTY INTERFACE_COMPILE_DEFINITIONS "HEADERONLY_DEFINE")
include(GenerateExportHeader)
add_library(sharedlib SHARED sharedlib.cpp)
generate_export_header(sharedlib)
set_property(TARGET sharedlib PROPERTY INCLUDE_DIRECTORIES
"${CMAKE_CURRENT_SOURCE_DIR}/sharedlib"
"${CMAKE_CURRENT_BINARY_DIR}"
)
set_property(TARGET sharedlib PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/sharedlib;${CMAKE_CURRENT_BINARY_DIR}>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/sharedlib>"
)
set_property(TARGET sharedlib PROPERTY INTERFACE_COMPILE_DEFINITIONS "SHAREDLIB_DEFINE")
add_library(sharediface INTERFACE)
target_link_libraries(sharediface INTERFACE sharedlib)
export(TARGETS sharediface sharedlib headeronly
NAMESPACE bld_
FILE ../ExportInterfaceBuildTree.cmake
)
enum { one };
struct HeaderOnly
{
int foo() const { return 0; }
};
#include "sharedlib.h"
int SharedLibObject::foo() const
{
return 0;
}
#include "sharedlib_export.h"
struct SHAREDLIB_EXPORT SharedLibObject
{
int foo() const;
};
......@@ -19,3 +19,6 @@ add_executable(imp_testTransExe1b imp_testTransExe1.c)
target_link_libraries(imp_testTransExe1b imp_lib1b)
add_subdirectory(try_compile)
# Test package INTERFACE controls
add_subdirectory(Interface)
# Import targets from the exported build tree.
include(${Import_BINARY_DIR}/../Export/ExportInterfaceBuildTree.cmake)
add_library(define_iface INTERFACE)
set_property(TARGET define_iface PROPERTY
INTERFACE_COMPILE_DEFINITIONS DEFINE_IFACE_DEFINE)
add_executable(headeronlytest_bld headeronlytest.cpp)
target_link_libraries(headeronlytest_bld bld_headeronly)
set_property(TARGET bld_sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
add_executable(interfacetest_bld interfacetest.cpp)
target_link_libraries(interfacetest_bld bld_sharediface)
include(CheckCXXSourceCompiles)
macro(do_try_compile prefix)
set(CMAKE_REQUIRED_LIBRARIES ${prefix}headeronly)
check_cxx_source_compiles(
"
#include \"headeronly.h\"
#ifndef HEADERONLY_DEFINE
#error Expected HEADERONLY_DEFINE
#endif
int main(int,char**)
{
HeaderOnly ho;
return ho.foo();
}
" ${prefix}IFACE_TRY_COMPILE)
if(NOT ${prefix}IFACE_TRY_COMPILE)
message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
endif()
endmacro()
do_try_compile(bld_)
#include "headeronly.h"
#ifndef HEADERONLY_DEFINE
#error Expected HEADERONLY_DEFINE
#endif
#ifdef SHAREDLIB_DEFINE
#error Unexpected SHAREDLIB_DEFINE
#endif
int main(int,char**)
{
HeaderOnly ho;
return ho.foo();
}
#include "sharedlib.h"
#ifndef SHAREDLIB_DEFINE
#error Expected SHAREDLIB_DEFINE
#endif
#ifdef HEADERONLY_DEFINE
#error Unexpected HEADERONLY_DEFINE
#endif
#ifndef DEFINE_IFACE_DEFINE
#error Expected DEFINE_IFACE_DEFINE
#endif
int main(int,char**)
{
SharedLibObject slo;
return slo.foo();
}
......@@ -7,3 +7,9 @@ CMake Error at invalid_name.cmake:4 \(add_library\):
add_library Invalid name for INTERFACE library target: iface::target
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_name.cmake:6 \(add_library\):
add_library Invalid name for IMPORTED INTERFACE library target:
if\$target_imported
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
......@@ -2,3 +2,5 @@
add_library(if$ace INTERFACE)
add_library(iface::target INTERFACE)
add_library(if$target_imported INTERFACE IMPORTED)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment