add_library: Disallow invalid signatures for INTERFACE_LIBRARY.

Document the valid signatures. Add a test for the IMPORTED GLOBAL
signature.
This commit is contained in:
Stephen Kelly 2013-12-31 14:52:07 +01:00
parent 10d65d5019
commit 9eb06d0dde
8 changed files with 215 additions and 5 deletions

View File

@ -109,12 +109,21 @@ The signature
:: ::
add_library(<name> INTERFACE) add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
creates an interface target. An interface target does not directly creates an interface target. An interface target does not directly
create build output, though it may have properties set on it and it create build output, though it may have properties set on it and it
may be installed, exported and imported. Typically the INTERFACE_* may be installed, exported and imported. Typically the INTERFACE_*
properties are populated on the interface target using the properties are populated on the interface target using the
set_property(), target_link_libraries(), target_include_directories() :command:`set_property`, :command:`target_link_libraries`,
and target_compile_defintions() commands, and then it is used as an :command:`target_include_directories`
argument to target_link_libraries() like any other target. and :command:`target_compile_defintions` commands, and then it is used as an
argument to :command:`target_link_libraries` like any other target.
An ``INTERFACE`` :prop_tgt:`IMPORTED` target may also be created with this
signature. An :prop_tgt:`IMPORTED` library target references a library defined
outside the project. The target name has scope in the directory in which it is
created and below, but the ``GLOBAL`` option extends visibility. It may be
referenced like any target built within the project. :prop_tgt:`IMPORTED`
libraries are useful for convenient reference from commands like
:command:`target_link_libraries`.

View File

@ -49,47 +49,117 @@ bool cmAddLibraryCommand
std::string libType = *s; std::string libType = *s;
if(libType == "STATIC") if(libType == "STATIC")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting STATIC type.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
type = cmTarget::STATIC_LIBRARY; type = cmTarget::STATIC_LIBRARY;
haveSpecifiedType = true; haveSpecifiedType = true;
} }
else if(libType == "SHARED") else if(libType == "SHARED")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting SHARED type.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
type = cmTarget::SHARED_LIBRARY; type = cmTarget::SHARED_LIBRARY;
haveSpecifiedType = true; haveSpecifiedType = true;
} }
else if(libType == "MODULE") else if(libType == "MODULE")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting MODULE type.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
type = cmTarget::MODULE_LIBRARY; type = cmTarget::MODULE_LIBRARY;
haveSpecifiedType = true; haveSpecifiedType = true;
} }
else if(libType == "OBJECT") else if(libType == "OBJECT")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting OBJECT type.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
type = cmTarget::OBJECT_LIBRARY; type = cmTarget::OBJECT_LIBRARY;
haveSpecifiedType = true; haveSpecifiedType = true;
} }
else if(libType == "UNKNOWN") else if(libType == "UNKNOWN")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting UNKNOWN type.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
type = cmTarget::UNKNOWN_LIBRARY; type = cmTarget::UNKNOWN_LIBRARY;
haveSpecifiedType = true; haveSpecifiedType = true;
} }
else if(libType == "ALIAS") else if(libType == "ALIAS")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting ALIAS type.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
isAlias = true; isAlias = true;
} }
else if(libType == "INTERFACE") else if(libType == "INTERFACE")
{ {
if (haveSpecifiedType)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting/multiple types.";
this->SetError(e.str().c_str());
return false;
}
if (isAlias)
{
cmOStringStream e;
e << "INTERFACE library specified with conflicting ALIAS type.";
this->SetError(e.str().c_str());
return false;
}
if (excludeFromAll)
{
cmOStringStream e;
e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
type = cmTarget::INTERFACE_LIBRARY; type = cmTarget::INTERFACE_LIBRARY;
haveSpecifiedType = true; haveSpecifiedType = true;
} }
else if(*s == "EXCLUDE_FROM_ALL") else if(*s == "EXCLUDE_FROM_ALL")
{ {
if (type == cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
this->SetError(e.str().c_str());
return false;
}
++s; ++s;
excludeFromAll = true; excludeFromAll = true;
} }
@ -109,6 +179,24 @@ bool cmAddLibraryCommand
} }
} }
if (type == cmTarget::INTERFACE_LIBRARY)
{
if (s != args.end())
{
cmOStringStream e;
e << "INTERFACE library requires no source arguments.";
this->SetError(e.str().c_str());
return false;
}
if (importGlobal && !importTarget)
{
cmOStringStream e;
e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
this->SetError(e.str().c_str());
return false;
}
}
bool nameOk = cmGeneratorExpression::IsValidTargetName(libName) && bool nameOk = cmGeneratorExpression::IsValidTargetName(libName) &&
!cmGlobalGenerator::IsReservedTarget(libName); !cmGlobalGenerator::IsReservedTarget(libName);

View File

@ -14,7 +14,7 @@ target_link_libraries(InterfaceLibrary iface_nodepends headeriface)
add_subdirectory(libsdir) add_subdirectory(libsdir)
add_executable(sharedlibtestexe sharedlibtestexe.cpp) add_executable(sharedlibtestexe sharedlibtestexe.cpp)
target_link_libraries(sharedlibtestexe shared_iface) target_link_libraries(sharedlibtestexe shared_iface imported::iface)
add_library(broken EXCLUDE_FROM_ALL broken.cpp) add_library(broken EXCLUDE_FROM_ALL broken.cpp)

View File

@ -24,3 +24,5 @@ target_compile_definitions(shareddependlib
add_library(shared_iface INTERFACE) add_library(shared_iface INTERFACE)
target_link_libraries(shared_iface INTERFACE sharedlib) target_link_libraries(shared_iface INTERFACE sharedlib)
add_library(imported::iface INTERFACE IMPORTED GLOBAL)

View File

@ -4,5 +4,6 @@ run_cmake(invalid_name)
run_cmake(target_commands) run_cmake(target_commands)
run_cmake(no_shared_libs) run_cmake(no_shared_libs)
run_cmake(whitelist) run_cmake(whitelist)
run_cmake(invalid_signature)
run_cmake(genex_link) run_cmake(genex_link)
run_cmake(add_dependencies) run_cmake(add_dependencies)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,89 @@
CMake Error at invalid_signature.cmake:2 \(add_library\):
add_library INTERFACE library requires no source arguments.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:3 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:4 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:5 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:6 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:7 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:8 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:9 \(add_library\):
add_library INTERFACE library specified with conflicting STATIC type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:10 \(add_library\):
add_library INTERFACE library specified with conflicting SHARED type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:11 \(add_library\):
add_library INTERFACE library specified with conflicting MODULE type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:12 \(add_library\):
add_library INTERFACE library specified with conflicting OBJECT type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:13 \(add_library\):
add_library INTERFACE library specified with conflicting UNKNOWN type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:14 \(add_library\):
add_library INTERFACE library specified with conflicting ALIAS type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:15 \(add_library\):
add_library INTERFACE library specified with conflicting ALIAS type.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:16 \(add_library\):
add_library INTERFACE library specified with conflicting/multiple types.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:17 \(add_library\):
add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:18 \(add_library\):
add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at invalid_signature.cmake:20 \(add_library\):
add_library INTERFACE library requires no source arguments.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,20 @@
add_library(iface1 INTERFACE empty.cpp)
add_library(iface3 STATIC INTERFACE)
add_library(iface4 STATIC INTERFACE empty.cpp)
add_library(iface5 SHARED INTERFACE)
add_library(iface6 MODULE INTERFACE)
add_library(iface7 OBJECT INTERFACE)
add_library(iface8 UNKNOWN INTERFACE)
add_library(iface9 INTERFACE STATIC)
add_library(iface10 INTERFACE SHARED)
add_library(iface11 INTERFACE MODULE)
add_library(iface12 INTERFACE OBJECT)
add_library(iface13 INTERFACE UNKNOWN)
add_library(iface14 INTERFACE ALIAS)
add_library(iface15 ALIAS INTERFACE)
add_library(iface16 INTERFACE INTERFACE)
add_library(iface17 INTERFACE EXCLUDE_FROM_ALL)
add_library(iface18 EXCLUDE_FROM_ALL INTERFACE)
add_library(iface19 GLOBAL INTERFACE)
add_library(iface20 INTERFACE GLOBAL)