cmExportBuildFileGenerator: handle genex-wrapped source paths

Previously a fileset with `$<$<CONFIG:Debug>:some_file>` would show up
as-is (with escaping) in the build directory export. Instead, evaluate
all fileset entries as generator expressions and list them as they are
similar to the installation information.
This commit is contained in:
Ben Boeckel 2022-04-15 15:45:54 -04:00
parent 60fab8a6e0
commit 9ee47188c0
2 changed files with 131 additions and 20 deletions

View File

@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */ file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildFileGenerator.h" #include "cmExportBuildFileGenerator.h"
#include <algorithm>
#include <map> #include <map>
#include <memory> #include <memory>
#include <set> #include <set>
@ -15,7 +16,6 @@
#include "cmGeneratorExpression.h" #include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h" #include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h" #include "cmLocalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmMessageType.h" #include "cmMessageType.h"
@ -362,16 +362,93 @@ std::string cmExportBuildFileGenerator::InstallNameDir(
return install_name_dir; return install_name_dir;
} }
std::string cmExportBuildFileGenerator::GetFileSetDirectories( namespace {
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/) bool EntryIsContextSensitive(
const std::unique_ptr<cmCompiledGeneratorExpression>& cge)
{ {
return cmOutputConverter::EscapeForCMake( return cge->GetHadContextSensitiveCondition();
cmJoin(fileSet->GetDirectoryEntries(), ";")); }
} }
std::string cmExportBuildFileGenerator::GetFileSetFiles( std::string cmExportBuildFileGenerator::GetFileSetDirectories(
cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/) cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport* /*te*/)
{ {
return cmOutputConverter::EscapeForCMake( std::vector<std::string> resultVector;
cmJoin(fileSet->GetFileEntries(), ";"));
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
auto directoryEntries = fileSet->CompileDirectoryEntries();
for (auto const& config : configs) {
auto directories = fileSet->EvaluateDirectoryEntries(
directoryEntries, gte->LocalGenerator, config, gte);
bool const contextSensitive =
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive);
for (auto const& directory : directories) {
auto dest = cmOutputConverter::EscapeForCMake(
directory, cmOutputConverter::WrapQuotes::NoWrap);
if (contextSensitive && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
} else {
resultVector.push_back(cmStrCat('"', dest, '"'));
break;
}
}
}
return cmJoin(resultVector, " ");
}
std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
cmFileSet* fileSet,
cmTargetExport* /*te*/)
{
std::vector<std::string> resultVector;
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
auto fileEntries = fileSet->CompileFileEntries();
auto directoryEntries = fileSet->CompileDirectoryEntries();
for (auto const& config : configs) {
auto directories = fileSet->EvaluateDirectoryEntries(
directoryEntries, gte->LocalGenerator, config, gte);
std::map<std::string, std::vector<std::string>> files;
for (auto const& entry : fileEntries) {
fileSet->EvaluateFileEntry(directories, files, entry,
gte->LocalGenerator, config, gte);
}
bool const contextSensitive =
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive) ||
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
for (auto const& it : files) {
for (auto const& filename : it.second) {
auto escapedFile = cmOutputConverter::EscapeForCMake(
filename, cmOutputConverter::WrapQuotes::NoWrap);
if (contextSensitive && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
} else {
resultVector.push_back(cmStrCat('"', escapedFile, '"'));
}
}
}
if (!(contextSensitive && configs.size() != 1)) {
break;
}
}
return cmJoin(resultVector, " ");
} }

View File

