Browse Source

Add <LANG>_COMPILER_ID generator expressions.

These expressions evaluate to the id of the compiler used to build
the target, or can be used to test if the compiler id matches a
specified value.
Stephen Kelly 12 years ago
parent
commit
1319a147bd
2 changed files with 110 additions and 0 deletions
  1. 8 0
      Source/cmDocumentGeneratorExpressions.h
  2. 102 0
      Source/cmGeneratorExpressionEvaluator.cxx

+ 8 - 0
Source/cmDocumentGeneratorExpressions.h

@@ -40,6 +40,14 @@
   "is exported using export(), or when the target is used by another "  \
   "target in the same buildsystem. Expands to the empty string "        \
   "otherwise.\n"                                                        \
+  "  $<C_COMPILER_ID>          = The CMake-id of the C compiler "       \
+  "used.\n"                                                             \
+  "  $<C_COMPILER_ID:comp>     = '1' if the CMake-id of the C "         \
+  "compiler matches comp, otherwise '0'.\n"                             \
+  "  $<CXX_COMPILER_ID>          = The CMake-id of the CXX compiler "   \
+  "used.\n"                                                             \
+  "  $<CXX_COMPILER_ID:comp>     = '1' if the CMake-id of the CXX "     \
+  "compiler matches comp, otherwise '0'.\n"                             \
   "  $<TARGET_FILE:tgt>        = main file (.exe, .so.1.2, .a)\n"       \
   "  $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n"   \
   "  $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n"            \

+ 102 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -246,6 +246,104 @@ static const struct SemicolonNode : public cmGeneratorExpressionNode
   }
 } semicolonNode;
 
+//----------------------------------------------------------------------------
+struct CompilerIdNode : public cmGeneratorExpressionNode
+{
+  CompilerIdNode() {}
+
+  virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
+
+  std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *,
+                       const std::string &lang) const
+  {
+    const char *compilerId = context->Makefile ?
+                              context->Makefile->GetSafeDefinition((
+                              "CMAKE_" + lang + "_COMPILER_ID").c_str()) : "";
+    if (parameters.size() == 0)
+      {
+      return compilerId ? compilerId : "";
+      }
+    else
+    {
+    cmsys::RegularExpression compilerIdValidator;
+    compilerIdValidator.compile("^[A-Za-z0-9_]*$");
+    if (!compilerIdValidator.find(parameters.begin()->c_str()))
+      {
+      reportError(context, content->GetOriginalExpression(),
+                  "Expression syntax not recognized.");
+      return std::string();
+      }
+    if (!compilerId)
+      {
+      return parameters.front().empty() ? "1" : "0";
+      }
+
+    if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0)
+      {
+      return "1";
+      }
+    return "0";
+    }
+  }
+};
+
+//----------------------------------------------------------------------------
+static const struct CCompilerIdNode : public CompilerIdNode
+{
+  CCompilerIdNode() {}
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *dagChecker) const
+  {
+    if (parameters.size() != 0 && parameters.size() != 1)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<C_COMPILER_ID> expression requires one or two parameters");
+      return std::string();
+      }
+    if (!context->HeadTarget)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<C_COMPILER_ID> may only be used with targets.  It may not "
+          "be used with add_custom_command.");
+      }
+    return this->EvaluateWithLanguage(parameters, context, content,
+                                      dagChecker, "C");
+  }
+} cCompilerIdNode;
+
+//----------------------------------------------------------------------------
+static const struct CXXCompilerIdNode : public CompilerIdNode
+{
+  CXXCompilerIdNode() {}
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *dagChecker) const
+  {
+    if (parameters.size() != 0 && parameters.size() != 1)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<CXX_COMPILER_ID> expression requires one or two parameters");
+      return std::string();
+      }
+    if (!context->HeadTarget)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<CXX_COMPILER_ID> may only be used with targets.  It may not "
+          "be used with add_custom_command.");
+      }
+    return this->EvaluateWithLanguage(parameters, context, content,
+                                      dagChecker, "CXX");
+  }
+} cxxCompilerIdNode;
+
 //----------------------------------------------------------------------------
 static const struct ConfigurationNode : public cmGeneratorExpressionNode
 {
@@ -1055,6 +1153,10 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     return &orNode;
   else if (identifier == "NOT")
     return &notNode;
+  else if (identifier == "C_COMPILER_ID")
+    return &cCompilerIdNode;
+  else if (identifier == "CXX_COMPILER_ID")
+    return &cxxCompilerIdNode;
   else if (identifier == "CONFIGURATION")
     return &configurationNode;
   else if (identifier == "CONFIG")