mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Merge topic 'genex-TARGET_OBJECTS-SOURCE_FILES'
987e0af366 GenEx: Add `$<TARGET_OBJECTS:...>` option to filter on source files
Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !11782
This commit is contained in:
@@ -3298,13 +3298,23 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
|
||||
.. genex:: $<TARGET_OBJECTS:tgt>
|
||||
.. genex:: $<TARGET_OBJECTS:tgt[,SOURCE_FILES:source_file[;source_file]...]>
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
List of objects resulting from building ``tgt``. This would typically be
|
||||
used on :ref:`object library <Object Libraries>` targets.
|
||||
|
||||
Additional arguments:
|
||||
|
||||
``SOURCE_FILES:source_file[;source_file]...``
|
||||
|
||||
.. versionadded:: 4.4
|
||||
|
||||
An optional list of one or more source files for the target. Only the
|
||||
object files built from those source files will be returned (but not
|
||||
necessarily in the same order they were specified).
|
||||
|
||||
.. genex:: $<TARGET_RUNTIME_DLLS:tgt>
|
||||
|
||||
.. versionadded:: 3.21
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
genex-TARGET_OBJECTS-SOURCE_FILES
|
||||
---------------------------------
|
||||
|
||||
* The :genex:`TARGET_OBJECTS` generator expression now has an optional
|
||||
``SOURCE_FILES:...`` argument, which can take one or more source files as
|
||||
arguments, and will filter its output to only include objects built from
|
||||
those source files.
|
||||
@@ -4335,6 +4335,55 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::vector<std::string> sourceFilePaths;
|
||||
for (auto const& arg : cmMakeRange(parameters).advance(1)) {
|
||||
if (cmHasLiteralPrefix(arg, "SOURCE_FILES:")) {
|
||||
cm::string_view listView{ arg.c_str() + cmStrLen("SOURCE_FILES:") };
|
||||
std::size_t semicolon;
|
||||
std::size_t start = 0;
|
||||
do {
|
||||
semicolon = listView.find(';', start);
|
||||
sourceFilePaths.push_back(
|
||||
std::string{ listView.substr(start, semicolon - start) });
|
||||
start = semicolon + 1;
|
||||
} while (semicolon != cm::string_view::npos);
|
||||
} else {
|
||||
reportError(eval, content->GetOriginalExpression(),
|
||||
cmStrCat("Unrecognized argument:\n ", arg));
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
if (gt->IsImported() && !sourceFilePaths.empty()) {
|
||||
reportError(
|
||||
eval, content->GetOriginalExpression(),
|
||||
cmStrCat("Cannot use SOURCE_FILES argument on imported target \"",
|
||||
tgtName, '"'));
|
||||
return std::string();
|
||||
}
|
||||
std::set<cmSourceFile const*> sourceFiles;
|
||||
for (auto const& sf : gt->GetSourceFiles(eval->Context.Config)) {
|
||||
sourceFiles.insert(sf.Value);
|
||||
}
|
||||
std::set<cmSourceFile const*> filteredSourceFiles;
|
||||
for (auto const& path : sourceFilePaths) {
|
||||
if (!cmSystemTools::FileIsFullPath(path)) {
|
||||
reportError(
|
||||
eval, content->GetOriginalExpression(),
|
||||
cmStrCat("Source file:\n ", path, "\nis not an absolute path"));
|
||||
return std::string();
|
||||
}
|
||||
|
||||
auto const* sf = gt->Makefile->GetSource(path);
|
||||
if (!sf || !sourceFiles.count(sf)) {
|
||||
reportError(eval, content->GetOriginalExpression(),
|
||||
cmStrCat("Source file:\n ", path,
|
||||
"\ndoes not exist for target \"", tgtName, '"'));
|
||||
return std::string();
|
||||
}
|
||||
filteredSourceFiles.insert(sf);
|
||||
}
|
||||
|
||||
cmList objects;
|
||||
|
||||
if (gt->IsImported()) {
|
||||
@@ -4347,7 +4396,11 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
||||
}
|
||||
eval->HadContextSensitiveCondition = true;
|
||||
} else {
|
||||
gt->GetTargetObjectNames(eval->Context.Config, objects);
|
||||
auto const filter =
|
||||
[&filteredSourceFiles](cmSourceFile const& sf) -> bool {
|
||||
return filteredSourceFiles.empty() || filteredSourceFiles.count(&sf);
|
||||
};
|
||||
gt->GetTargetObjectNames(eval->Context.Config, filter, objects);
|
||||
|
||||
std::string obj_dir;
|
||||
if (eval->EvaluateForBuildsystem && !gg->SupportsCrossConfigs()) {
|
||||
@@ -4373,6 +4426,8 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
||||
|
||||
return objects.to_string();
|
||||
}
|
||||
|
||||
int NumExpectedParameters() const override { return OneOrMoreParameters; }
|
||||
} targetObjectsNode;
|
||||
|
||||
struct TargetRuntimeDllsBaseNode : public cmGeneratorExpressionNode
|
||||
|
||||
@@ -4076,9 +4076,17 @@ std::string cmGeneratorTarget::GetObjectDirectory(
|
||||
|
||||
void cmGeneratorTarget::GetTargetObjectNames(
|
||||
std::string const& config, std::vector<std::string>& objects) const
|
||||
{
|
||||
this->GetTargetObjectNames(
|
||||
config, [](cmSourceFile const&) -> bool { return true; }, objects);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetTargetObjectNames(
|
||||
std::string const& config, std::function<bool(cmSourceFile const&)> filter,
|
||||
std::vector<std::string>& objects) const
|
||||
{
|
||||
this->GetTargetObjectLocations(
|
||||
config,
|
||||
config, filter,
|
||||
[&objects](cmObjectLocation const& buildLoc, cmObjectLocation const&) {
|
||||
objects.push_back(buildLoc.GetPath());
|
||||
});
|
||||
@@ -4088,6 +4096,15 @@ void cmGeneratorTarget::GetTargetObjectLocations(
|
||||
std::string const& config,
|
||||
std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
|
||||
const
|
||||
{
|
||||
this->GetTargetObjectLocations(
|
||||
config, [](cmSourceFile const&) -> bool { return true; }, cb);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetTargetObjectLocations(
|
||||
std::string const& config, std::function<bool(cmSourceFile const&)> filter,
|
||||
std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
|
||||
const
|
||||
{
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
this->GetObjectSources(objectSources, config);
|
||||
@@ -4105,15 +4122,17 @@ void cmGeneratorTarget::GetTargetObjectLocations(
|
||||
auto const installUseShortPaths = this->GetUseShortObjectNamesForInstall();
|
||||
|
||||
for (cmSourceFile const* src : objectSources) {
|
||||
// Find the object file name corresponding to this source file.
|
||||
auto map_it = mapping.find(src);
|
||||
auto const& buildLoc = map_it->second.GetLocation(buildUseShortPaths);
|
||||
auto const& installLoc =
|
||||
map_it->second.GetInstallLocation(installUseShortPaths, config);
|
||||
// It must exist because we populated the mapping just above.
|
||||
assert(!buildLoc.GetPath().empty());
|
||||
assert(!installLoc.GetPath().empty());
|
||||
cb(buildLoc, installLoc);
|
||||
if (filter(*src)) {
|
||||
// Find the object file name corresponding to this source file.
|
||||
auto map_it = mapping.find(src);
|
||||
auto const& buildLoc = map_it->second.GetLocation(buildUseShortPaths);
|
||||
auto const& installLoc =
|
||||
map_it->second.GetInstallLocation(installUseShortPaths, config);
|
||||
// It must exist because we populated the mapping just above.
|
||||
assert(!buildLoc.GetPath().empty());
|
||||
assert(!installLoc.GetPath().empty());
|
||||
cb(buildLoc, installLoc);
|
||||
}
|
||||
}
|
||||
|
||||
// We need to compute the relative path from the root of
|
||||
@@ -4121,11 +4140,14 @@ void cmGeneratorTarget::GetTargetObjectLocations(
|
||||
std::string rootObjectDir = this->GetObjectDirectory(config);
|
||||
rootObjectDir = cmSystemTools::CollapseFullPath(rootObjectDir);
|
||||
auto ispcObjects = this->GetGeneratedISPCObjects(config);
|
||||
for (std::string const& output : ispcObjects) {
|
||||
auto relativePathFromObjectDir = output.substr(rootObjectDir.size());
|
||||
cmObjectLocation ispcLoc(relativePathFromObjectDir);
|
||||
// FIXME: apply short path to this object if needed.
|
||||
cb(ispcLoc, ispcLoc);
|
||||
for (auto const& output : ispcObjects) {
|
||||
if (filter(*output.first)) {
|
||||
auto relativePathFromObjectDir =
|
||||
output.second.substr(rootObjectDir.size());
|
||||
cmObjectLocation ispcLoc(relativePathFromObjectDir);
|
||||
// FIXME: apply short path to this object if needed.
|
||||
cb(ispcLoc, ispcLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4389,8 +4411,9 @@ std::vector<std::string> cmGeneratorTarget::GetGeneratedISPCHeaders(
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::AddISPCGeneratedObject(std::vector<std::string>&& objs,
|
||||
std::string const& config)
|
||||
void cmGeneratorTarget::AddISPCGeneratedObject(
|
||||
std::vector<std::pair<cmSourceFile const*, std::string>>&& objs,
|
||||
std::string const& config)
|
||||
{
|
||||
std::string config_upper;
|
||||
if (!config.empty()) {
|
||||
@@ -4404,8 +4427,8 @@ void cmGeneratorTarget::AddISPCGeneratedObject(std::vector<std::string>&& objs,
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> cmGeneratorTarget::GetGeneratedISPCObjects(
|
||||
std::string const& config) const
|
||||
std::vector<std::pair<cmSourceFile const*, std::string>>
|
||||
cmGeneratorTarget::GetGeneratedISPCObjects(std::string const& config) const
|
||||
{
|
||||
std::string config_upper;
|
||||
if (!config.empty()) {
|
||||
@@ -4413,7 +4436,7 @@ std::vector<std::string> cmGeneratorTarget::GetGeneratedISPCObjects(
|
||||
}
|
||||
auto iter = this->ISPCGeneratedObjects.find(config_upper);
|
||||
if (iter == this->ISPCGeneratedObjects.end()) {
|
||||
return std::vector<std::string>{};
|
||||
return std::vector<std::pair<cmSourceFile const*, std::string>>{};
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
@@ -313,11 +313,18 @@ public:
|
||||
its object file directory for the build. */
|
||||
void GetTargetObjectNames(std::string const& config,
|
||||
std::vector<std::string>& objects) const;
|
||||
void GetTargetObjectNames(std::string const& config,
|
||||
std::function<bool(cmSourceFile const&)> filter,
|
||||
std::vector<std::string>& objects) const;
|
||||
/** Get the build and install locations of objects for a given context. */
|
||||
void GetTargetObjectLocations(
|
||||
std::string const& config,
|
||||
std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
|
||||
const;
|
||||
void GetTargetObjectLocations(
|
||||
std::string const& config, std::function<bool(cmSourceFile const&)> filter,
|
||||
std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
|
||||
const;
|
||||
|
||||
/** What hierarchy level should the reported directory contain */
|
||||
enum BundleDirectoryLevel
|
||||
@@ -1102,10 +1109,11 @@ public:
|
||||
std::vector<std::string> GetGeneratedISPCHeaders(
|
||||
std::string const& config) const;
|
||||
|
||||
void AddISPCGeneratedObject(std::vector<std::string>&& objs,
|
||||
std::string const& config);
|
||||
std::vector<std::string> GetGeneratedISPCObjects(
|
||||
std::string const& config) const;
|
||||
void AddISPCGeneratedObject(
|
||||
std::vector<std::pair<cmSourceFile const*, std::string>>&& objs,
|
||||
std::string const& config);
|
||||
std::vector<std::pair<cmSourceFile const*, std::string>>
|
||||
GetGeneratedISPCObjects(std::string const& config) const;
|
||||
|
||||
void AddSystemIncludeDirectory(std::string const& inc,
|
||||
std::string const& lang);
|
||||
@@ -1370,7 +1378,8 @@ private:
|
||||
|
||||
std::unordered_map<std::string, std::vector<std::string>>
|
||||
ISPCGeneratedHeaders;
|
||||
std::unordered_map<std::string, std::vector<std::string>>
|
||||
std::unordered_map<std::string,
|
||||
std::vector<std::pair<cmSourceFile const*, std::string>>>
|
||||
ISPCGeneratedObjects;
|
||||
|
||||
enum class LinkInterfaceField
|
||||
|
||||
@@ -1383,17 +1383,18 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
|
||||
std::string const& targetConfig) {
|
||||
if (depTarget->CanCompileSources()) {
|
||||
auto headers = depTarget->GetGeneratedISPCHeaders(targetConfig);
|
||||
auto const mapToNinjaPath = gg->MapToNinjaPath();
|
||||
if (!headers.empty()) {
|
||||
std::transform(headers.begin(), headers.end(), headers.begin(),
|
||||
gg->MapToNinjaPath());
|
||||
mapToNinjaPath);
|
||||
outputDeps.insert(outputDeps.end(), headers.begin(), headers.end());
|
||||
}
|
||||
auto objs = depTarget->GetGeneratedISPCObjects(targetConfig);
|
||||
if (!objs.empty()) {
|
||||
std::transform(objs.begin(), objs.end(), objs.begin(),
|
||||
gg->MapToNinjaPath());
|
||||
outputDeps.insert(outputDeps.end(), objs.begin(), objs.end());
|
||||
}
|
||||
std::transform(
|
||||
objs.begin(), objs.end(), std::back_inserter(outputDeps),
|
||||
[&mapToNinjaPath](
|
||||
std::pair<cmSourceFile const*, std::string> const& obj)
|
||||
-> std::string { return mapToNinjaPath(obj.second); });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2688,8 +2688,11 @@ void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target)
|
||||
cmStrCat(headerDir, '/', ispcSource, *ispcHeaderSuffixProp);
|
||||
target->AddISPCGeneratedHeader(headerPath, config);
|
||||
if (extra_objects) {
|
||||
std::vector<std::string> objs = detail::ComputeISPCExtraObjects(
|
||||
objectName, rootObjectDir, ispcArchSuffixes);
|
||||
std::vector<std::pair<cmSourceFile const*, std::string>> objs;
|
||||
for (auto& obj : detail::ComputeISPCExtraObjects(
|
||||
objectName, rootObjectDir, ispcArchSuffixes)) {
|
||||
objs.push_back({ sf, std::move(obj) });
|
||||
}
|
||||
target->AddISPCGeneratedObject(std::move(objs), config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,9 +240,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
// Look for ISPC extra object files generated by this target
|
||||
auto const ispcAdditionalObjs =
|
||||
this->GeneratorTarget->GetGeneratedISPCObjects(this->GetConfigName());
|
||||
for (std::string const& ispcObj : ispcAdditionalObjs) {
|
||||
for (auto const& ispcObj : ispcAdditionalObjs) {
|
||||
this->CleanFiles.insert(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(ispcObj));
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(ispcObj.second));
|
||||
}
|
||||
|
||||
// add custom commands to the clean rules?
|
||||
@@ -1930,8 +1930,8 @@ void cmMakefileTargetGenerator::WriteObjectsStrings(
|
||||
}
|
||||
auto const ispcAdditionalObjs =
|
||||
this->GeneratorTarget->GetGeneratedISPCObjects(this->GetConfigName());
|
||||
for (std::string const& obj : ispcAdditionalObjs) {
|
||||
helper.Feed(obj);
|
||||
for (auto const& obj : ispcAdditionalObjs) {
|
||||
helper.Feed(obj.second);
|
||||
}
|
||||
helper.Done();
|
||||
}
|
||||
|
||||
@@ -1319,11 +1319,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
linkBuild.ExplicitDeps = this->GetObjects(config);
|
||||
}
|
||||
|
||||
std::vector<std::string> extraISPCObjects =
|
||||
auto extraISPCObjects =
|
||||
this->GetGeneratorTarget()->GetGeneratedISPCObjects(config);
|
||||
std::transform(extraISPCObjects.begin(), extraISPCObjects.end(),
|
||||
std::back_inserter(linkBuild.ExplicitDeps),
|
||||
this->MapToNinjaPath());
|
||||
auto const mapToNinjaPath = this->MapToNinjaPath();
|
||||
std::transform(
|
||||
extraISPCObjects.begin(), extraISPCObjects.end(),
|
||||
std::back_inserter(linkBuild.ExplicitDeps),
|
||||
[&mapToNinjaPath](std::pair<cmSourceFile const*, std::string> const& obj)
|
||||
-> std::string { return mapToNinjaPath(obj.second); });
|
||||
|
||||
linkBuild.ImplicitDeps =
|
||||
this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
|
||||
@@ -1497,7 +1500,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
std::transform(
|
||||
ccByproducts.begin(), ccByproducts.end(),
|
||||
std::back_inserter(globalGen->GetByproductsForCleanTarget()),
|
||||
this->MapToNinjaPath());
|
||||
mapToNinjaPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,6 +536,11 @@ add_RunCMake_test(GenEx-FILE_SET_EXISTS)
|
||||
add_RunCMake_test(GenEx-FILE_SET_PROPERTY)
|
||||
add_RunCMake_test(GenEx-TARGET_PROPERTY)
|
||||
add_RunCMake_test(GenEx-TARGET_RUNTIME_DLLS)
|
||||
list(LENGTH CMAKE_OSX_ARCHITECTURES _num_archs)
|
||||
if(NOT (XCODE AND _num_archs GREATER 1))
|
||||
add_RunCMake_test(GenEx-TARGET_OBJECTS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
||||
set_property(TEST RunCMake.GenEx-TARGET_OBJECTS APPEND PROPERTY LABELS "CUDA")
|
||||
endif()
|
||||
add_RunCMake_test(GenEx-STRING)
|
||||
add_RunCMake_test(GenEx-PATH)
|
||||
add_RunCMake_test(GenEx-PATH_EQUAL)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 4.3)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
@@ -0,0 +1,18 @@
|
||||
include(RunCMake)
|
||||
|
||||
function(run_cmake_and_build name)
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${name}-build")
|
||||
run_cmake_with_options(${name} -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --verbose)
|
||||
endfunction()
|
||||
|
||||
run_cmake_and_build(all)
|
||||
run_cmake_and_build(SOURCE_FILES)
|
||||
|
||||
run_cmake(SOURCE_FILES-noexist)
|
||||
run_cmake(SOURCE_FILES-not-in-target)
|
||||
run_cmake(SOURCE_FILES-imported)
|
||||
run_cmake(SOURCE_FILES-relative)
|
||||
|
||||
run_cmake(invalid)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,7 @@
|
||||
CMake Error at SOURCE_FILES-imported\.cmake:[0-9]+ \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:c_objs,SOURCE_FILES:[^
|
||||
]*/Tests/RunCMake/GenEx-TARGET_OBJECTS/empty4\.c>
|
||||
|
||||
Cannot use SOURCE_FILES argument on imported target "c_objs"
|
||||
@@ -0,0 +1,8 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(c_objs IMPORTED OBJECT)
|
||||
|
||||
add_custom_target(obj ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty4.c>
|
||||
VERBATIM
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,12 @@
|
||||
CMake Error at SOURCE_FILES-noexist\.cmake:[0-9]+ \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:c_objs,SOURCE_FILES:[^
|
||||
]*/Tests/RunCMake/GenEx-TARGET_OBJECTS/empty4\.c>
|
||||
|
||||
Source file:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/GenEx-TARGET_OBJECTS/empty4\.c
|
||||
|
||||
does not exist for target "c_objs"
|
||||
@@ -0,0 +1,8 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(c_objs OBJECT empty1.c empty2.c empty3.c)
|
||||
|
||||
add_custom_target(obj ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty4.c>
|
||||
VERBATIM
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,12 @@
|
||||
CMake Error at SOURCE_FILES-not-in-target\.cmake:[0-9]+ \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:c_objs,SOURCE_FILES:[^
|
||||
]*/Tests/RunCMake/GenEx-TARGET_OBJECTS/empty3\.c>
|
||||
|
||||
Source file:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/GenEx-TARGET_OBJECTS/empty3\.c
|
||||
|
||||
does not exist for target "c_objs"
|
||||
@@ -0,0 +1,9 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(c_objs OBJECT empty1.c empty2.c)
|
||||
add_library(other OBJECT empty3.c)
|
||||
|
||||
add_custom_target(obj ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty3.c>
|
||||
VERBATIM
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,10 @@
|
||||
CMake Error at SOURCE_FILES-relative\.cmake:[0-9]+ \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:c_objs,SOURCE_FILES:empty1\.c>
|
||||
|
||||
Source file:
|
||||
|
||||
empty1\.c
|
||||
|
||||
is not an absolute path
|
||||
@@ -0,0 +1,8 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(c_objs OBJECT empty1.c empty2.c empty3.c)
|
||||
|
||||
add_custom_target(obj ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_OBJECTS:c_objs,SOURCE_FILES:empty1.c>
|
||||
VERBATIM
|
||||
)
|
||||
@@ -0,0 +1,53 @@
|
||||
enable_language(C)
|
||||
|
||||
include(common.cmake)
|
||||
|
||||
add_library(c_objs OBJECT EXCLUDE_FROM_ALL empty1.c empty2.c empty3.c)
|
||||
|
||||
check_target_objects(single_absolute
|
||||
"$<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty2.c>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty2(\.c)?\.(o|obj)$]]
|
||||
)
|
||||
check_target_objects(multi
|
||||
"$<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty1.c;${CMAKE_CURRENT_SOURCE_DIR}/empty2.c>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty1(\.c)?\.(o|obj)$]]
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty2(\.c)?\.(o|obj)$]]
|
||||
)
|
||||
check_target_objects(multi_reordered
|
||||
"$<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty3.c;${CMAKE_CURRENT_SOURCE_DIR}/empty2.c>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty2(\.c)?\.(o|obj)$]]
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty3(\.c)?\.(o|obj)$]]
|
||||
)
|
||||
check_target_objects(multi_duplicate
|
||||
"$<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty1.c;${CMAKE_CURRENT_SOURCE_DIR}/empty3.c;${CMAKE_CURRENT_SOURCE_DIR}/empty1.c>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty1(\.c)?\.(o|obj)$]]
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty3(\.c)?\.(o|obj)$]]
|
||||
)
|
||||
|
||||
add_subdirectory(SOURCE_FILES_subdir)
|
||||
|
||||
if(CMake_TEST_CUDA)
|
||||
enable_language(CUDA)
|
||||
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT ipo_supported LANGUAGES CUDA)
|
||||
|
||||
if(ipo_supported AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
|
||||
add_library(fatbin_objs OBJECT EXCLUDE_FROM_ALL empty1.cu empty2.cu)
|
||||
set_target_properties(fatbin_objs PROPERTIES
|
||||
CUDA_SEPARABLE_COMPILATION ON
|
||||
CUDA_FATBIN_COMPILATION ON
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
INTERPROCEDURAL_OPTIMIZATION ON
|
||||
)
|
||||
|
||||
check_target_objects(fatbin_1
|
||||
"$<TARGET_OBJECTS:fatbin_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty1.cu>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/fatbin_objs\.dir(/(\.|[a-zA-Z]+))?|/build/fatbin_objs\.build/.*)/empty1(\.cu\.o)?\.fatbin$]]
|
||||
)
|
||||
check_target_objects(fatbin_2
|
||||
"$<TARGET_OBJECTS:fatbin_objs,SOURCE_FILES:${CMAKE_CURRENT_SOURCE_DIR}/empty2.cu>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/fatbin_objs\.dir(/(\.|[a-zA-Z]+))?|/build/fatbin_objs\.build/.*)/empty2(\.cu\.o)?\.fatbin$]]
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,4 @@
|
||||
check_target_objects(single_subdir_absolute
|
||||
"$<TARGET_OBJECTS:c_objs,SOURCE_FILES:${CMAKE_SOURCE_DIR}/empty2.c>"
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/SOURCE_FILES-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty2(\.c)?\.(o|obj)$]]
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(C)
|
||||
|
||||
include(common.cmake)
|
||||
|
||||
add_library(c_objs OBJECT EXCLUDE_FROM_ALL empty1.c empty2.c empty3.c)
|
||||
|
||||
check_target_objects(all
|
||||
$<TARGET_OBJECTS:c_objs>
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/all-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty1(\.c)?\.(o|obj)$]]
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/all-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty2(\.c)?\.(o|obj)$]]
|
||||
[[/Tests/RunCMake/GenEx-TARGET_OBJECTS/all-build((/CMakeFiles)?/c_objs\.dir(/(\.|[a-zA-Z]+))?|/build/c_objs\.build/.*)/empty3(\.c)?\.(o|obj)$]]
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
include("${VARS_FILE}")
|
||||
|
||||
list(LENGTH ACTUAL al)
|
||||
list(LENGTH EXPECTED el)
|
||||
if(NOT al EQUAL el)
|
||||
message(FATAL_ERROR "Got the wrong number of objects")
|
||||
endif()
|
||||
|
||||
foreach(a e IN ZIP_LISTS ACTUAL EXPECTED)
|
||||
if(NOT a MATCHES "${e}")
|
||||
message(SEND_ERROR "Object \"${a}\" does not match expected regex \"${e}\"")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -0,0 +1,12 @@
|
||||
function(check_target_objects name genex)
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}_vars_$<CONFIG>.cmake" CONTENT "
|
||||
set(EXPECTED [==[${ARGN}]==])
|
||||
set(ACTUAL [==[${genex}]==])
|
||||
")
|
||||
add_custom_target(${name}_check ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DVARS_FILE=${CMAKE_CURRENT_BINARY_DIR}/${name}_vars_$<CONFIG>.cmake"
|
||||
-P "${CMAKE_SOURCE_DIR}/check_target_objects.cmake"
|
||||
VERBATIM
|
||||
)
|
||||
endfunction()
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,8 @@
|
||||
CMake Error at invalid\.cmake:[0-9]+ \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:c_objs,INVALID_ARGUMENT_1,INVALID_ARGUMENT_2>
|
||||
|
||||
Unrecognized argument:
|
||||
|
||||
INVALID_ARGUMENT_1
|
||||
@@ -0,0 +1,8 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(c_objs OBJECT empty1.c empty2.c empty3.c)
|
||||
|
||||
add_custom_target(obj ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_OBJECTS:c_objs,INVALID_ARGUMENT_1,INVALID_ARGUMENT_2>
|
||||
VERBATIM
|
||||
)
|
||||
Reference in New Issue
Block a user