Commit 9eb06d0d authored by Stephen Kelly's avatar Stephen Kelly

add_library: Disallow invalid signatures for INTERFACE_LIBRARY.

Document the valid signatures. Add a test for the IMPORTED GLOBAL
signature.
parent 10d65d50
......@@ -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
create build output, though it may have properties set on it and it
may be installed, exported and imported. Typically the INTERFACE_*
properties are populated on the interface target using the
set_property(), target_link_libraries(), target_include_directories()
and target_compile_defintions() commands, and then it is used as an
argument to target_link_libraries() like any other target.
:command:`set_property`, :command:`target_link_libraries`,
:command:`target_include_directories`
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`.
......@@ -49,47 +49,117 @@ bool cmAddLibraryCommand
std::string libType = *s;
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;
type = cmTarget::STATIC_LIBRARY;
haveSpecifiedType = true;
}
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;
type = cmTarget::SHARED_LIBRARY;
haveSpecifiedType = true;
}
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;
type = cmTarget::MODULE_LIBRARY;
haveSpecifiedType = true;
}
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;
type = cmTarget::OBJECT_LIBRARY;
haveSpecifiedType = true;
}
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;
type = cmTarget::UNKNOWN_LIBRARY;
haveSpecifiedType = true;
}
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;
isAlias = true;
}
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;
type = cmTarget::INTERFACE_LIBRARY;
haveSpecifiedType = true;
}
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;
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) &&
!cmGlobalGenerator::IsReservedTarget(libName);
......
......@@ -14,7 +14,7 @@ target_link_libraries(InterfaceLibrary iface_nodepends headeriface)
add_subdirectory(libsdir)
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)
......
......@@ -24,3 +24,5 @@ target_compile_definitions(shareddependlib
add_library(shared_iface INTERFACE)
target_link_libraries(shared_iface INTERFACE sharedlib)
add_library(imported::iface INTERFACE IMPORTED GLOBAL)
......@@ -4,5 +4,6 @@ run_cmake(invalid_name)
run_cmake(target_commands)
run_cmake(no_shared_libs)
run_cmake(whitelist)
run_cmake(invalid_signature)
run_cmake(genex_link)
run_cmake(add_dependencies)
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\)
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)
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