Подтвердить что ты не робот

Правильный способ форсирования 32-разрядной компиляции с использованием CMake

Извините, что есть много похожих вопросов, но я обнаружил, что запросы Googling для 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-битный вывод? Дальнейший Googling для этой проблемы не давал никакого успеха, поэтому, если бы кто-нибудь мог проверить, что я прав, и дать правильный способ сделать это, я был бы очень благодарен!

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

4b9b3361

Ответ 1

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

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

Ответ 2

Даже если это похоже на дополнительные работы, я считаю, что правильным решением является использование файла 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

Важная часть здесь состоит в том, что теперь можно указать корневой путь dir (CMAKE_FIND_ROOT_PATH), который должен использоваться для поиска сторонней библиотеки lib. Действительно, ваш компилятор может быть недостаточно умным, чтобы знать, где искать библиотеку x86 Qt в системе x86_64.

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

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

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

Ответ 3

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

set (CMAKE_C_FLAGS "-m32")

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

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

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