LINUX.ORG.RU

cmake build for ARM

 , ,


1

1

В большинстве случаев для кросс-сборки программ с ./configure && make мне достаточно указать --host=arm-linux-gnueabi, как быть под cmake, неужто переназначать все переменные в ccmake? собираю qt-gstreamer под ARM.

★★★★★

Последнее исправление: splinter (всего исправлений: 1)

arm-toolchain.cmake:

set(CMAKE_SYSTEM_MAKE Linux)

set(CMAKE_C_COMPILER /opt/toolchains/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER/opt/toolchains/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-g++)
set(CMAKE_AR /opt/toolchains/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-ar)
...

set(CMAKE_FIND_ROOT_PATH /opt/toolchains/arm-qemu-linux-gnueabi)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
cmake -DCMAKE_TOOLCHAIN_FILE=arm-toolchain.cmake
EXL ★★★★★
()
Ответ на: комментарий от EXL

Could NOT find Qt4 (missing: QT_QMAKE_EXECUTABLE QT_MOC_EXECUTABLE QT_RCC_EXECUTABLE QT_UIC_EXECUTABLE QT_INCLUDE_DIR QT_LIBRARY_DIR QT_QTCORE_LIBRARY)

мне надо в зависмостях указать QT4, мне для этого надо все эти переменные заполнить?

splinter ★★★★★
() автор топика
Ответ на: комментарий от EXL

В общем как то не удобно кросс-компилировать если проект под cmake, без pkgconfig собираться не хочет, а мне он на встраиваемом устройстве нафиг не нужен.

splinter ★★★★★
() автор топика
Ответ на: комментарий от splinter

Переменные эти заполнять вовсе не нужно. Я сталкивался с похожей проблемой при построении приложений на основе Qt4.
Смотри: у меня есть read-only arm-toolchain, собранный и установленный с помощью crosstool-NG, помимо него есть arm-sdk с прикладными библиотеками и заголовочными файлами, который я собирал сам. Этот arm-sdk располагается отдельно от toolchain'а.

Я сейчас попробовал собрать достаточно сложное приложение для чтения электронных книжек - Cool Reader, на основе библиотеки Qt 4.8.5, которая присутствует у меня в arm-sdk. Сборочной системой в Cool Reader является как раз CMake, поэтому кросс-компиляция этого приложения будет похожа на кросс-компиляцию твоей программы.

В каталоге «~/x-tools/arm-qemu-linux-gnueabi/» у меня располагается read-only arm-toolchain, в который нельзя добавлять библиотеки (согласно политике, используемой в crosstool-NG).
В каталоге «~/SandBox/QEMU_arm/arm-sdk/» находится arm-sdk, в который собираются и добавляются необходимые библиотеки. Сошки оттуда переносятся потом на устройство.
В общем, структура arm-sdk такова:

exl@exl-Lenovo-G560e:~/SandBox/QEMU_arm/arm-sdk/lib > ls *.so*
libexpat.so             libQt3Support.so.4.8.5     libQtNetwork.so.4.8        libQtTest.so.4
libexpat.so.1           libQtCore.so               libQtNetwork.so.4.8.5      libQtTest.so.4.8
libexpat.so.1.6.0       libQtCore.so.4             libQtScript.so             libQtTest.so.4.8.5
libfontconfig.so        libQtCore.so.4.8           libQtScript.so.4           libQtWebKit.so
libfontconfig.so.1      libQtCore.so.4.8.5         libQtScript.so.4.8         libQtWebKit.so.4
libfontconfig.so.1.8.0  libQtDeclarative.so        libQtScript.so.4.8.5       libQtWebKit.so.4.9
libfreetype.so          libQtDeclarative.so.4      libQtScriptTools.so        libQtWebKit.so.4.9.4
libfreetype.so.6        libQtDeclarative.so.4.8    libQtScriptTools.so.4      libQtXml.so
libfreetype.so.6.11.1   libQtDeclarative.so.4.8.5  libQtScriptTools.so.4.8    libQtXml.so.4
libjpeg.so              libQtGui.so                libQtScriptTools.so.4.8.5  libQtXml.so.4.8
libjpeg.so.9            libQtGui.so.4              libQtSql.so                libQtXml.so.4.8.5
libjpeg.so.9.1.0        libQtGui.so.4.8            libQtSql.so.4              libSDL-1.2.so.0
libpng16.so             libQtGui.so.4.8.5          libQtSql.so.4.8            libSDL-1.2.so.0.11.4
libpng16.so.16          libQtMultimedia.so         libQtSql.so.4.8.5          libSDL.so
libpng16.so.16.9.0      libQtMultimedia.so.4       libQtSvg.so                libz.so
libpng.so               libQtMultimedia.so.4.8     libQtSvg.so.4              libz.so.1
libQt3Support.so        libQtMultimedia.so.4.8.5   libQtSvg.so.4.8            libz.so.1.2.8
libQt3Support.so.4      libQtNetwork.so            libQtSvg.so.4.8.5
libQt3Support.so.4.8    libQtNetwork.so.4          libQtTest.so
exl@exl-Lenovo-G560e:~/SandBox/QEMU_arm/arm-sdk/include > ls
bzlib.h           jmorecfg.h    Qt             QtScript       SDL
expat_external.h  jpeglib.h     Qt3Support     QtScriptTools  zconf.h
expat.h           libpng16      QtCore         QtSql          zlib.h
fontconfig        ncurses       QtDeclarative  QtSvg
freetype2         pngconf.h     QtGui          QtTest
jconfig.h         png.h         QtMultimedia   QtWebKit
jerror.h          pnglibconf.h  QtNetwork      QtXml

