【问题标题】:How to have CHECK_CXX_COMPILER_FLAG fail on illegal value?如何让 CHECK_CXX_COMPILER_FLAG 因非法值而失败?
【发布时间】:2017-08-26 14:14:09
【问题描述】:

我们的CMakeFile.txt 包含以下 SunCC 代码路径。 SunCC 使用-xarch=XXX 而不是GCC 样式-mXXX

CHECK_CXX_COMPILER_FLAG("-xarch=sha" CRYPTOPP_IA32_SHA)

当我们在 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
...

然而,当我们编译它的时候:

$ 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

添加 SunCC 的 -errwarn-errwarn=%all 并不能帮助 CMake 检测到故障。

该消息可能会给用户带来很多问题。它也违反了我们对干净编译的治理。我们想清理它并避免任何麻烦。

我们如何告诉 CMake 对非法值进行 CHECK_CXX_COMPILER_FLAG 测试失败?

【问题讨论】:

    标签: cmake solaris compiler-options suncc


    【解决方案1】:

    我猜,当检查编译器标志时,CMake 只是验证编译命令的 result。由于“警告”消息不会影响结果,CMake 无法检测到该标志实际上被忽略了。

    您可以使用try_compile 命令手动测试该标志,以便检查某些模式的输出(例如“警告”)。

    还有CHECK_CXX_SOURCE_COMPILES 宏,它已经接受匹配模式。

    另请参阅that question 和我的回答。

    【讨论】:

    • 谢谢。看起来try_compile 仅适用于 3.0。 2.8还有其他技巧吗? 2.8 是我们更喜欢使用 CMake 的地方。 (我们实际上更喜欢更远一些,但我们在 2.8 时妥协了)。
    • try_compile exists 即使是 2.8。
    • 啊,废话。 CHECK_CXX_COMPILER_FLAG 也是一个 Cmake 3.0 函数。我们将拉动它以支持可行的方法。
    【解决方案2】:

    我们所能做的最好的事情是添加一个自定义CheckCompilerOption。但是,它还有其他问题,因为在执行 CMakeLists.txt 时 CMake 不提供准确的CXXFLAGS。在交叉编译过程中问题浮出水面。另见CMake Issue 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}}" 看起来很奇怪,但根据一些现有代码,我相信它是正确的。 取消引用的第一个版本是错误的。 function 的 CMake 文档没有讨论它,也没有提供示例,所以我们又瞎了眼。它在 Stack Overflow 上的 What's the CMake syntax to set and use variables? 中提到。

    可以按预期调用:

    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)
    

    如果您需要比 CMake 3.0 更进一步(例如使用 CMake 2.8 回到 Ubuntu 10 或 CentOS 5),那么放弃 CHECK_CXX_COMPILER_FLAG 并使用 Clang、GCC、ICC 等函数的顶部。

    GCC 的检查语法如下所示。该命令以SSSE3为例。

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

    【讨论】:

    • 什么是 CMake 2.8?那时第三个数字 2.8.x 是相关的!
    • @usr1234567 - CMake 版本 2.8.5。
    猜你喜欢
    • 2016-10-19
    • 1970-01-01
    • 2020-10-27
    • 2012-08-08
    • 1970-01-01
    • 2021-05-10
    • 2011-01-07
    • 1970-01-01
    • 2012-02-29
    相关资源
    最近更新 更多