0

が不足しているため、CMake メイクファイルでエラーを検出しています-fPIC。彼女は 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。誰かがリストを持っているなら、それを提供するのは素晴らしいことです.

4

2 に答える 2

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()

要するに私がやったこと:

  • WIN3264 ビット 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()

参考文献

于 2016-09-14T21:18:07.623 に答える
0

これにより、Windows 以外のほぼすべてで検出が実行されると思います。Windows は を消費しないので-fPIC、私には関係ありません。ピースは、3 つのスタック オーバーフローの回答から接着されました。

# 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 -mOS X でもほぼ正確です。たとえば、OS X では、 return中に return をuname -p返します。10.6 または 10.7 は、64 ビット Mac への移行が行われていたため、少し不安定だったことを思い出すようです。i386uname -mx86_64

プロセッサを取得するuname -pこともありますが、多くの開発ボードでは失敗します。たとえば、私のci20 dev-boardは、マシンの場合は「mips」、プロセッサの場合は「unknown」を返します。もう 1 つの例は、私のLeMaker HiKeyです。マシンの場合は「aarch64」、プロセッサの場合は「unknown」を返します。


Cmake が提供するプロセッサのリストを引き続き確認したいと思います。

于 2016-09-14T05:20:42.837 に答える