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" \
|
"else '0'.\n" \
|
||||||
" $<VERSION_EQUAL:v1,v2> = '1' if v1 is the same version as v2, " \
|
" $<VERSION_EQUAL:v1,v2> = '1' if v1 is the same version as v2, " \
|
||||||
"else '0'.\n" \
|
"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_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
|
||||||
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
|
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
|
||||||
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
|
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
|
||||||
|
|
|
@ -341,6 +341,102 @@ static const struct CXXCompilerIdNode : public CompilerIdNode
|
||||||
}
|
}
|
||||||
} cxxCompilerIdNode;
|
} 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
|
static const struct VersionGreaterNode : public cmGeneratorExpressionNode
|
||||||
{
|
{
|
||||||
|
@ -1247,6 +1343,10 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
||||||
return &versionLessNode;
|
return &versionLessNode;
|
||||||
else if (identifier == "VERSION_EQUAL")
|
else if (identifier == "VERSION_EQUAL")
|
||||||
return &versionEqualNode;
|
return &versionEqualNode;
|
||||||
|
else if (identifier == "C_COMPILER_VERSION")
|
||||||
|
return &cCompilerVersionNode;
|
||||||
|
else if (identifier == "CXX_COMPILER_VERSION")
|
||||||
|
return &cxxCompilerVersionNode;
|
||||||
else if (identifier == "CONFIGURATION")
|
else if (identifier == "CONFIGURATION")
|
||||||
return &configurationNode;
|
return &configurationNode;
|
||||||
else if (identifier == "CONFIG")
|
else if (identifier == "CONFIG")
|
||||||
|
|
|
@ -5,11 +5,23 @@ project(CompileOptions)
|
||||||
add_library(testlib other.cpp)
|
add_library(testlib other.cpp)
|
||||||
|
|
||||||
add_executable(CompileOptions main.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
|
set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
|
||||||
"-DTEST_DEFINE"
|
"-DTEST_DEFINE"
|
||||||
"-DNEEDS_ESCAPE=\"E$CAPE\""
|
"-DNEEDS_ESCAPE=\"E$CAPE\""
|
||||||
"$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
|
"$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
|
||||||
|
${c_tests}
|
||||||
|
${cxx_tests}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(CompileOptions testlib)
|
target_link_libraries(CompileOptions testlib)
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
|
@ -18,3 +30,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
"DO_GNU_TESTS"
|
"DO_GNU_TESTS"
|
||||||
)
|
)
|
||||||
endif()
|
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()
|
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