Правильный способ принудительной 32-битной компиляции с использованием CMake - PullRequest
46 голосов
/ 27 апреля 2011

Извините, что есть много похожих вопросов, но я нахожу, что поиск в Google для запросов CMake всегда приводит к похожим, но не одинаковым сценариям, конфликтующим командам CMake и так далее!

Мне нужно заставить мой проект создавать 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

И по-прежнему получают те же ошибки для внешней библиотеки. Я думаю это потому, что -m32 заставил gcc генерировать 32-битные двоичные файлы, но ld все еще пытается получить 64-битный вывод? Дальнейшее поиск по этой проблеме не принесло успеха, поэтому, если бы кто-нибудь смог убедиться, что я прав, и дать правильный способ сделать это, я был бы очень признателен!

Большое спасибо!

Ответы [ 6 ]

39 голосов
/ 11 октября 2013

Если вы хотите скомпилировать и связать 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")

Надеюсь, это поможет,

16 голосов
/ 20 января 2015

Даже если это кажется дополнительной работой, я считаю, что правильным решением является использование файла toolchain в этом случае.Что-то вроде:

# 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), который должен бытьиспользуется для поиска сторонних lib.Действительно, ваш компилятор может быть недостаточно умен, чтобы знать, где искать библиотеку x86 Qt в системе x86_64.

Наличие файла цепочки инструментов позволяет указать другой на уровне компилятора, и вам следуетвозможность настроить опцию при компиляции в 32 битах из среды Windows.

В настоящее время это дополнительная работа, поскольку компиляция 32 бит из ОС Linux x86_64 довольно тривиальна, но это решение подойдет для других более экзотических установок.

Для получения дополнительной информации о файле набора инструментов можно проверить, например:

7 голосов
/ 27 апреля 2011

CMAKE_CXX_FLAGS влияет только на компилятор C ++. Вы, вероятно, также должны установить флаг для компилятора C:

set (CMAKE_C_FLAGS "-m32")
4 голосов
/ 27 апреля 2011

Звучит так, как будто вы не передали m32 в LFLAGS, или там скрываются старые файлы obj. Обязательно сначала почистите.

Этот вопрос похож на ваш: cmake, gcc, cuda и -m32

3 голосов
/ 27 апреля 2011

Используйте команду 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)

Это будет работать на всех стандартных компиляторах.

1 голос
/ 24 марта 2017

Я использовал подход Малата и создал файл Toolchain.

У меня есть файл Toolchain, который работает на некоторых дисках Linux, возможно, он вдохновит вас.Он может работать для вас как есть, или вам могут потребоваться другие уродливые хаки, чтобы заставить работать другие скрипты cmake, на которые вы полагаетесь, или ж / д:

https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/cmake/Toolchain-cross-m32.cmake

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...