@ -19,20 +19,54 @@ include("${export_build_dir}/install/lib/cmake/export.cmake")
assert_prop_eq(export::lib1 HEADER_SETS "") assert_prop_eq(export::lib1 HEADER_SETS "")
assert_prop_eq(export::lib1 INTERFACE_HEADER_SETS "HEADERS;b;c;d;dir3;e;f;g") assert_prop_eq(export::lib1 INTERFACE_HEADER_SETS "HEADERS;b;c;d;dir3;e;f;g")
assert_prop_eq(export::lib1 HEADER_SET "${CMAKE_CURRENT_SOURCE_DIR}/error.c") assert_prop_eq(export::lib1 HEADER_SET "${CMAKE_CURRENT_SOURCE_DIR}/error.c")
assert_prop_eq(export::lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") if (_multi_config)
assert_prop_eq(export::lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
else ()
assert_prop_eq(export::lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
endif ()
assert_prop_eq(export::lib1 HEADER_SET_b "${CMAKE_CURRENT_SOURCE_DIR}/h2.h") assert_prop_eq(export::lib1 HEADER_SET_b "${CMAKE_CURRENT_SOURCE_DIR}/h2.h")
assert_prop_eq(export::lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR}") if (_multi_config)
assert_prop_eq(export::lib1 HEADER_SET_c "$<1:dir/dir.h>") assert_prop_eq(export::lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(export::lib1 HEADER_DIRS_c "$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>") else ()
assert_prop_eq(export::lib1 HEADER_SET_d "${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>/empty.h") assert_prop_eq(export::lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR}")
assert_prop_eq(export::lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR}") endif ()
assert_prop_eq(export::lib1 HEADER_SET_e "${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>/empty2.h") assert_prop_eq(export::lib1 HEADER_SET_c "${CMAKE_CURRENT_SOURCE_DIR}/dir/dir.h")
assert_prop_eq(export::lib1 HEADER_DIRS_e "${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>") if (_multi_config)
assert_prop_eq(export::lib1 HEADER_DIRS_c "${CMAKE_CURRENT_SOURCE_DIR}/dir;${CMAKE_CURRENT_SOURCE_DIR}/dir")
else ()
assert_prop_eq(export::lib1 HEADER_DIRS_c "${CMAKE_CURRENT_SOURCE_DIR}/dir")
endif ()
if (_multi_config)
assert_prop_eq(export::lib1 HEADER_SET_d "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug/empty.h>;$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release/empty.h>")
assert_prop_eq(export::lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
else ()
assert_prop_eq(export::lib1 HEADER_SET_d "${CMAKE_CURRENT_SOURCE_DIR}/debug/empty.h")
assert_prop_eq(export::lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR}")
endif ()
if (_multi_config)
assert_prop_eq(export::lib1 HEADER_SET_e "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug/empty2.h>;$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release/empty2.h>")
assert_prop_eq(export::lib1 HEADER_DIRS_e "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug>;$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release>")
else ()
assert_prop_eq(export::lib1 HEADER_SET_e "${CMAKE_CURRENT_SOURCE_DIR}/debug/empty2.h")
assert_prop_eq(export::lib1 HEADER_DIRS_e "${CMAKE_CURRENT_SOURCE_DIR}/debug")
endif ()
assert_prop_eq(export::lib1 HEADER_SET_f "${CMAKE_CURRENT_SOURCE_DIR}/empty3.h") assert_prop_eq(export::lib1 HEADER_SET_f "${CMAKE_CURRENT_SOURCE_DIR}/empty3.h")
assert_prop_eq(export::lib1 HEADER_DIRS_f "${CMAKE_CURRENT_SOURCE_DIR}") if (_multi_config)
assert_prop_eq(export::lib1 HEADER_DIRS_f "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
else ()
assert_prop_eq(export::lib1 HEADER_DIRS_f "${CMAKE_CURRENT_SOURCE_DIR}")
endif ()
assert_prop_eq(export::lib1 HEADER_SET_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1/file1.h;${CMAKE_CURRENT_SOURCE_DIR}/dir2/file2.h") assert_prop_eq(export::lib1 HEADER_SET_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1/file1.h;${CMAKE_CURRENT_SOURCE_DIR}/dir2/file2.h")
assert_prop_eq(export::lib1 HEADER_DIRS_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2") if (_multi_config)
assert_prop_eq(export::lib1 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR};$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2;${CMAKE_CURRENT_SOURCE_DIR}/dir3;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir2>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>") assert_prop_eq(export::lib1 HEADER_DIRS_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir1")
else ()
assert_prop_eq(export::lib1 HEADER_DIRS_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1")
endif ()
if (_multi_config)
assert_prop_eq(export::lib1 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR};$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2;${CMAKE_CURRENT_SOURCE_DIR}/dir3;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug>>;$<BUILD_INTERFACE:$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release>>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>")
else ()
assert_prop_eq(export::lib1 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR};$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2;${CMAKE_CURRENT_SOURCE_DIR}/dir3;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/debug>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>")
endif ()
assert_prop_eq(install::lib1 HEADER_SETS "") assert_prop_eq(install::lib1 HEADER_SETS "")
assert_prop_eq(install::lib1 INTERFACE_HEADER_SETS "HEADERS;b;c;d;dir3;e;f;g") assert_prop_eq(install::lib1 INTERFACE_HEADER_SETS "HEADERS;b;c;d;dir3;e;f;g")