В директории "../bin" находятся бинарники под архитектуру хоста (x86_64):

exl@exl-Lenovo-G560e:~/SandBox/QEMU_arm/arm-sdk/bin > ls
freetype-config  libpng16-config  lrelease  moc              pkg-config  rcc         uic
gzip             libpng-config    lupdate   ncurses5-config  qmake       sdl-config

Для кросс-компиляции приложения, использующего Qt, я использую следующий cmake-модуль:

exl@exl-Lenovo-G560e:~/SandBox/QEMU_arm > cat arm_toolchain.cmake 
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)

# specify the cross compiler
SET(CMAKE_C_COMPILER   /home/exl/x-tools/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /home/exl/x-tools/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-g++)

# where is the target environment
SET(CMAKE_FIND_ROOT_PATH  /home/exl/SandBox/QEMU_arm/arm-sdk/)

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Следующим образом я кросс-компилирую Cool Reader и отправляю его на устройство:

exl@exl-Lenovo-G560e:~/SandBox/CoolReader > cd ~/SandBox/CoolReader
exl@exl-Lenovo-G560e:~/SandBox/CoolReader > ll -a
total 12
drwxr-xr-x 3 exl exl 4096 февр. 15 22:28 ./
drwxr-xr-x 7 exl exl 4096 февр. 15 22:28 ../
drwxr-xr-x 2 exl exl 4096 февр. 15 22:28 build/
exl@exl-Lenovo-G560e:~/SandBox/CoolReader > git clone git://crengine.git.sourceforge.net/gitroot/crengine/crengine
exl@exl-Lenovo-G560e:~/SandBox/CoolReader > cd crengine
exl@exl-Lenovo-G560e:~/SandBox/CoolReader/crengine > git checkout cr3.0.57-18
exl@exl-Lenovo-G560e:~/SandBox/CoolReader/crengine > patch -Np1 < ~/SandBox/QEMU_arm/Cross-compile.patch
patching file cr3qt/CMakeLists.txt
exl@exl-Lenovo-G560e:~/SandBox/CoolReader/crengine > cd ../build/
exl@exl-Lenovo-G560e:~/SandBox/CoolReader/build > cmake -DCMAKE_TOOLCHAIN_FILE=../../QEMU_arm/arm_toolchain.cmake 
                                                        -DFONTCONFIG_LIB=/home/exl/SandBox/QEMU_arm/arm-sdk/lib/libfontconfig.so 
                                                        --build ../crengine/
exl@exl-Lenovo-G560e:~/SandBox/CoolReader/build > make
exl@exl-Lenovo-G560e:~/SandBox/CoolReader/build > make DESTDIR=/home/exl/SandBox/QEMU_arm/rootfs install

Патч «Cross-compile.patch» добавляет костыль исправляет ошибку, связанную с библиотекой libfontconfig (необходима для работы Cool Reader). Сам патч, весьма простой:

exl@exl-Lenovo-G560e:~/SandBox/CoolReader/build > cat  ~/SandBox/QEMU_arm/Cross-compile.patch 
diff --git a/cr3qt/CMakeLists.txt b/cr3qt/CMakeLists.txt
index 80395df..4fd6ef2 100644
--- a/cr3qt/CMakeLists.txt
+++ b/cr3qt/CMakeLists.txt
@@ -148,8 +148,6 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio.*")
 endif(CMAKE_GENERATOR MATCHES "Visual Studio.*")
 endif(WIN32)
 
-
-
 IF(MAC)
     message("Qt libs = ${QT_LIBRARIES}")
 #    SET(FRAMEWORKS "-framework ApplicationServices -framework Carbon -framework AppKit")
