2011-04-27 1768 views
36

對不起,有許多類似的問題,但我確實發現Google搜索的CMake查詢總是會產生類似但不是相同的場景,與CMake命令衝突等等上!強制使用CMake進行32位編譯的正確方法

我需要強制我的項目構建32位二進制文​​件,因爲我必須鏈接一個只能用於32位的庫。我診斷此基礎上的錯誤信息,如:

/usr/bin/ld: i386 architecture of input file `*external-32bit-lib*' is incompatible with i386:x86-64 output 

從我所收集的,我因此應使用:

set (CMAKE_CXX_FLAGS "-m32") 

這並不改變的事情 - 我現在得到幾個這樣的錯誤:

/usr/bin/ld: i386 architecture of input file `*project-output-lib*' is incompatible with i386:x86-64 output 

AND仍然會爲外部庫獲得相同的錯誤。我認爲這是因爲-m32使gcc生成32位二進制文​​件,但ld仍然在嘗試64位輸出?進一步谷歌搜索這個問題沒有取得任何成功,所以如果任何人都可以驗證我是正確的,並給出正確的方式做到這一點,我將非常感激!

非常感謝!

回答

4

這聽起來像你沒有將m32傳遞給LFLAGS,或者有舊的obj文件偷偷摸摸。一定要先清理。

這個問題是與你相似:cmake, gcc, cuda and -m32

+0

感謝 - 即很可能的情況下 - 但如何將我這樣做,但CMake?這是做這件事最明智還是「正確」的方式?我做了乾淨順便:) – jazzbassrob 2011-04-27 14:45:20

+0

已更新的答案。請參閱鏈接。我的意思是打掃你的手,你很髒:) – 2011-04-27 14:51:33

+0

乾杯,但不幸的是,這個鏈接似乎沒有幫助。設置LDFLAGS似乎沒有效果... – jazzbassrob 2011-04-27 15:05:56

5

CMAKE_CXX_FLAGS隻影響C++編譯器。您可能還必須設置C編譯器的標誌:

set (CMAKE_C_FLAGS "-m32") 
3

使用TRY_RUN命令由以下來源。

size.cpp:

#include <cstdlib> 

int main(int argc, char** argv) 
{ 
    size_t size = sizeof(void*); 
    if (size == 4) 
    return 0; 
    return 1; 
} 

的CMakeLists.txt:

TRY_RUN(RUN_RESULT_VAR COMPILE_RESULT_VAR ${your_temp_dir} size.cpp RUN_OUTPUT_VARIABLE IS_64_SYSTEM) 
IF(IS_64_SYSTEM) 
    MESSAGE(FATAL_ERROR "64 compiling not allowed!") 
ENDIF(IS_64_SYSTEM) 

它會在所有標準的編譯器工作。

33

如果你想編譯和鏈接的32位使用cmake使用這種用於創建庫和二進制文件:

創建庫:

add_library(mylib SHARED my_source.c) 
set_target_properties(mylib PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 

創建可執行文件:

add_executable(mybin sources.c) 
set_target_properties(mybin PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 

希望這幫助,

13

即使這看起來像額外的作品,我相信一個合適的解決方案on就是在這種情況下使用工具鏈文件。喜歡的東西:

# the name of the target operating system 
set(CMAKE_SYSTEM_NAME Linux) 

# which compilers to use for C and C++ 
set(CMAKE_C_COMPILER gcc) 
set(CMAKE_C_FLAGS -m32) 
set(CMAKE_CXX_COMPILER g++) 
set(CMAKE_CXX_FLAGS -m32) 

# here is the target environment located 
set(CMAKE_FIND_ROOT_PATH /usr/i486-linux-gnu) 

# adjust the default behaviour of the FIND_XXX() commands: 
# search headers and libraries in the target environment, search 
# programs in the host environment 
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 

然後用法很簡單:

$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake /path/to/source 

最重要的這裏的部分是一個現在可以指定哪些應該被用來尋找第三方根目錄路徑(CMAKE_FIND_ROOT_PATH)庫。事實上,您的編譯器可能不夠聰明,無法知道在x86_64系統上如何搜索x86 Qt庫。

有一個工具鏈文件允許你在一個par編譯器的基礎上指定一個不同的文件,你應該能夠從windows環境編譯32位時調整選項。

現在,這是一個額外的工作,因爲從x86_64 Linux操作系統編譯32位數據是非常微不足道的,但這種解決方案將適用於其他更奇特的設置。

有關工具鏈文件的詳細信息,可以檢查,例如:

+3

當'cmake/path/to/source -DCMAKE_CXX_FLAGS = -m32 -DCMAKE_C_FLAGS = -m32'可能會發生時,工具鏈文件可能有點多,但這兩個是唯一正確的方法處理這種情況。 CMakeLists.txt不應該包含這種「信息」。除非OP要防止發生64位編譯。 – rubenvb 2015-01-20 13:57:42

+0

@rubenvb在我的文章中解釋過,你仍然需要'CMAKE_FIND_ROOT_PATH'來幫助cmake處理類似'find_package(Qt)' – malat 2015-01-20 13:59:48

+0

使用這種技術和cmake 3.9.3,工具鏈中定義的CMAKE_CXX_FLAGS不是在第一次在子項目中傳播我正在創建構建目錄。但是,如果您再次運行創建構建目錄的命令而不刪除現有的構建目錄,則行爲會發生變化!爲了解決這個問題,我在工具鏈文件中定義瞭如下的CMAKE_CXX_FLAGS:'set(CMAKE_CXX_FLAGS「$ {CMAKE_CXX_FLAGS} -m32」CACHE STRING「C++ flags」) ' – sancelot 2017-11-06 11:09:12