2011-04-27 10 views
36

dispiace che ci sono molte domande simili, ma io trovano che usare Google per le query CMake produce sempre scenari simili-ma-non-lo-stesso, contrastanti comandi CMake e così sopra!Il modo corretto di costringere a 32 bit compilare usando CMake

ho bisogno di forzare il mio progetto per costruire i binari a 32 bit perché devo collegare con una libreria che è disponibile solo a 32-bit. Ho diagnosticato questo sulla base di messaggi di errore come:

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

Da quanto ho capito, mi dovrebbe quindi utilizzare:

set (CMAKE_CXX_FLAGS "-m32") 

Questo non cambia le cose - io ora ottenere diversi errori come:

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

e ancora ottenere gli stessi errori per la libreria esterna troppo. Io penso questo è perché il -m32 Made gcc generare file binari a 32 bit, ma ld sta ancora cercando per l'uscita a 64 bit? Ulteriore Googling per questo problema non ha dato alcun successo, quindi se qualcuno potesse verificare che ho ragione e dare il modo corretto di farlo, sarei molto grato!

Grazie mille!

risposta

4

suona come non avete superato m32 a LFLAGS troppo, o non ci sono i vecchi file obj skulking circa. Assicurati di pulire prima.

Questa domanda è simile al tuo: cmake, gcc, cuda and -m32

+0

Grazie -che potrebbe essere il caso - Ma come Lo faccio anche se CMake? Ed è questo il modo più sensato o 'corretto' per farlo? Ho fatto pulire btw :) – jazzbassrob

+0

risposta aggiornata. Vedi il link. Intendevo pulire le mani, sei sporco :) –

+0

Saluti, ma sfortunatamente il collegamento non sembra aiutare. Impostazione LDFLAGS sembra avere alcun effetto ... – jazzbassrob

5

CMAKE_CXX_FLAGS colpisce solo il compilatore C++. Probabilmente avete anche impostare il flag per il compilatore C:

set (CMAKE_C_FLAGS "-m32") 
3

Utilizzare il comando TRY_RUN dal seguente fonte.

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) 

Si lavorerà su tutti compilatore standard.

33

Se vuoi compilare e collegamento per 32 bit che utilizza l'uso cmake questo per la creazione di librerie ei binari:

creazione di librerie:

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

creando eseguibili:

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

Spero che questo aiuta,

13

Anche se questo sembra come le opere in più, credo che una corretta soluti su è usare il file toolchain in questo caso.Qualcosa di simile:

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

Poi utilizzo è semplice:

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

La parte importante qui è che uno è ora in grado di specificare un percorso di root dir (CMAKE_FIND_ROOT_PATH) che dovrebbe essere utilizzato per la ricerca di terze parti lib. In effetti il ​​tuo compilatore potrebbe non essere abbastanza intelligente da sapere dove cercare una libreria Qt x86 su un sistema x86_64.

Avere un file toolchain permette di specificare uno diverso su base compilatore par, e si dovrebbe essere in grado di modificare l'opzione durante la compilazione in 32bit da un environement finestre.

Al giorno d'oggi questo è un lavoro extra dal momento che la compilazione di 32 bit da un sistema operativo Linux x86_64 è piuttosto banale, ma questa soluzione funzionerà per altre impostazioni più esotiche.

Per ulteriori informazioni sul file di toolchain, si può verificare ad esempio:

+3

Un file toolchain può essere un po 'troppo quando 'CMake/path/to/fonte -DCMAKE_CXX_FLAGS = -m32 -DCMAKE_C_FLAGS = -m32' potrebbe fare, ma questi due sono gli unici modi adeguati di gestire questa situazione. CMakeLists.txt non dovrebbe contenere questo tipo di "informazioni". A meno che l'OP non impedisca il completamento di una compilazione a 64 bit. – rubenvb

+0

@rubenvb come spiegato nel mio post, è ancora necessario 'CMAKE_FIND_ROOT_PATH' per aiutare manico CMake qualcosa del tipo' find_package (Qt) ' – malat

+0

utilizzando questa tecnica e CMake 3.9.3, CMAKE_CXX_FLAGS definito in toolchain non è stato propagato nel bambino proietta la prima volta Sto creando la directory di build. Ma il comportamento cambia se si esegue una seconda volta il comando per creare la directory di costruzione senza cancellare la directory di compilazione esistente !!! Io non so esattamente se questa è una caratteristica normale o no ... per risolvere il problema, ho definito come CMAKE_CXX_FLAGS seguire nel file di toolchain: 'set (CMAKE_CXX_FLAGS "$ {} CMAKE_CXX_FLAGS -m32" CACHE STRING "C++ bandiere") ' – sancelot

Problemi correlati