Страницы

Поиск по вопросам

Показаны сообщения с ярлыком кросс-компиляция. Показать все сообщения
Показаны сообщения с ярлыком кросс-компиляция. Показать все сообщения

воскресенье, 9 февраля 2020 г.

Как прилинковать нестандартную версию protobuf используя cmake

#cpp #cmake #protobuf #кросс_компиляция #линковка


Есть проект под arm который компилируется и собирается на х86ой машине (кросскомпиляция).
Есть версия библиотеки protobuf собранная под arm по этой 
инструкции. В cmake файле я пытаюсь явно указать местоположение собранной под arm
библиотеки через переменную Protobuf_SRC_ROOT_FOLDER но похоже что cmake эта переменная
вообще побоку. Что мне сделать что бы find_package(Protobuf REQUIRED) нашёл ту версию
protobuf которая мне нужна?

cmake_minimum_required(VERSION 2.8)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -pthread ") #-lboost_system
project(proto_test)

# Подключаем протобуф 
set (Protobuf_SRC_ROOT_FOLDER "/home/mrfieldy/prot_build/protobuf-3.5.1-arm/src")  
#set (Protobuf_USE_STATIC_LIBS ON)   
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS test.proto)
add_executable(${PROJECT_NAME} test.pb.cc ${PROTO_SRCS} ${PROTO_HDRS} "main.cpp")
target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})




Ответ:

В общем, как посоветовали ниже, я выбрал путь сначала выполнить find_package, а потом
с помошью set переопределить пути. Долго искал на какие пути надо переопределить. Вот
рабочий вариант.

cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -pthread ")
project(proto_test)
# Подключаем протобуф 
find_package(Protobuf REQUIRED)
set (PROTOBUF_INCLUDE_DIRS "/home/mrfieldy/prot_build/protobuf-3.6.0-arm/src/")
set (PROTOBUF_LIBRARIES "/home/mrfieldy/prot_build/protobuf-3.6.0-arm/src/.libs/libprotobuf.so")
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
#protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS test.proto)
add_executable(${PROJECT_NAME} test.pb.cc ${PROTO_SRCS} ${PROTO_HDRS} "main.cpp")
target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})

    


Ответы

Ответ 1



Поискал по переменной Protobuf_SRC_ROOT_FOLDER и нашел вот что: FindProtobuf К сожалению мой английский sehr schlecht, но, насколько я понял у вас версия cmake слишком низкая (документация там начинается с 3.02), а сама переменная касается лишь определенного случая, касающегося Visual Studio и, что-то мне подсказывает, это не то, что вы используете. Посоветую написать Find-файл самому - это довольно просто

Ответ 2



У нас похожая ситуация, только QtCreator. Может поможет. Это переменные конфигурации CMake А это toolchain (если собирать не в QtCreator, а в консоли): set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(buildrootdir /home/vegorov/Build-Root/04.06.2018/BR-opo) set(buildtriplet arm-buildroot-linux-gnueabihf) set(CMAKE_SYSROOT ${buildrootdir}/output/host/${buildtriplet}/sysroot) set(CMAKE_STAGING_PREFIX ${buildroot}/output/spo-stage) set(tools ${buildrootdir}/output/host/) set(CMAKE_C_COMPILER ${tools}/bin/${buildtriplet}-gcc) set(CMAKE_CXX_COMPILER ${tools}/bin/${buildtriplet}-g++) set(PROTOBUF_PROTOC_EXECUTABLE "${tools}bin/protoc") set(CMAKE_PREFIX_PATH ${buildrootdir}/output/host/${buildtriplet}/sysroot/usr/lib/cmake) set(OE_QMAKE_PATH_EXTERNAL_HOST_BINS ${tools}/bin/) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(COMPILER_FLAGS "--sysroot=${CMAKE_SYSROOT} -O2 -march=armv7-a -marm -mfpu=vfpv3-d16 -mfloat-abi=hard -mcpu=cortex-a9") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS}" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS}" CACHE STRING "" FORCE) #set(envpath $ENV{PATH}) #set(ENV{PATH} "${tools}bin:${envpath}" ) #message(STATUS ":${tools}bin:${envpath}")

среда, 22 января 2020 г.

Qt5 кроскомпиляция из под Windows в ARM

#windows #qt #qt5 #arm #кросс_компиляция


