Правильный способ форсирования 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 для этой проблемы не давал никакого успеха, поэтому, если бы кто-нибудь мог проверить, что я прав, и дать правильный способ сделать это, я был бы очень благодарен!
Большое спасибо!
Ответы
Ответ 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