在 CMakeList.txt 中检测到 32 位 x86 处理器?
Detect 32-bit x86 processor in CMakeList.txt?
由于缺少 -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
中提供了目标处理器。我遇到的问题是文档没有告诉我这些值,所以我不知道如何制作 "not 32-bit x86" 测试。
如何在 CMakeList.txt 中检测 32 位 x86 处理器?
更好的是,我希望看到 CMake 设置 CMAKE_SYSTEM_PROCESSOR
的处理器的完整列表。谁有名单的话,提供一下就好了。
我相信这对除 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
returns i386
而 uname -m
returns x86_64
。我似乎记得 10.6 或 10.7 在过渡到 64 位 Mac 时有点不稳定。
有时你会得到带 uname -p
的处理器,但它在许多开发板上都失败了。例如我的ci20 dev-board returns "mips" for the machine and "unknown" for the processor. Another example is my LeMaker HiKey。它 returns "aarch64" 用于机器,"unknown" 用于处理器。
我还是想看看Cmake提供的处理器列表。
我可能会围绕编译器构建一些东西。
使用现有 variables/modules 的近似值是:
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位也有效Windowscompilers/environments
CMAKE_SIZEOF_VOID_P GREATER 4
检查 "greater then 32 Bit"
- 最后一个是最大的假设:将所有小端处理器作为Intel/AMD基础
- 使用更通用的
CMAKE_POSITION_INDEPENDENT_CODE
来设置 -fPIC
我承认更准确的方法是围绕预定义的宏测试构建一些东西。
编辑:添加了 "Predefined Macros Check" 备选方案
这里是对预定义宏的更精确的检查:
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()
参考资料
- Detecting CPU architecture compile-time
由于缺少 -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
中提供了目标处理器。我遇到的问题是文档没有告诉我这些值,所以我不知道如何制作 "not 32-bit x86" 测试。
如何在 CMakeList.txt 中检测 32 位 x86 处理器?
更好的是,我希望看到 CMake 设置 CMAKE_SYSTEM_PROCESSOR
的处理器的完整列表。谁有名单的话,提供一下就好了。
我相信这对除 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
returns i386
而 uname -m
returns x86_64
。我似乎记得 10.6 或 10.7 在过渡到 64 位 Mac 时有点不稳定。
有时你会得到带 uname -p
的处理器,但它在许多开发板上都失败了。例如我的ci20 dev-board returns "mips" for the machine and "unknown" for the processor. Another example is my LeMaker HiKey。它 returns "aarch64" 用于机器,"unknown" 用于处理器。
我还是想看看Cmake提供的处理器列表。
我可能会围绕编译器构建一些东西。
使用现有 variables/modules 的近似值是:
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位也有效Windowscompilers/environmentsCMAKE_SIZEOF_VOID_P GREATER 4
检查 "greater then 32 Bit"- 最后一个是最大的假设:将所有小端处理器作为Intel/AMD基础
- 使用更通用的
CMAKE_POSITION_INDEPENDENT_CODE
来设置-fPIC
我承认更准确的方法是围绕预定义的宏测试构建一些东西。
编辑:添加了 "Predefined Macros Check" 备选方案
这里是对预定义宏的更精确的检查:
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()
参考资料
- Detecting CPU architecture compile-time