简体   繁体   English

如何使CHECK_CXX_COMPILER_FLAG的非法值失败?

[英]How to have CHECK_CXX_COMPILER_FLAG fail on illegal value?

Our CMakeFile.txt contains the following for SunCC code paths. 我们的CMakeFile.txt包含以下SunCC代码路径。 SunCC uses -xarch=XXX rather than GCC style -mXXX . SunCC使用-xarch=XXX而不是GCC样式-mXXX

CHECK_CXX_COMPILER_FLAG("-xarch=sha" CRYPTOPP_IA32_SHA)

When we run CMake under Sun's compiler it results in: 当我们在Sun的编译器下运行CMake时,结果为:

-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CRYPTOPP_IA32_SSSE3
-- Performing Test CRYPTOPP_IA32_SSSE3 - Success
-- Performing Test CRYPTOPP_IA32_SSE4
-- Performing Test CRYPTOPP_IA32_SSE4 - Success
-- Performing Test CRYPTOPP_IA32_CLMUL
-- Performing Test CRYPTOPP_IA32_CLMUL - Success
-- Performing Test CRYPTOPP_IA32_AES
-- Performing Test CRYPTOPP_IA32_AES - Success
-- Performing Test CRYPTOPP_IA32_SHA
-- Performing Test CRYPTOPP_IA32_SHA - Success
...

However, when we compile it results in: 但是,当我们编译时会导致:

$ make sha-simd.o shacal2-simd.o VERBOSE=1

make -f CMakeFiles/cryptopp-object.dir/build.make CMakeFiles/cryptopp-object.dir/sha-simd.cpp.o
Building CXX object CMakeFiles/cryptopp-object.dir/sha-simd.cpp.o
/opt/solarisstudio12.4/bin/CC -m32 -template=no%extdef -g -xO2 -DNDEBUG -xarch=sha -o CMakeFiles/cryptopp-object.dir/sha-simd.cpp.o -c /export/home/test/sha-simd.cpp
CC: Warning: illegal use of -xarch option, illegal value ignored: sha

make -f CMakeFiles/cryptopp-object.dir/build.make CMakeFiles/cryptopp-object.dir/shacal2-simd.cpp.o
Building CXX object CMakeFiles/cryptopp-object.dir/shacal2-simd.cpp.o
/opt/solarisstudio12.4/bin/CC -m32 -template=no%extdef -g -xO2 -DNDEBUG -xarch=sha -o CMakeFiles/cryptopp-object.dir/shacal2-simd.cpp.o -c /export/home/test/shacal2-simd.cpp
CC: Warning: illegal use of -xarch option, illegal value ignored: sha

Adding SunCC's -errwarn and -errwarn=%all does not help CMake to detect the failure. 添加SunCC的-errwarn-errwarn=%all不能帮助CMake检测到故障。

The message could cause a lot of problems for users. 该消息可能给用户带来很多问题。 It also violates our governance for clean compiles. 它还违反了我们对干净编译的治理。 We would like to clean it up and avoid any trouble. 我们想清理它,避免任何麻烦。

How do we tell CMake to fail the CHECK_CXX_COMPILER_FLAG test on an illegal value? 我们如何告诉CMake对非法值的CHECK_CXX_COMPILER_FLAG测试失败?

I guess, when checks a compiler flag, CMake simply verifies result of the compilation command. 我猜想,当检查编译器标志时,CMake只会验证编译命令的结果 As "Warning" message doesn't affect on result, CMake cannot detect that the flag is actually ignored. 由于“警告”消息不会影响结果,因此CMake无法检测到该标志实际上已被忽略。

You may manually test the flag with try_compile command, so you can check output for some patterns (eg, for "Warning"). 您可以使用try_compile命令手动测试该标志,以便检查某些模式的输出(例如,“警告”)。

There is also CHECK_CXX_SOURCE_COMPILES macro, which already accepts pattern for match. 还有CHECK_CXX_SOURCE_COMPILES宏,该宏已经接受匹配模式。

