cmake/Source/cmRulePlaceholderExpander.cxx

354 lines
11 KiB
C++
Raw Normal View History

2017-04-14 19:02:05 +02:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmRulePlaceholderExpander.h"
#include <utility>
#include "cmOutputConverter.h"
2021-09-14 00:13:48 +02:00
#include "cmStringAlgorithms.h"
2017-04-14 19:02:05 +02:00
#include "cmSystemTools.h"
cmRulePlaceholderExpander::cmRulePlaceholderExpander(
2019-11-11 23:01:05 +01:00
std::map<std::string, std::string> compilers,
std::map<std::string, std::string> variableMappings,
std::string compilerSysroot, std::string linkerSysroot)
: Compilers(std::move(compilers))
, VariableMappings(std::move(variableMappings))
, CompilerSysroot(std::move(compilerSysroot))
, LinkerSysroot(std::move(linkerSysroot))
2017-04-14 19:02:05 +02:00
{
}
2022-08-04 22:12:04 +02:00
std::string cmRulePlaceholderExpander::ExpandVariable(
std::string const& variable)
2017-04-14 19:02:05 +02:00
{
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->LinkFlags) {
2017-04-14 19:02:05 +02:00
if (variable == "LINK_FLAGS") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->LinkFlags;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Manifests) {
2017-04-14 19:02:05 +02:00
if (variable == "MANIFESTS") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Manifests;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Flags) {
2017-04-14 19:02:05 +02:00
if (variable == "FLAGS") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Flags;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Source) {
2017-04-14 19:02:05 +02:00
if (variable == "SOURCE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Source;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->DynDepFile) {
2021-09-14 00:13:48 +02:00
if (variable == "DYNDEP_FILE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->DynDepFile;
2021-09-14 00:13:48 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->PreprocessedSource) {
2017-04-14 19:02:05 +02:00
if (variable == "PREPROCESSED_SOURCE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->PreprocessedSource;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->AssemblySource) {
2017-04-14 19:02:05 +02:00
if (variable == "ASSEMBLY_SOURCE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->AssemblySource;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Object) {
2017-04-14 19:02:05 +02:00
if (variable == "OBJECT") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Object;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->ObjectDir) {
2017-04-14 19:02:05 +02:00
if (variable == "OBJECT_DIR") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->ObjectDir;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->ObjectFileDir) {
2017-04-14 19:02:05 +02:00
if (variable == "OBJECT_FILE_DIR") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->ObjectFileDir;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Objects) {
2017-04-14 19:02:05 +02:00
if (variable == "OBJECTS") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Objects;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->ObjectsQuoted) {
2017-04-14 19:02:05 +02:00
if (variable == "OBJECTS_QUOTED") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->ObjectsQuoted;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->CudaCompileMode) {
2022-03-29 21:10:50 +02:00
if (variable == "CUDA_COMPILE_MODE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->CudaCompileMode;
2022-03-29 21:10:50 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->AIXExports) {
2020-08-30 11:54:41 +02:00
if (variable == "AIX_EXPORTS") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->AIXExports;
2020-08-30 11:54:41 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->ISPCHeader) {
2021-09-14 00:13:48 +02:00
if (variable == "ISPC_HEADER") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->ISPCHeader;
2021-09-14 00:13:48 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Defines && variable == "DEFINES") {
return this->ReplaceValues->Defines;
2017-04-14 19:02:05 +02:00
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Includes && variable == "INCLUDES") {
return this->ReplaceValues->Includes;
2017-04-14 19:02:05 +02:00
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->SwiftLibraryName) {
2019-11-11 23:01:05 +01:00
if (variable == "SWIFT_LIBRARY_NAME") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->SwiftLibraryName;
2019-11-11 23:01:05 +01:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->SwiftModule) {
2019-11-11 23:01:05 +01:00
if (variable == "SWIFT_MODULE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->SwiftModule;
2019-11-11 23:01:05 +01:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->SwiftModuleName) {
2019-11-11 23:01:05 +01:00
if (variable == "SWIFT_MODULE_NAME") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->SwiftModuleName;
2019-11-11 23:01:05 +01:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->SwiftSources) {
2019-11-11 23:01:05 +01:00
if (variable == "SWIFT_SOURCES") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->SwiftSources;
2019-11-11 23:01:05 +01:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->TargetPDB) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_PDB") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->TargetPDB;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->TargetCompilePDB) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_COMPILE_PDB") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->TargetCompilePDB;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->DependencyFile) {
2017-04-14 19:02:05 +02:00
if (variable == "DEP_FILE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->DependencyFile;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->DependencyTarget) {
2021-09-14 00:13:48 +02:00
if (variable == "DEP_TARGET") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->DependencyTarget;
2021-09-14 00:13:48 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Fatbinary) {
2021-09-14 00:13:48 +02:00
if (variable == "FATBINARY") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Fatbinary;
2021-09-14 00:13:48 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->RegisterFile) {
2021-09-14 00:13:48 +02:00
if (variable == "REGISTER_FILE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->RegisterFile;
2021-09-14 00:13:48 +02:00
}
}
2017-04-14 19:02:05 +02:00
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Target) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_QUOTED") {
2022-08-04 22:12:04 +02:00
std::string targetQuoted = this->ReplaceValues->Target;
2019-11-11 23:01:05 +01:00
if (!targetQuoted.empty() && targetQuoted.front() != '\"') {
2017-04-14 19:02:05 +02:00
targetQuoted = '\"';
2022-08-04 22:12:04 +02:00
targetQuoted += this->ReplaceValues->Target;
2017-04-14 19:02:05 +02:00
targetQuoted += '\"';
}
return targetQuoted;
}
if (variable == "TARGET_UNQUOTED") {
2022-08-04 22:12:04 +02:00
std::string unquoted = this->ReplaceValues->Target;
2017-04-14 19:02:05 +02:00
std::string::size_type sz = unquoted.size();
2019-11-11 23:01:05 +01:00
if (sz > 2 && unquoted.front() == '\"' && unquoted.back() == '\"') {
2017-04-14 19:02:05 +02:00
unquoted = unquoted.substr(1, sz - 2);
}
return unquoted;
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->LanguageCompileFlags) {
2017-04-14 19:02:05 +02:00
if (variable == "LANGUAGE_COMPILE_FLAGS") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->LanguageCompileFlags;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Target) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Target;
2017-04-14 19:02:05 +02:00
}
}
if (variable == "TARGET_IMPLIB") {
return this->TargetImpLib;
}
if (variable == "TARGET_VERSION_MAJOR") {
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->TargetVersionMajor) {
return this->ReplaceValues->TargetVersionMajor;
2017-04-14 19:02:05 +02:00
}
return "0";
}
if (variable == "TARGET_VERSION_MINOR") {
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->TargetVersionMinor) {
return this->ReplaceValues->TargetVersionMinor;
2017-04-14 19:02:05 +02:00
}
return "0";
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Target) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_BASE") {
// Strip the last extension off the target name.
2022-08-04 22:12:04 +02:00
std::string targetBase = this->ReplaceValues->Target;
2017-04-14 19:02:05 +02:00
std::string::size_type pos = targetBase.rfind('.');
2017-07-20 19:35:53 +02:00
if (pos != std::string::npos) {
2017-04-14 19:02:05 +02:00
return targetBase.substr(0, pos);
}
return targetBase;
}
}
}
if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
variable == "TARGET_INSTALLNAME_DIR") {
// All these variables depend on TargetSOName
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->TargetSOName) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_SONAME") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->TargetSOName;
2017-04-14 19:02:05 +02:00
}
2022-08-04 22:12:04 +02:00
if (variable == "SONAME_FLAG" && this->ReplaceValues->SONameFlag) {
return this->ReplaceValues->SONameFlag;
2017-04-14 19:02:05 +02:00
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->TargetInstallNameDir &&
2017-04-14 19:02:05 +02:00
variable == "TARGET_INSTALLNAME_DIR") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->TargetInstallNameDir;
2017-04-14 19:02:05 +02:00
}
}
return "";
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->LinkLibraries) {
2017-04-14 19:02:05 +02:00
if (variable == "LINK_LIBRARIES") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->LinkLibraries;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Language) {
2017-04-14 19:02:05 +02:00
if (variable == "LANGUAGE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Language;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->CMTargetName) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_NAME") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->CMTargetName;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->CMTargetType) {
2017-04-14 19:02:05 +02:00
if (variable == "TARGET_TYPE") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->CMTargetType;
2017-04-14 19:02:05 +02:00
}
}
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Output) {
2017-04-14 19:02:05 +02:00
if (variable == "OUTPUT") {
2022-08-04 22:12:04 +02:00
return this->ReplaceValues->Output;
2017-04-14 19:02:05 +02:00
}
}
if (variable == "CMAKE_COMMAND") {
2022-08-04 22:12:04 +02:00
return this->OutputConverter->ConvertToOutputFormat(
2020-08-30 11:54:41 +02:00
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
2017-04-14 19:02:05 +02:00
}
2020-02-01 23:06:01 +01:00
auto compIt = this->Compilers.find(variable);
2017-04-14 19:02:05 +02:00
if (compIt != this->Compilers.end()) {
2022-08-04 22:12:04 +02:00
std::string ret = this->OutputConverter->ConvertToOutputForExisting(
2017-04-14 19:02:05 +02:00
this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER"]);
std::string const& compilerArg1 =
this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER_ARG1"];
std::string const& compilerTarget =
this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER_TARGET"];
std::string const& compilerOptionTarget =
this->VariableMappings["CMAKE_" + compIt->second +
"_COMPILE_OPTIONS_TARGET"];
std::string const& compilerExternalToolchain =
this->VariableMappings["CMAKE_" + compIt->second +
"_COMPILER_EXTERNAL_TOOLCHAIN"];
std::string const& compilerOptionExternalToolchain =
this->VariableMappings["CMAKE_" + compIt->second +
"_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN"];
std::string const& compilerOptionSysroot =
this->VariableMappings["CMAKE_" + compIt->second +
"_COMPILE_OPTIONS_SYSROOT"];
2022-08-04 22:12:04 +02:00
if (compIt->second == this->ReplaceValues->Language &&
this->ReplaceValues->Launcher) {
2021-09-14 00:13:48 +02:00
// Add launcher as part of expansion so that it always appears
// immediately before the command itself, regardless of whether the
// overall rule template contains other content at the front.
2022-08-04 22:12:04 +02:00
ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
2021-09-14 00:13:48 +02:00
}
// if there are required arguments to the compiler add it
2017-04-14 19:02:05 +02:00
// to the compiler string
if (!compilerArg1.empty()) {
ret += " ";
ret += compilerArg1;
}
if (!compilerTarget.empty() && !compilerOptionTarget.empty()) {
ret += " ";
ret += compilerOptionTarget;
ret += compilerTarget;
}
if (!compilerExternalToolchain.empty() &&
!compilerOptionExternalToolchain.empty()) {
ret += " ";
ret += compilerOptionExternalToolchain;
2022-08-04 22:12:04 +02:00
ret +=
this->OutputConverter->EscapeForShell(compilerExternalToolchain, true);
2017-04-14 19:02:05 +02:00
}
2017-07-20 19:35:53 +02:00
std::string sysroot;
// Some platforms may use separate sysroots for compiling and linking.
// If we detect link flags, then we pass the link sysroot instead.
// FIXME: Use a more robust way to detect link line expansion.
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->LinkFlags) {
2017-07-20 19:35:53 +02:00
sysroot = this->LinkerSysroot;
} else {
sysroot = this->CompilerSysroot;
}
if (!sysroot.empty() && !compilerOptionSysroot.empty()) {
2017-04-14 19:02:05 +02:00
ret += " ";
ret += compilerOptionSysroot;
2022-08-04 22:12:04 +02:00
ret += this->OutputConverter->EscapeForShell(sysroot, true);
2017-04-14 19:02:05 +02:00
}
return ret;
}
2020-02-01 23:06:01 +01:00
auto mapIt = this->VariableMappings.find(variable);
2017-04-14 19:02:05 +02:00
if (mapIt != this->VariableMappings.end()) {
2017-07-20 19:35:53 +02:00
if (variable.find("_FLAG") == std::string::npos) {
2021-09-14 00:13:48 +02:00
std::string ret =
2022-08-04 22:12:04 +02:00
this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
2021-09-14 00:13:48 +02:00
2022-08-04 22:12:04 +02:00
if (this->ReplaceValues->Launcher && variable == "CMAKE_LINKER") {
2021-09-14 00:13:48 +02:00
// Add launcher as part of expansion so that it always appears
// immediately before the command itself, regardless of whether the
// overall rule template contains other content at the front.
2022-08-04 22:12:04 +02:00
ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
2021-09-14 00:13:48 +02:00
}
return ret;
2017-04-14 19:02:05 +02:00
}
return mapIt->second;
}
return variable;
}
void cmRulePlaceholderExpander::ExpandRuleVariables(
cmOutputConverter* outputConverter, std::string& s,
const RuleVariables& replaceValues)
{
2022-08-04 22:12:04 +02:00
this->OutputConverter = outputConverter;
this->ReplaceValues = &replaceValues;
2020-08-30 11:54:41 +02:00
2022-08-04 22:12:04 +02:00
this->ExpandVariables(s);
2017-04-14 19:02:05 +02:00
}