【问题标题】:Detect 32-bit x86 processor in CMakeList.txt?在 CMakeList.txt 中检测 32 位 x86 处理器?
【发布时间】:2016-09-14 03:42:16
【问题描述】:

由于缺少-fPIC,我们正在捕获errors in our CMake makefiles。她来自 ci20 MIPS 开发板:

...
[ 92%] Built target cryptopp-object
Scanning dependencies of target cryptopp-shared
Scanning dependencies of target cryptopp-static
Linking CXX static library libcryptopp.a
Linking CXX shared library libcryptopp.so
/usr/bin/ld: CMakeFiles/cryptopp-object.dir/cryptlib.cpp.o: relocation R_MIPS_HI16 against
`a local symbol' can not be used when making a shared object; recompile with -fPIC
CMakeFiles/cryptopp-object.dir/cryptlib.cpp.o: could not read symbols: Bad value
collect2: ld returned 1 exit status

由于注册压力,该项目的政策是除了 32 位 x86 之外的所有地方都向我们提供 PIC。这意味着 x86_64、ARM-32、Aarch32、Aarch64、MIPS、MIPS64、UltraSparc 等获得 PIC。

我相信CMAKE_SYSTEM_PROCESSOR 中提供了目标处理器。我遇到的问题是文档没有告诉我值,所以我无法弄清楚如何制作“非 32 位 x86”测试。

如何在 CMakeList.txt 中检测 32 位 x86 处理器?

更好的是,我希望看到 CMake 将 CMAKE_SYSTEM_PROCESSOR 设置为的处理器的完整列表。如果有人有这个列表,那么提供它会很棒。

【问题讨论】:

    标签: cmake processor fpic


    【解决方案1】:

    我可能会围绕编译器构建一些东西。

    使用现有变量/模块的近似值是:

    include(TestBigEndian)
    
    if (NOT WIN32)
        TEST_BIG_ENDIAN(_bigendian)
        if((CMAKE_SIZEOF_VOID_P GREATER 4) OR (_bigendian))
            message(
                STATUS "Setting ${CMAKE_CXX_COMPILE_OPTIONS_PIC} "
                       "for machine ${CMAKE_HOST_SYSTEM_PROCESSOR}"
            )
            set(CMAKE_POSITION_INDEPENDENT_CODE 1)
        endif()
    endif()
    

    简而言之,我做了什么:

    • WIN32 也适用于 64 位 Windows 编译器/环境
    • CMAKE_SIZEOF_VOID_P GREATER 4 检查“大于 32 位”
    • 最后一个是最大的假设:将所有小端处理器作为基于 Intel/AMD 的处理器
    • 使用更通用的CMAKE_POSITION_INDEPENDENT_CODE 来设置-fPIC

    我承认更准确的方法是围绕预定义的宏测试构建一些东西。

    编辑:添加“预定义宏检查”替代项

    这是对预定义宏的更精确检查:

    include(CheckCXXSourceCompiles)
    
    if (CMAKE_CXX_COMPILE_OPTIONS_PIC)
        set(
            _preDefMacrosX86 
                __i386 __i386__ __i486__ __i586__ __i686__      
                _M_I86 _M_IX86 __X86__ _X86_ __THW_INTEL__
                __I86__ __INTEL__ __386
        )
        set(_code "void main() {}")
        foreach(_macro IN LISTS _preDefMacrosX86)
            set(
                _code
                "${_code}\n\#ifdef ${_macro}\n\#error ${_macro} is defined\n\#endif"
            )
        endforeach()
        CHECK_CXX_SOURCE_COMPILES("${_code}" _canCompileX86DoesFailCheck)
    
        if((CMAKE_SIZEOF_VOID_P GREATER 4) OR (_canCompileX86DoesFailCheck))
            message(STATUS "Setting ${CMAKE_CXX_COMPILE_OPTIONS_PIC}")
            set(CMAKE_POSITION_INDEPENDENT_CODE 1)
        endif()
    endif()
    

    参考文献

    【讨论】:

    • 再次感谢弗洛里安。我不知道CMAKE_POSITION_INDEPENDENT_CODE 。我会添加的。
    • " ...将所有小端处理器都作为基于 Intel 的处理器" - 这可能需要放宽一点。我使用的所有 ARM 处理器都是 LE。角落案例可能是旧 Apple G5 中的 PowerPC。它的 BE,它需要 -fPIC (IIRC)。我的地下室有一个 G5 用于测试库的 BE 版本。当Verizon fixes port forwarding in their routers 时,如果您愿意,我可以为您提供远程 SSH 访问。 PF 以前可以工作,但 VZ 在 4XX 系列固件 ror 更新中破坏了它。你可以随心所欲地测试 CMake :)
    • @jww 是的,我应该知道得更好。对此感到抱歉。我添加了更精确的“检查预定义的 x86 宏”版本。应该这样做。
    【解决方案2】:

    我相信这会对除了 Windows 之外的几乎所有东西进行检测。 Windows 不消耗-fPIC,所以对我来说没关系。这些碎片是从三个 Stack Overflow 答案粘在一起的。

    # Stop hiding the damn output...
    set(CMAKE_VERBOSE_MAKEFILE on)
    
    # Enable PIC for all targets except Windows and 32-bit x86
    if (NOT (WINDOWS OR WINDOWS_STORE OR WINDOWS_PHONE))
    
        set (UNAME_CMD "uname")
        set (UNAME_ARG "-m")
        execute_process(COMMAND ${UNAME_CMD} ${UNAME_ARG}
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
            RESULT_VARIABLE UNAME_RESULT
            OUTPUT_VARIABLE UNAME_MACHINE)
    
        # Use Regex; match i386, i486, i586 and i686
        IF (NOT (${UNAME_MACHINE} MATCHES "i.86"))
            # message(STATUS "Setting -fPIC for machine ${UNAME_MACHINE}")
            if (CMAKE_VERSION VERSION_LESS 2.8.12)
                add_definitions(-fPIC)
            else()
                add_compile_options(-fPIC)
            endif()
        endif()
    endif()
    

    你得到带有uname -m 的机器,并且它大部分准确,即使在 OS X 上也是如此。例如,在 OS X 上,uname -p 返回i386uname -m 返回x86_64。我似乎记得 10.6 或 10.7 在过渡到 64 位 Mac 时有点不稳定。

    您有时会获得带有uname -p 的处理器,但它在许多开发板上都失败了。例如我的ci20 dev-board 为机器返回“mips”,为处理器返回“unknown”。另一个例子是我的LeMaker HiKey。它为机器返回“aarch64”,为处理器返回“未知”。


    我还是想看看 Cmake 提供的处理器列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-16
      • 2015-12-03
      • 2012-08-26
      • 1970-01-01
      • 2010-09-19
      • 2023-03-22
      • 1970-01-01
      • 2011-04-19
      相关资源
      最近更新 更多