See also that question and my answer for it. 另请参见该问题和我的答案。

The best we have been able to do is add a custom CheckCompilerOption . 我们能够做的最好的事情就是添加一个自定义CheckCompilerOption However, it has other problems because CMake does not supply accurate CXXFLAGS when CMakeLists.txt is executed. 但是,它还有其他问题,因为执行CMakeLists.txt时CMake无法提供准确的CXXFLAGS The problem surfaces during cross-compiles. 问题在交叉编译期间浮出水面。 Also see CMake Issue 18813 . 另请参阅CMake问题18813

function(CheckCompilerOption option variable)

    if (${CMAKE_CXX_COMPILER_ID} STREQUAL "SunPro")

        message(STATUS "Performing Test ${variable}")        
        execute_process(
            COMMAND sh -c "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${option} -E -xdumpmacros /dev/null 2>&1"
            COMMAND egrep -i -c "illegal value ignored"
            RESULT_VARIABLE COMMAND_RESULT
            OUTPUT_VARIABLE COMMAND_OUTPUT
            OUTPUT_STRIP_TRAILING_WHITESPACE)

            if (COMMAND_RESULT STREQUAL "1" AND COMMAND_OUTPUT STREQUAL "0")
                set(${variable} 1 PARENT_SCOPE)
                message(STATUS "Performing Test ${variable} - Success")
            else ()
                set(${variable} 0 PARENT_SCOPE)
                message(STATUS "Performing Test ${variable} - Failed")
            endif ()

    else()

        CHECK_CXX_COMPILER_FLAG(${option} ${variable})

    endif()

endfunction(CheckCompilerOption)

"${${variable}}" looks strange, but I believe its correct based on some existing code. "${${variable}}"看起来很奇怪,但是我相信它基于某些现有代码是正确的。 The first version with the dereference was wrong. 取消引用的第一个版本是错误的。 The CMake docs for function don't discuss it and don't offer an example, so we were flying blind again. CMake function文档没有讨论它,也没有提供示例,因此我们又一次失明了。 It is mentioned in What's the CMake syntax to set and use variables? 设置和使用变量的CMake语法什么? on Stack Overflow. 在堆栈溢出。

It can be called like expected: 可以像预期的那样调用:

CheckCompilerOption("-msse4.1 -maes" CRYPTOPP_IA32_AES)
CheckCompilerOption("-msse4.2 -msha" CRYPTOPP_IA32_SHA)
...

CheckCompilerOption("-march=armv7-a -mfloat-abi=hard -mfpu=neon" CRYPTOPP_ARMV7A_HARD)
CheckCompilerOption("-march=armv7-a -mfloat-abi=softfp -mfpu=neon" CRYPTOPP_ARMV7A_SOFTFP)
...

CheckCompilerOption("-march=armv8-a+crc" CRYPTOPP_ARMV8A_CRC)
CheckCompilerOption("-march=armv8-a+crypto" CRYPTOPP_ARMV8A_CRYPTO)
...

CheckCompilerOption("-xarch=aes" CRYPTOPP_SUNCC_AES)
CheckCompilerOption("-xarch=sha" CRYPTOPP_SUNCC_SHA)

If you need to go back further than CMake 3.0 (like to Ubuntu 10 or CentOS 5 with CMake 2.8), then abandon CHECK_CXX_COMPILER_FLAG and use the top part of the function for Clang, GCC, ICC, etc. 如果您需要返回到比CMake 3.0更远的位置(例如,带有Ubuntu或带有CMake 2.8的CentOS 5),请放弃CHECK_CXX_COMPILER_FLAG并将函数的顶部用于Clang,GCC,ICC等。

GCC's syntax for checking is an option is shown below. GCC的检查语法是一个选项,如下所示。 The command uses SSSE3 as an example. 该命令以SSSE3为例。

$(CXX) -x c++ $(CXXFLAGS) -mssse3 -dM -E - </dev/null 2>&1 | egrep -i -c __SSSE3__

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM