Дата и время публикации:
Проблема и решение
1. Суть проблемы
А все началось с того, что сборка пакета pseudo(-native) завершилась с кучей предупреждений и фатальными ошибками:
... | pseudo_wrapper_table.c:664:3: warning: cast between incompatible function types from ‘int (*)(char *, int, int)’ to ‘int (*)(void)’ [-Wcast-function-type] | 664 | (int (*)(void)) wrap_mkostemps, | | ^ | pseudo_wrapper_table.c:670:3: warning: cast between incompatible function types from ‘int (*)(char *)’ to ‘int (*)(void)’ [-Wcast-function-type] | 670 | (int (*)(void)) wrap_mkstemp, | | ^ | pseudo_wrapper_table.c:676:3: warning: cast between incompatible function types from ‘int (*)(char *)’ to ‘int (*)(void)’ [-Wcast-function-type] | 676 | (int (*)(void)) wrap_mkstemp64, | | ^ | pseudo_wrapper_table.c:682:3: warning: cast between incompatible function types from ‘int (*)(char *, int)’ to ‘int (*)(void)’ [-Wcast-function-type] | 682 | (int (*)(void)) wrap_mkstemps, | | ^ | pseudo_wrapper_table.c:688:3: warning: cast between incompatible function types from ‘char * (*)(char *)’ to ‘int (*)(void)’ [-Wcast-function-type] | 688 | (int (*)(void)) wrap_mktemp, … | pseudo_wrapper_table.c:1024:3: warning: cast between incompatible function types from ‘int (*)(const char *, const struct timeval *)’ to ‘int (*)(void)’ [-Wcast-function-type] | 1024 | (int (*)(void)) wrap_utimes, | | ^ | In file included from port_wrappers.c:3, | from pseudo_wrappers.c:296: | ports/linux/pseudo_wrappers.c: In function ‘syscall’: | ports/linux/pseudo_wrappers.c:84:30: warning: cast between incompatible function types from ‘long int (*)(long int, ...)’ to ‘void (*)()’ [-Wcast-function-type] | 84 | void *res = __builtin_apply((void (*)()) real_syscall, __builtin_apply_args(), sizeof(long) * 7); | | ^ ... | /home/user/poky/build/tmp/hosttools/ld: pseudo_db.o:/home/user/poky/build/tmp/work/x86_64-linux/pseudo-native/1.9.0+gitAUTOINC+060058bb29-r0/git/pseudo_ipc.h:37: multiple definition of `pseudo_access_t'; pseudolog.o:/home/user/poky/build/tmp/work/x86_64-linux/pseudo-native/1.9.0+gitAUTOINC+060058bb29-r0/git/pseudo_ipc.h:37: first defined here | collect2: error: ld returned 1 exit status | make: *** [Makefile:113: bin/pseudodb] Error 1 | make: *** Waiting for unfinished jobs.... | /home/user/poky/build/tmp/hosttools/ld: pseudo_util.o:/home/user/poky/build/tmp/work/x86_64-linux/pseudo-native/1.9.0+gitAUTOINC+060058bb29-r0/git/pseudo_ipc.h:37: multiple definition of `pseudo_access_t'; pseudolog.o:/home/user/poky/build/tmp/work/x86_64-linux/pseudo-native/1.9.0+gitAUTOINC+060058bb29-r0/git/pseudo_ipc.h:37: first defined here | collect2: error: ld returned 1 exit status | make: *** [Makefile:107: bin/pseudolog] Error 1 | collect2: error: ld returned 1 exit status | make: *** [Makefile:100: bin/pseudo] Error 1 | ERROR: oe_runmake failed ...
Условия сборки заключались в том, что cборка
- пакета pseudo(-native) производилась, в начале сентября 2020 года, с использованием среды разработки (собственного) дистрибутива Yocto/Poky с одной из устаревших на этот момент версии, но пока поддерживающейся ещё сообществом проекта Yocto, если верить списку поддерживаемых релизов.
- осуществлялась на host-системе под управлением дистрибутива Debian ОС GNU Linux 11.
При этом трекер ошибок Debian отрапортовал, о нечто похожим со сборкой пакета pseudo и предлагал использовать версию GCC-9 вместо GCC-10:
user@home:~/Build/poky/build$ gcc --version gcc (Debian 10.2.0-5) 10.2.0 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ...
1: #ifndef __pseudo_ipc_H 2: #define __pseudo_ipc_H 1 ... 37: /* The [] item at the end of the struct is a C99 feature, replacing the 38: * old (and unportable) "struct hack". 39: */ 40: # if !defined __pseudo_msg_type && defined __pseudo_ipc_H 41: # define __pseudo_msg_type 42: typedef struct { 43: pseudo_msg_type_t type; 44: pseudo_op_t op; 45: pseudo_res_t result; 46: ... 47: } pseudo_msg_t; ... 72: #endif /*__pseudo_ipc_H*/Где макроопределения __pseudo_ipc_H и __pseudo_msg_type гарантируют отсутствие возникновения ошибки, связанной с многократным определением компилятором GCC-10 на этапе трансляции. Использование подобных макроопределений избавит самого разработчика и контрибьютеров исходного кода в дальнейшем от решения головоломки, где и что править.
2. Решение
Для выработки решения, сначала рассмотрим, что происходит, когда производится сборка образа выбранной встраиваемой платформы, целевой машины, например ARM, на осуществляющую сборку, так называемую, хозяйскую машину или host-машину.
Соответственно, собираемая система точно не может использовать компилятор GCC из окружения host-машины, т.к. набор инструкций ЦПУ, предназначен для целевой машины, коей является ARM, и отличается от машины, на которой осуществляется сборка, коей является amd64 (х86-64) . В следствии чего, нам нужен другой экземпляр компилятора собранного с учетом архитектуры целевой машины, который поможет нам развернуть целевую, собираемую систему и необходимое ей окружение на host-машине.
Собранный экземпляр компилятора GCC называется кросс-компилятором, потому что в отличии от обычного экземпляра собранного для своей архитектуры целевой машины может запускаться на host-машине, функциклирующей на архитектурной платформе х86-64
Кроме того, также нам потребуется набор утилит, выполняющие во время сборки и компоновки исполняемых файлов, библиотек и модулей ядра бинарного кода собираемого пакета требование целевой архитектуры, но и/или, возможно, приводящие к соответствию требования прикладного бинарного интерфейса (Application binary interfac, ABI), который может разительно отличаться с ABI не только host-машины.
Поэтому Yocto/poky производит насколько возможно совместимую сборку окружения с целевой машиной, в процессе которого собираются утилиты, именуемые toolchain, с версиями указанными в метаданных собираемых пакетов .
В различных системах кросс-платформенной сборки образов дистрибутивов Linux часто используется уже кем-то ранее собранные наборы утилит toolchain, но в случае с Yocto/poky для сборки кросс-платформенных утилит toolchain используется компилятор host-машины, на который указывает символическая ссылка /usr/bin/gcc
user@home:~/Build/poky/build$ ls -l /usr/bin/gcc lrwxrwxrwx 1 root root 6 июл 21 17:16 /usr/bin/gcc -> gcc-10
Теперь, поставим вопрос: "А причем пакет pseudo(-native) и набор утилит toolchain?". – А все потому, что при использование busybox в их число включаются пакеты, имеющие суффикс -native . Поэтому, при возникновение подобных проблем сборки пакета pseudo-native на Debian-11, в конфигурационном файле сборочной директории conf/local.conf нужно прописать:
... # change the default compilers are BUILD_CC ="/usr/bin/gcc-9 " BUILD_CCLD ="/usr/bin/gcc-9 " BUILD_AR ="/usr/bin/gcc-ar-9 " BUILD_NM ="/usr/bin/gcc-nm-9 " BUILD_RANLIB ="/usr/bin/gcc-ranlib-9 " BUILD_CPP="/usr/bin/gcc-9 -E" ...
При этом лучше прописывать полные пути. Кроме того, также может потребоваться переназначение других компиляторов, полный список которых обычно определены в meta/classes/native.bbclass :
... 60: # set the compiler as well. It could have been set to something else 61: export CC = "${BUILD_CC}" 62: export CXX = "${BUILD_CXX}" 63: export FC = "${BUILD_FC}" 64: export CPP = "${BUILD_CPP}" 65: export LD = "${BUILD_LD}" 66: export CCLD = "${BUILD_CCLD}" 67: export AR = "${BUILD_AR}" 68: export AS = "${BUILD_AS}" 69: export RANLIB = "${BUILD_RANLIB}" 70: export STRIP = "${BUILD_STRIP}" 71: export NM = "${BUILD_NM}" ...
3. Библиография
3.1 ADT manual.The-cross-development-toolchain