2016-09-14 56 views
0

由於缺少-fPIC,我們正在追趕errors in our CMake makefiles。她是一個從ci20 MIPS開發板:檢測CMakeList.txt中的32位x86處理器?

... 
[ 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 

該項目的政策是我們到處PIC除了由於註冊的壓力32位x86。這意味着x86_64,ARM-32,Aarch32,Aarch64,MIPS,MIPS64,UltraSparc等獲得PIC。

我相信在CMAKE_SYSTEM_PROCESSOR中提供了目標處理器。我遇到的問題是文檔沒有告訴我這些值,所以我無法弄清楚如何編寫「不是32位的x86」測試。

如何檢測CMakeList.txt中的32位x86處理器?

更好的是,我希望看到CMake設置CMAKE_SYSTEM_PROCESSOR的處理器的完整列表。如果有人有這個清單,那麼提供它就太好了。

回答

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位」
  • 最後是最大的假設:取所有小端處理器英特爾/ 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() 

參考

+0

再次感謝弗洛裏安。我不知道「CMAKE_POSITION_INDEPENDENT_CODE」。我會添加它。 – jww

+0

*「......將所有小端處理器作爲基於英特爾的處理器」* - 可能需要放鬆一點。我使用的所有ARM處理器都是LE。角落案例可能是一個PowerPC,比如老蘋果G5。它的BE,它需要-fPIC(IIRC)。我的地下室裏有一臺G5,用於測試圖書館的版本。當[Verizon修復其路由器中的端口轉發](https://www.google.com/search?q=verizon+prt+forwarding+broke)時,如果需要,我可以爲您提供遠程SSH訪問。 PF曾經工作,但VZ在4XX系列固件更新中破壞了它。你可以測試CMake,你喜歡:) – jww

+0

@jww是的,我應該知道更好。對不起。我添加了更精確的「檢查預定義x86宏」版本。這應該做到這一點。 – Florian

0

我相信這幾乎可以檢測除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」,爲處理器返回「未知」。另一個例子是我的LeMaker HiKey。它返回機器的「aarch64」和處理器的「未知」。


我還想看看Cmake提供的處理器列表。