Пытаюсь настроить Qt Creator (qt5.10.1) что бы можно было компилировать в нём проекты
для ARM систем.  

Но не знаю с чего начать, в интернете много каких-то мануалов, но все они не понятны
и сложны.  

Почему надо делать множество настроек (лезть  в конфиги кумейк.конф), когда можно
было бы создать простейший установщик и не париться?  



Установил  


  gcc-arm-none-eabi-7-2018-q2-update-win32.exe 


Прописал компилятор С:  


  arm-none-eabi-gcc.exe (директория ..\GNU_Tools_Arm_Embedded\7_2018-q2-update\bin)


Прописал компилятор С++:  


  arm-none-eabi-g++.exe (директория ..\GNU_Tools_Arm_Embedded\7_2018-q2-update\bin)


Прописал отладчик:  


  \GNU_Tools_Arm_Embedded\7_2018-q2-update\bin\arm-none-eabi-gdb.exe


Но где взять СMake? Где взять профиль Qt (для gcc-arm-а)?



Учёл ответ Павла и попробовал для начала собрать Qt из исходников по примеру  (для
начало на винду) 

C:\Qt\qt5\qt-everywhere-src-5.10.1\configure -platform ARM
+cd qtbase
+C:\Qt\qt5\qt-everywhere-src-5.10.1\qtbase\configure.bat -top-level -platform ARM 
Host platform 'ARM' is invalid. Aborting.


Попробовал так :

call configure.bat  -recheck-all -static -release -prefix C:\Qt\qt5\qt-relise-5_10_1
-opensource -confirm-license -nomake tools -nomake examples -nomake tests


Но увы снова не заработало

Cannot detect host toolchain. Please use -platform. Aborting.






Дополнил вызовом -platform linux-arm-gnueabi-g++


    


Ответы

Ответ 1



Вам нужно собрать Qt из исходников под вашу целевую операционную систему, либо попробовать найти у кого-то уже собранный. Обратите внимание: не для конкретного процессора, а для процессора+ОС.

четверг, 9 января 2020 г.

Кросскомпиляция модуля helloworld

#linux #c #makefile #кросс_компиляция #модули


Добрый день.
Пытаюсь собрать модуль helloworld под другую машину. Хост x86_64, таргет armhf.
Установил кросскомилятор /usr/bin/arm-linux-gnueabihf-gcc, скачал исходники ядра
под данную машину ~/projects/linux-3.4.113/
Пытаюсь собрать (пробовал через makefile, переменные, но поскольку ничего не получилось,
пытаюсь уже в лоб):
/usr/bin/arm-linux-gnueabihf-gcc -I~/projects/linux-3.4.113/ -c ./helloworld.c

(и много всяких мелких вариаций похожей команды)
На что раз за разом получаю ругань о том, что linux/modules.h не найден.
Может кто объяснить что я делаю не так, и как надо правильно?
Исходный код helloworld:

/*
 *  hello-1.c - The simplest kernel module.
 */
#include    /* Needed by all modules */
#include    /* Needed for KERN_INFO */

int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");

    /*
     * A non 0 return means init_module failed; module can't be loaded.
     */
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}


Содержимое Makefile, которым пытался собирать модуль:

CC := g++
TOOLCHAIN := arm-linux-gnueabihf
PT :=
CFL := -Wextra -std=c++11
TPATH := /usr/bin/
LPATH := /usr/$(TOOLCHAIN)/
ARCH := arm
all: helloworld.c
    $(TPATH)$(TOOLCHAIN)-$(CC) $(CFL) $(ARCH) -o helloworld.c 

    


Ответы

Ответ 1



