| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /* 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"
- #include "cmStringAlgorithms.h"
- #include "cmSystemTools.h"
- cmRulePlaceholderExpander::cmRulePlaceholderExpander(
- cmBuildStep buildStep, std::map<std::string, std::string> compilers,
- std::map<std::string, std::string> variableMappings,
- std::string compilerSysroot, std::string linkerSysroot)
- : BuildStep(buildStep)
- , Compilers(std::move(compilers))
- , VariableMappings(std::move(variableMappings))
- , CompilerSysroot(std::move(compilerSysroot))
- , LinkerSysroot(std::move(linkerSysroot))
- {
- }
- std::string cmRulePlaceholderExpander::ExpandVariable(
- std::string const& variable)
- {
- if (this->ReplaceValues->LinkFlags) {
- if (variable == "LINK_FLAGS") {
- return this->ReplaceValues->LinkFlags;
- }
- }
- if (this->ReplaceValues->Linker) {
- if (variable == "CMAKE_LINKER") {
- auto result = this->OutputConverter->ConvertToOutputForExisting(
- this->ReplaceValues->Linker);
- if (this->ReplaceValues->Launcher) {
- // 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.
- result = cmStrCat(this->ReplaceValues->Launcher, " ", result);
- }
- return result;
- }
- }
- if (this->ReplaceValues->Manifests) {
- if (variable == "MANIFESTS") {
- return this->ReplaceValues->Manifests;
- }
- }
- if (this->ReplaceValues->Flags) {
- if (variable == "FLAGS") {
- return this->ReplaceValues->Flags;
- }
- }
- if (this->ReplaceValues->Source) {
- if (variable == "SOURCE") {
- return this->ReplaceValues->Source;
- }
- }
- if (this->ReplaceValues->DynDepFile) {
- if (variable == "DYNDEP_FILE") {
- return this->ReplaceValues->DynDepFile;
- }
- }
- if (this->ReplaceValues->PreprocessedSource) {
- if (variable == "PREPROCESSED_SOURCE") {
- return this->ReplaceValues->PreprocessedSource;
- }
- }
- if (this->ReplaceValues->AssemblySource) {
- if (variable == "ASSEMBLY_SOURCE") {
- return this->ReplaceValues->AssemblySource;
- }
- }
- if (this->ReplaceValues->Object) {
- if (variable == "OBJECT") {
- return this->ReplaceValues->Object;
- }
- }
- if (this->ReplaceValues->ObjectDir) {
- if (variable == "OBJECT_DIR") {
- return this->ReplaceValues->ObjectDir;
- }
- }
- if (this->ReplaceValues->ObjectFileDir) {
- if (variable == "OBJECT_FILE_DIR") {
- return this->ReplaceValues->ObjectFileDir;
- }
- }
- if (this->ReplaceValues->Objects) {
- if (variable == "OBJECTS") {
- return this->ReplaceValues->Objects;
- }
- }
- if (this->ReplaceValues->ObjectsQuoted) {
- if (variable == "OBJECTS_QUOTED") {
- return this->ReplaceValues->ObjectsQuoted;
- }
- }
- if (this->ReplaceValues->CudaCompileMode) {
- if (variable == "CUDA_COMPILE_MODE") {
- return this->ReplaceValues->CudaCompileMode;
- }
- }
- if (this->ReplaceValues->AIXExports) {
- if (variable == "AIX_EXPORTS") {
- return this->ReplaceValues->AIXExports;
- }
- }
- if (this->ReplaceValues->ISPCHeader) {
- if (variable == "ISPC_HEADER") {
- return this->ReplaceValues->ISPCHeader;
- }
- }
- if (this->ReplaceValues->Defines && variable == "DEFINES") {
- return this->ReplaceValues->Defines;
- }
- if (this->ReplaceValues->Includes && variable == "INCLUDES") {
- return this->ReplaceValues->Includes;
- }
- if (this->ReplaceValues->SwiftLibraryName) {
- if (variable == "SWIFT_LIBRARY_NAME") {
- return this->ReplaceValues->SwiftLibraryName;
- }
- }
- if (this->ReplaceValues->SwiftModule) {
- if (variable == "SWIFT_MODULE") {
- return this->ReplaceValues->SwiftModule;
- }
- }
- if (this->ReplaceValues->SwiftModuleName) {
- if (variable == "SWIFT_MODULE_NAME") {
- return this->ReplaceValues->SwiftModuleName;
- }
- }
- if (this->ReplaceValues->SwiftSources) {
- if (variable == "SWIFT_SOURCES") {
- return this->ReplaceValues->SwiftSources;
- }
- }
- if (this->ReplaceValues->TargetPDB) {
- if (variable == "TARGET_PDB") {
- return this->ReplaceValues->TargetPDB;
- }
- }
- if (this->ReplaceValues->TargetCompilePDB) {
- if (variable == "TARGET_COMPILE_PDB") {
- return this->ReplaceValues->TargetCompilePDB;
- }
- }
- if (this->ReplaceValues->DependencyFile) {
- if (variable == "DEP_FILE") {
- return this->ReplaceValues->DependencyFile;
- }
- }
- if (this->ReplaceValues->DependencyTarget) {
- if (variable == "DEP_TARGET") {
- return this->ReplaceValues->DependencyTarget;
- }
- }
- if (this->ReplaceValues->Fatbinary) {
- if (variable == "FATBINARY") {
- return this->ReplaceValues->Fatbinary;
- }
- }
- if (this->ReplaceValues->RegisterFile) {
- if (variable == "REGISTER_FILE") {
- return this->ReplaceValues->RegisterFile;
- }
- }
- if (this->ReplaceValues->Target) {
- if (variable == "TARGET_QUOTED") {
- std::string targetQuoted = this->ReplaceValues->Target;
- if (!targetQuoted.empty() && targetQuoted.front() != '\"') {
- targetQuoted = '\"';
- targetQuoted += this->ReplaceValues->Target;
- targetQuoted += '\"';
- }
- return targetQuoted;
- }
- if (variable == "TARGET_UNQUOTED") {
- std::string unquoted = this->ReplaceValues->Target;
- std::string::size_type sz = unquoted.size();
- if (sz > 2 && unquoted.front() == '\"' && unquoted.back() == '\"') {
- unquoted = unquoted.substr(1, sz - 2);
- }
- return unquoted;
- }
- if (this->ReplaceValues->LanguageCompileFlags) {
- if (variable == "LANGUAGE_COMPILE_FLAGS") {
- return this->ReplaceValues->LanguageCompileFlags;
- }
- }
- if (this->ReplaceValues->Target) {
- if (variable == "TARGET") {
- return this->ReplaceValues->Target;
- }
- }
- if (variable == "TARGET_IMPLIB") {
- return this->TargetImpLib;
- }
- if (variable == "TARGET_VERSION_MAJOR") {
- if (this->ReplaceValues->TargetVersionMajor) {
- return this->ReplaceValues->TargetVersionMajor;
- }
- return "0";
- }
- if (variable == "TARGET_VERSION_MINOR") {
- if (this->ReplaceValues->TargetVersionMinor) {
- return this->ReplaceValues->TargetVersionMinor;
- }
- return "0";
- }
- if (this->ReplaceValues->Target) {
- if (variable == "TARGET_BASE") {
- // Strip the last extension off the target name.
- std::string targetBase = this->ReplaceValues->Target;
- std::string::size_type pos = targetBase.rfind('.');
- if (pos != std::string::npos) {
- return targetBase.substr(0, pos);
- }
- return targetBase;
- }
- }
- }
- if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
- variable == "TARGET_INSTALLNAME_DIR") {
- // All these variables depend on TargetSOName
- if (this->ReplaceValues->TargetSOName) {
- if (variable == "TARGET_SONAME") {
- return this->ReplaceValues->TargetSOName;
- }
- if (variable == "SONAME_FLAG" && this->ReplaceValues->SONameFlag) {
- return this->ReplaceValues->SONameFlag;
- }
- if (this->ReplaceValues->TargetInstallNameDir &&
- variable == "TARGET_INSTALLNAME_DIR") {
- return this->ReplaceValues->TargetInstallNameDir;
- }
- }
- return "";
- }
- if (this->ReplaceValues->LinkLibraries) {
- if (variable == "LINK_LIBRARIES") {
- return this->ReplaceValues->LinkLibraries;
- }
- }
- if (this->ReplaceValues->Language) {
- if (variable == "LANGUAGE") {
- return this->ReplaceValues->Language;
- }
- }
- if (this->ReplaceValues->CMTargetName) {
- if (variable == "TARGET_NAME") {
- return this->ReplaceValues->CMTargetName;
- }
- }
- if (this->ReplaceValues->CMTargetType) {
- if (variable == "TARGET_TYPE") {
- return this->ReplaceValues->CMTargetType;
- }
- }
- if (this->ReplaceValues->Output) {
- if (variable == "OUTPUT") {
- return this->ReplaceValues->Output;
- }
- }
- if (variable == "CMAKE_COMMAND") {
- return this->OutputConverter->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
- }
- auto compIt = this->Compilers.find(variable);
- if (compIt != this->Compilers.end()) {
- std::string ret = this->OutputConverter->ConvertToOutputForExisting(
- 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"];
- if (compIt->second == this->ReplaceValues->Language &&
- this->ReplaceValues->Launcher) {
- // 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.
- ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
- }
- // if there are required arguments to the compiler add it
- // 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;
- ret +=
- this->OutputConverter->EscapeForShell(compilerExternalToolchain, true);
- }
- std::string sysroot;
- // Some platforms may use separate sysroots for compiling and linking.
- // When the build step is link, pass the link sysroot instead.
- if (this->BuildStep == cmBuildStep::Link) {
- sysroot = this->LinkerSysroot;
- } else {
- sysroot = this->CompilerSysroot;
- }
- if (!sysroot.empty() && !compilerOptionSysroot.empty()) {
- ret += " ";
- ret += compilerOptionSysroot;
- ret += this->OutputConverter->EscapeForShell(sysroot, true);
- }
- return ret;
- }
- auto mapIt = this->VariableMappings.find(variable);
- if (mapIt != this->VariableMappings.end()) {
- if (variable.find("_FLAG") == std::string::npos) {
- return this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
- }
- return mapIt->second;
- }
- return variable;
- }
- void cmRulePlaceholderExpander::ExpandRuleVariables(
- cmOutputConverter* outputConverter, std::string& s,
- const RuleVariables& replaceValues)
- {
- this->OutputConverter = outputConverter;
- this->ReplaceValues = &replaceValues;
- this->ExpandVariables(s);
- }
|