@@ -157,7 +155,17 @@ IF(MAC)
     SET (EXTRA_LIBS ${QT_LIBRARIES} ${STD_LIBS} )
 #${QT_LIBRARIES} 
 ELSEIF (UNIX)
-    SET (EXTRA_LIBS ${QT_LIBRARIES} fontconfig ${STD_LIBS} )
+    IF(DEFINED CMAKE_TOOLCHAIN_FILE)
+      message("Warning: Cross-compilation detected!")
+      IF(NOT DEFINED FONTCONFIG_LIB)
+       message("Error: Please define FONTCONFIG_LIB variable, eg: -DFONTCONFIG_LIB=/usr/lib/libfontconfig.so!")
+      ENDIF(NOT DEFINED FONTCONFIG_LIB)
+      message("Warning: Fontconfig library here: " ${FONTCONFIG_LIB})
+      SET (EXTRA_LIBS ${QT_LIBRARIES} ${FONTCONFIG_LIB} ${STD_LIBS} )
+    ELSE()
+      message("Warning: libfontconfig will be linked!")
+      SET (EXTRA_LIBS ${QT_LIBRARIES} fontconfig ${STD_LIBS} )
+    ENDIF(DEFINED CMAKE_TOOLCHAIN_FILE)
 ELSE()
     SET (EXTRA_LIBS ${STD_LIBS} ${QT_LIBRARIES})
 ENDIF(MAC)

Итог получился таким: [скриншот]

Как видишь, с помощью CMake можно кросс-компилировать приложение использующее Qt4. И вовсе не требуется прописывать переменные для каждой библиотеки. Qt и все его библиотеки подхватятся автоматом благодаря cmake-модулю «arm_toolchain.cmake», точнее переменной CMAKE_FIND_ROOT_PATH в нём. А вот для Fontconfig (используется в приложении) пришлось писать костыль-патчик, ибо модуля FindFontconfig.cmake у меня не было. Надеюсь ты избежишь этой участи.

Лог CMake: [pastebin.com]

Лог сборки с make VERBOSE=1: [pastebin.com]

EXL ★★★★★
()
Ответ на: комментарий от splinter

Согласен с тобой, CMake - не самая приятная система сборки для кросс-компиляции. Мне, например, больше нравится QMake.

Насчёт pkg-config, действительно он вовсе не нужен на Embedded-устройстве. Для кросс-компиляции нужен именно хостовый pkg-config под x86/x86_64. Взгляни на лог моей кросс-компиляции:

Found PkgConfig: /usr/bin/pkg-config (found version "0.26")

EXL ★★★★★
()
Ответ на: комментарий от splinter

И еще. Если переменная CMAKE_FIND_ROOT_PATH_MODE_PROGRAM в «arm_toolchain.cmake» установлена в NEVER, то будут использоваться инструменты из недр «/usr/...». Это видно по логу:

-- Found Qt4: /usr/lib/x86_64-linux-gnu/qt4/bin/qmake (found version "4.8.4")

Если она установлена в ONLY, то будут использованы инструменты из CMAKE_FIND_ROOT_PATH/bin, то есть из твоего SDK:

-- Found Qt4: /home/exl/SandBox/QEMU_arm/arm-sdk/bin/qmake (found version "4.8.5")

Лог в случае с ONLY: [pastebin]

Но тут нужно быть осторожным, так как почему-то пропадают некоторые кросс-утилиты из binutils, например tuple-ar и tuple-ranlib. Я решил эту проблему, которая кстати упоминалась на ЛОРе, так:

ln -s ~/x-tools/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-ar ~/SandBox/QEMU_arm/arm-sdk/bin/arm-qemu-linux-gnueabi-ar
ln -s ~/x-tools/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-ranlib ~/SandBox/QEMU_arm/arm-sdk/bin/arm-qemu-linux-gnueabi-ranlib
ln -s ~/x-tools/arm-qemu-linux-gnueabi/bin/arm-qemu-linux-gnueabi-strip ~/SandBox/QEMU_arm/arm-sdk/bin/arm-qemu-linux-gnueabi-strip

То есть нужно зазеркалить в SDK все используемые инструменты, которые нужны для построения программы (кроме компиляторов). Если столкнешься с проблемой, когда CMake пишет Error running link command: No such file or directory, а по make VERBOSE=1 ar определяется как CMAKE_AR-NOTFOUND cr или вообще "" cr - будешь знать как решить эту фигню.

Кстати, вот полезная страничка в wiki - [CMake Cross Compiling], там неплохо все описано.

P.S. А что за приложение пытаешься кросс-компилировать? Если у него открытый код, говори название - попробую собрать под свой эмулятор.

EXL ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.