Основные зависимости Для сборки внешних модулей ядра обязательно надо иметь: Исходные кода ядра, крайне желательно точно той же версии, что и на запущенном ядре (достаточно будет заголовочные файлы ядра с Makefile'ами [содержимое пакета linux-headers* в большинстве пакетных дистрибутивов]) Конфиг ядра под которое собираешь или максимально близкий. [Кросс-]компилятор, make и прочую dev-мишуру Типовая структура . ├── hello.c └── Kbuild hello.c: #include #include int init_module(void) { printk(KERN_INFO "Hello cruel world.\n"); return 0; } void cleanup_module(void) { printk(KERN_INFO "Goodbye cruel world.\n"); } Kbuild или Makefile, первое предпочтительнее. В простейшем случаее содержит одну строчку: obj-m += hello.o Подготовка дерева исходников ядра Далее подразумевается, что исходники ядра распакованы в /tmp/linux, префикс кросс компилятора armv6j-hardfloat-linux-gnueabi, а целевая архитектура arm. Создайм config: $ cd /tmp/linux $ cp /path/to/my/kernel/config ./.config Желательно сделать oldconfig и ответить на сотню другую вопросов, но вполне хватит и silentoldconfig. Внимание на - в конце CROSS_COMPILE — это не ошибка, так и должно быть. $ make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- silentoldconfig Стоит проверить, что поддержка модулей в ядре включена: $ grep CONFIG_MODULES .config CONFIG_MODULES_USE_ELF_REL=y CONFIG_MODULES=y CONFIG_MODULES_TREE_LOOKUP=y Подготовка дерева для сборки модулей: $ make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- modules_prepare Перед кросс компиляцией настоятельно советую потренироваться и собрать helloworld для текущего нативного ядра, всё точно также, но не надо указывать CROSS_COMPILE и ARCH. Сборка модуля $ cd /path/to/my/module $ make -C /tmp/linux ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- M=$PWD modules make: вход в каталог «/tmp/linux» WARNING: Symbol version dump ./Module.symvers is missing; modules will have no dependencies and modversions. CC [M] /tmp/hello-module/hello.o Building modules, stage 2. MODPOST 1 modules CC /tmp/hello-module/hello.mod.o LD [M] /tmp/hello-module/hello.ko make: выход из каталога «/tmp/linux» $ file hello.ko hello.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=16266c17567bf164e6fd4f48a52ecf477dad55cb, not stripped Всё, как видно на выходе получен hello.ko. Предупреждение про Module.symvers можно игнорировать покуда нет зависимостей от других модулей. Иначе нужно будет пересобрать модули самого ядра или разжиться данным файлом. К прочтению: Documentation/kbuild/modules.txt

понедельник, 15 апреля 2019 г.

Как прилинковать нестандартную версию protobuf используя cmake

Есть проект под arm который компилируется и собирается на х86ой машине (кросскомпиляция). Есть версия библиотеки protobuf собранная под arm по этой инструкции. В cmake файле я пытаюсь явно указать местоположение собранной под arm библиотеки через переменную Protobuf_SRC_ROOT_FOLDER но похоже что cmake эта переменная вообще побоку. Что мне сделать что бы find_package(Protobuf REQUIRED) нашёл ту версию protobuf которая мне нужна?
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -pthread ") #-lboost_system project(proto_test)
# Подключаем протобуф set (Protobuf_SRC_ROOT_FOLDER "/home/mrfieldy/prot_build/protobuf-3.5.1-arm/src") #set (Protobuf_USE_STATIC_LIBS ON) find_package(Protobuf REQUIRED) include_directories(${PROTOBUF_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS test.proto) add_executable(${PROJECT_NAME} test.pb.cc ${PROTO_SRCS} ${PROTO_HDRS} "main.cpp") target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})

Ответ:
В общем, как посоветовали ниже, я выбрал путь сначала выполнить find_package, а потом с помошью set переопределить пути. Долго искал на какие пути надо переопределить. Вот рабочий вариант.
cmake_minimum_required(VERSION 2.8) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -pthread ") project(proto_test) # Подключаем протобуф find_package(Protobuf REQUIRED) set (PROTOBUF_INCLUDE_DIRS "/home/mrfieldy/prot_build/protobuf-3.6.0-arm/src/") set (PROTOBUF_LIBRARIES "/home/mrfieldy/prot_build/protobuf-3.6.0-arm/src/.libs/libprotobuf.so") include_directories(${PROTOBUF_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) #protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS test.proto) add_executable(${PROJECT_NAME} test.pb.cc ${PROTO_SRCS} ${PROTO_HDRS} "main.cpp") target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})


Ответ

Поискал по переменной Protobuf_SRC_ROOT_FOLDER и нашел вот что:
FindProtobuf
К сожалению мой английский sehr schlecht, но, насколько я понял у вас версия cmake слишком низкая (документация там начинается с 3.02), а сама переменная касается лишь определенного случая, касающегося Visual Studio и, что-то мне подсказывает, это не то, что вы используете.
Посоветую написать Find-файл самому - это довольно просто

понедельник, 18 февраля 2019 г.

Кросскомпиляция модуля helloworld

Добрый день. Пытаюсь собрать модуль helloworld под другую машину. Хост x86_64, таргет armhf Установил кросскомилятор /usr/bin/arm-linux-gnueabihf-gcc, скачал исходники ядра под данную машину ~/projects/linux-3.4.113/ Пытаюсь собрать (пробовал через makefile, переменные, но поскольку ничего не получилось, пытаюсь уже в лоб): /usr/bin/arm-linux-gnueabihf-gcc -I~/projects/linux-3.4.113/ -c ./helloworld.c
(и много всяких мелких вариаций похожей команды) На что раз за разом получаю ругань о том, что linux/modules.h не найден. Может кто объяснить что я делаю не так, и как надо правильно? Исходный код helloworld:
/* * hello-1.c - The simplest kernel module. */ #include /* Needed by all modules */ #include /* Needed for KERN_INFO */
int init_module(void) { printk(KERN_INFO "Hello world 1.
");
/* * A non 0 return means init_module failed; module can't be loaded. */ return 0; }
void cleanup_module(void) { printk(KERN_INFO "Goodbye world 1.
"); }
Содержимое Makefile, которым пытался собирать модуль:
CC := g++ TOOLCHAIN := arm-linux-gnueabihf PT := CFL := -Wextra -std=c++11 TPATH := /usr/bin/ LPATH := /usr/$(TOOLCHAIN)/ ARCH := arm all: helloworld.c $(TPATH)$(TOOLCHAIN)-$(CC) $(CFL) $(ARCH) -o helloworld.c


Ответ

Основные зависимости
Для сборки внешних модулей ядра обязательно надо иметь:
Исходные кода ядра, крайне желательно точно той же версии, что и на запущенном ядре (достаточно будет заголовочные файлы ядра с Makefile'ами [содержимое пакета linux-headers* в большинстве пакетных дистрибутивов]) Конфиг ядра под которое собираешь или максимально близкий. [Кросс-]компилятор, make и прочую dev-мишуру
Типовая структура
. ├── hello.c └── Kbuild
hello.c
#include #include
int init_module(void) { printk(KERN_INFO "Hello cruel world.
"); return 0; }
void cleanup_module(void) { printk(KERN_INFO "Goodbye cruel world.
"); }
Kbuild или Makefile, первое предпочтительнее. В простейшем случаее содержит одну строчку:
obj-m += hello.o
Подготовка дерева исходников ядра
Далее подразумевается, что исходники ядра распакованы в /tmp/linux, префикс кросс компилятора armv6j-hardfloat-linux-gnueabi, а целевая архитектура arm
Создайм config:
$ cd /tmp/linux $ cp /path/to/my/kernel/config ./.config
Желательно сделать oldconfig и ответить на сотню другую вопросов, но вполне хватит и silentoldconfig. Внимание на - в конце CROSS_COMPILE — это не ошибка, так и должно быть.
$ make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- silentoldconfig
Стоит проверить, что поддержка модулей в ядре включена:
$ grep CONFIG_MODULES .config CONFIG_MODULES_USE_ELF_REL=y CONFIG_MODULES=y CONFIG_MODULES_TREE_LOOKUP=y
Подготовка дерева для сборки модулей:
$ make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- modules_prepare
Перед кросс компиляцией настоятельно советую потренироваться и собрать helloworld для текущего нативного ядра, всё точно также, но не надо указывать CROSS_COMPILE и ARCH
Сборка модуля
$ cd /path/to/my/module $ make -C /tmp/linux ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- M=$PWD modules
make: вход в каталог «/tmp/linux»
WARNING: Symbol version dump ./Module.symvers is missing; modules will have no dependencies and modversions.
CC [M] /tmp/hello-module/hello.o Building modules, stage 2. MODPOST 1 modules CC /tmp/hello-module/hello.mod.o LD [M] /tmp/hello-module/hello.ko make: выход из каталога «/tmp/linux»
$ file hello.ko hello.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=16266c17567bf164e6fd4f48a52ecf477dad55cb, not stripped
Всё, как видно на выходе получен hello.ko
Предупреждение про Module.symvers можно игнорировать покуда нет зависимостей от других модулей. Иначе нужно будет пересобрать модули самого ядра или разжиться данным файлом.
К прочтению:
Documentation/kbuild/modules.txt