Add generator expressions for compiler versions.
New generator expressions allow retrieval of the version per language, as well as equality comparison.
This commit is contained in:
parent
d221eac812
commit
47a8db5bcd
|
@ -54,6 +54,13 @@
|
|||
"else '0'.\n" \
|
||||
" $<VERSION_EQUAL:v1,v2> = '1' if v1 is the same version as v2, " \
|
||||
"else '0'.\n" \
|
||||
" $<C_COMPILER_VERSION> = The version of the C compiler used.\n" \
|
||||
" $<C_COMPILER_VERSION:ver> = '1' if the version of the C " \
|
||||
"compiler matches ver, otherwise '0'.\n" \
|
||||
" $<CXX_COMPILER_VERSION> = The version of the CXX compiler " \
|
||||
"used.\n" \
|
||||
" $<CXX_COMPILER_VERSION:ver> = '1' if the version of the CXX " \
|
||||
"compiler matches ver, 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" \
|
||||
|
|
|
@ -341,6 +341,102 @@ static const struct CXXCompilerIdNode : public CompilerIdNode
|
|||
}
|
||||
} cxxCompilerIdNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct CompilerVersionNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
CompilerVersionNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
|
||||
|
||||
std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *,
|
||||
const std::string &lang) const
|
||||
{
|
||||
const char *compilerVersion = context->Makefile ?
|
||||
context->Makefile->GetSafeDefinition((
|
||||
"CMAKE_" + lang + "_COMPILER_VERSION").c_str()) : "";
|
||||
if (parameters.size() == 0)
|
||||
{
|
||||
return compilerVersion ? compilerVersion : "";
|
||||
}
|
||||
|
||||
cmsys::RegularExpression compilerIdValidator;
|
||||
compilerIdValidator.compile("^[0-9\\.]*$");
|
||||
if (!compilerIdValidator.find(parameters.begin()->c_str()))
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"Expression syntax not recognized.");
|
||||
return std::string();
|
||||
}
|
||||
if (!compilerVersion)
|
||||
{
|
||||
return parameters.front().empty() ? "1" : "0";
|
||||
}
|
||||
|
||||
return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
|
||||
parameters.begin()->c_str(),
|
||||
compilerVersion) ? "1" : "0";
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct CCompilerVersionNode : public CompilerVersionNode
|
||||
{
|
||||
CCompilerVersionNode() {}
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
if (parameters.size() != 0 && parameters.size() != 1)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<C_COMPILER_VERSION> expression requires one or two parameters");
|
||||
return std::string();
|
||||
}
|
||||
if (!context->HeadTarget)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<C_COMPILER_VERSION> may only be used with targets. It may not "
|
||||
"be used with add_custom_command.");
|
||||
}
|
||||
return this->EvaluateWithLanguage(parameters, context, content,
|
||||
dagChecker, "C");
|
||||
}
|
||||
} cCompilerVersionNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct CxxCompilerVersionNode : public CompilerVersionNode
|
||||
{
|
||||
CxxCompilerVersionNode() {}
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
if (parameters.size() != 0 && parameters.size() != 1)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<CXX_COMPILER_VERSION> expression requires one or two "
|
||||
"parameters");
|
||||
return std::string();
|
||||
}
|
||||
if (!context->HeadTarget)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<CXX_COMPILER_VERSION> may only be used with targets. It may "
|
||||
"not be used with add_custom_command.");
|
||||
}
|
||||
return this->EvaluateWithLanguage(parameters, context, content,
|
||||
dagChecker, "CXX");
|
||||
}
|
||||
} cxxCompilerVersionNode;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct VersionGreaterNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
|
@ -1247,6 +1343,10 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
return &versionLessNode;
|
||||
else if (identifier == "VERSION_EQUAL")
|
||||
return &versionEqualNode;
|
||||
else if (identifier == "C_COMPILER_VERSION")
|
||||
return &cCompilerVersionNode;
|
||||
else if (identifier == "CXX_COMPILER_VERSION")
|
||||
return &cxxCompilerVersionNode;
|
||||
else if (identifier == "CONFIGURATION")
|
||||
return &configurationNode;
|
||||
else if (identifier == "CONFIG")
|
||||
|
|
|
@ -5,11 +5,23 @@ project(CompileOptions)
|
|||
add_library(testlib other.cpp)
|
||||
|
||||
add_executable(CompileOptions main.cpp)
|
||||
|
||||
macro(get_compiler_test_genex lst lang)
|
||||
list(APPEND ${lst} -DTEST_${lang}_COMPILER_VERSION="$<${lang}_COMPILER_VERSION>")
|
||||
list(APPEND ${lst} -DTEST_${lang}_COMPILER_VERSION_EQUALITY=$<${lang}_COMPILER_VERSION:${CMAKE_${lang}_COMPILER_VERSION}>)
|
||||
endmacro()
|
||||
|
||||
get_compiler_test_genex(c_tests C)
|
||||
get_compiler_test_genex(cxx_tests CXX)
|
||||
|
||||
set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
|
||||
"-DTEST_DEFINE"
|
||||
"-DNEEDS_ESCAPE=\"E$CAPE\""
|
||||
"$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
|
||||
${c_tests}
|
||||
${cxx_tests}
|
||||
)
|
||||
|
||||
target_link_libraries(CompileOptions testlib)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
|
@ -18,3 +30,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|||
"DO_GNU_TESTS"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(CompileOptions
|
||||
PRIVATE
|
||||
"EXPECTED_C_COMPILER_VERSION=\"${CMAKE_C_COMPILER_VERSION}\""
|
||||
"EXPECTED_CXX_COMPILER_VERSION=\"${CMAKE_CXX_COMPILER_VERSION}\""
|
||||
)
|
||||
|
|
|
@ -16,5 +16,9 @@
|
|||
|
||||
int main()
|
||||
{
|
||||
return strcmp(NEEDS_ESCAPE, "E$CAPE") == 0 ? 0 : 1;
|
||||
return (strcmp(NEEDS_ESCAPE, "E$CAPE") == 0
|
||||
&& strcmp(EXPECTED_C_COMPILER_VERSION, TEST_C_COMPILER_VERSION) == 0
|
||||
&& strcmp(EXPECTED_CXX_COMPILER_VERSION, TEST_CXX_COMPILER_VERSION) == 0
|
||||
&& TEST_C_COMPILER_VERSION_EQUALITY == 1
|
||||
&& TEST_CXX_COMPILER_VERSION_EQUALITY == 1) ? 0 : 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue