1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

Add INTERFACE libraries to generated buildsystem if they have SOURCES

INTERFACE libraries were created with the intention of collecting usage
requirements for use by other targets via `target_link_libraries`.
Therefore they were not allowed to have SOURCES and were not included in
the generated buildsystem.  In practice, this has become limiting:

* Header-only libraries do have sources, they just do not compile.
  Developers should be able to edit those sources (the header files)
  in their IDE.

* Header-only libraries may need to generate some of their header
  files via custom commands.

Some projects work around these limitations by pairing each interface
library with an `add_custom_target` that makes the header files and
custom commands appear in the generated buildsystem and in IDEs.

Lift such limitations by allowing INTERFACE libraries to have SOURCES.
For those with sources, add a corresponding build target to the
generated buildsystem.

Fixes: #19145
This commit is contained in:
Brad King
2020-07-20 13:19:26 -04:00
parent afb998704e
commit 4391913133
48 changed files with 303 additions and 94 deletions

View File

@@ -2,8 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLibraryCommand.h"
#include <cmext/algorithm>
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -111,20 +109,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
"INTERFACE library specified with conflicting ALIAS type.");
return false;
}
if (excludeFromAll) {
status.SetError(
"INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
return false;
}
++s;
type = cmStateEnums::INTERFACE_LIBRARY;
haveSpecifiedType = true;
} else if (*s == "EXCLUDE_FROM_ALL") {
if (type == cmStateEnums::INTERFACE_LIBRARY) {
status.SetError(
"INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
return false;
}
++s;
excludeFromAll = true;
} else if (*s == "IMPORTED") {
@@ -143,10 +131,6 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
}
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (s != args.end()) {
status.SetError("INTERFACE library requires no source arguments.");
return false;
}
if (importGlobal && !importTarget) {
status.SetError(
"INTERFACE library specified as GLOBAL, but not as IMPORTED.");
@@ -302,8 +286,6 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
}
}
std::vector<std::string> srclists;
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (!cmGeneratorExpression::IsValidTargetName(libName) ||
libName.find("::") != std::string::npos) {
@@ -311,14 +293,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
cmStrCat("Invalid name for INTERFACE library target: ", libName));
return false;
}
mf.AddLibrary(libName, type, srclists, excludeFromAll);
return true;
}
cm::append(srclists, s, args.end());
mf.AddLibrary(libName, type, srclists, excludeFromAll);
std::vector<std::string> srcs(s, args.end());
mf.AddLibrary(libName, type, srcs, excludeFromAll);
return true;
}