export: Add support for INTERFACE_LIBRARY targets

This commit is contained in:
Stephen Kelly 2012-11-20 10:58:15 +01:00 committed by Brad King
parent fe732264e9
commit 435c912848
17 changed files with 185 additions and 14 deletions

View File

@ -220,6 +220,16 @@ bool cmAddLibraryCommand
); );
return true; 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. // Make sure the target does not already exist.
if(this->Makefile->FindTargetToUse(libName.c_str())) if(this->Makefile->FindTargetToUse(libName.c_str()))

View File

@ -99,6 +99,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
{ {
case cmTarget::SHARED_LIBRARY: case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY: case cmTarget::STATIC_LIBRARY:
case cmTarget::INTERFACE_LIBRARY:
case cmTarget::UNKNOWN_LIBRARY: case cmTarget::UNKNOWN_LIBRARY:
break; break;
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:

View File

@ -47,6 +47,10 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
} }
return false; return false;
} }
if (te->GetType() == cmTarget::INTERFACE_LIBRARY)
{
this->GenerateRequiredCMakeVersion(os, "2.8.12.20131007"); // 2.8.13
}
} }
this->GenerateExpectedTargetsCode(os, expectedTargets); this->GenerateExpectedTargetsCode(os, expectedTargets);
@ -118,16 +122,22 @@ cmExportBuildFileGenerator
// Collect import properties for this target. // Collect import properties for this target.
cmTarget* target = *tei; cmTarget* target = *tei;
ImportPropertyMap properties; ImportPropertyMap properties;
this->SetImportLocationProperty(config, suffix, target, properties);
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
this->SetImportLocationProperty(config, suffix, target, properties);
}
if(!properties.empty()) if(!properties.empty())
{ {
// Get the rest of the target details. // Get the rest of the target details.
this->SetImportDetailProperties(config, suffix, if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
target, properties, missingTargets); {
this->SetImportLinkInterface(config, suffix, this->SetImportDetailProperties(config, suffix,
cmGeneratorExpression::BuildInterface, target, properties, missingTargets);
target, properties, missingTargets); this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::BuildInterface,
target, properties, missingTargets);
}
// TOOD: PUBLIC_HEADER_LOCATION // TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff // This should wait until the build feature propagation stuff

View File

@ -130,7 +130,8 @@ bool cmExportCommand
if((target->GetType() == cmTarget::EXECUTABLE) || if((target->GetType() == cmTarget::EXECUTABLE) ||
(target->GetType() == cmTarget::STATIC_LIBRARY) || (target->GetType() == cmTarget::STATIC_LIBRARY) ||
(target->GetType() == cmTarget::SHARED_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); targets.push_back(target);
} }

View File

@ -378,11 +378,14 @@ void getCompatibleInterfaceProperties(cmTarget *target,
if (!info) if (!info)
{ {
cmMakefile* mf = target->GetMakefile(); if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
cmOStringStream e; {
e << "Exporting the target \"" << target->GetName() << "\" is not " cmMakefile* mf = target->GetMakefile();
"allowed since its linker language cannot be determined"; cmOStringStream e;
mf->IssueMessage(cmake::FATAL_ERROR, e.str()); e << "Exporting the target \"" << target->GetName() << "\" is not "
"allowed since its linker language cannot be determined";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
}
return; return;
} }
@ -887,6 +890,9 @@ cmExportFileGenerator
case cmTarget::UNKNOWN_LIBRARY: case cmTarget::UNKNOWN_LIBRARY:
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n"; os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
break; break;
case cmTarget::INTERFACE_LIBRARY:
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
break;
default: // should never happen default: // should never happen
break; break;
} }

View File

@ -6164,7 +6164,8 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
const char* loc = 0; const char* loc = 0;
const char* imp = 0; const char* imp = 0;
std::string suffix; std::string suffix;
if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix)) if (this->GetType() != INTERFACE_LIBRARY &&
!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
{ {
return; return;
} }

View File

@ -426,3 +426,5 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
NAMESPACE bld_ NAMESPACE bld_
APPEND FILE ExportBuildTree.cmake APPEND FILE ExportBuildTree.cmake
) )
add_subdirectory(Interface)

View File

@ -0,0 +1,29 @@
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
)

View File

@ -0,0 +1,7 @@
enum { one };
struct HeaderOnly
{
int foo() const { return 0; }
};

View File

@ -0,0 +1,7 @@
#include "sharedlib.h"
int SharedLibObject::foo() const
{
return 0;
}

View File

@ -0,0 +1,7 @@
#include "sharedlib_export.h"
struct SHAREDLIB_EXPORT SharedLibObject
{
int foo() const;
};

View File

@ -19,3 +19,6 @@ add_executable(imp_testTransExe1b imp_testTransExe1.c)
target_link_libraries(imp_testTransExe1b imp_lib1b) target_link_libraries(imp_testTransExe1b imp_lib1b)
add_subdirectory(try_compile) add_subdirectory(try_compile)
# Test package INTERFACE controls
add_subdirectory(Interface)

View File

@ -0,0 +1,42 @@
# 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_)

View File

@ -0,0 +1,17 @@
#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();
}

View File

@ -0,0 +1,20 @@
#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();
}

View File

@ -7,3 +7,9 @@ CMake Error at invalid_name.cmake:4 \(add_library\):
add_library Invalid name for INTERFACE library target: iface::target add_library Invalid name for INTERFACE library target: iface::target
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) 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\)

View File

@ -2,3 +2,5 @@
add_library(if$ace INTERFACE) add_library(if$ace INTERFACE)
add_library(iface::target INTERFACE) add_library(iface::target INTERFACE)
add_library(if$target_imported INTERFACE IMPORTED)