× К оглавлению На главную Об авторе

Дата и время публикации:    

Проблема и решение

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борка

При этом трекер ошибок 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.
...
Примечание. Debian ОС GNU Linux 11 (на сентябрь 2020 года) были доступны две версии компилятора GCC-9 и GCC-10, последние из-за введения более драконовских условий стал более разборчив при обнаружении многократного определения псевдонима или синонима типа c использованием спецификатора типа typedef, которым скорей всего следует пользоваться, как было во времена GCC-2:
 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-машины.

Примечание. К полноценным ABI относятся такие, как Стандарт Бинарной Совместимости Intel (Intel Binary Compatibility Standard, iBCS), позволяющие программе одной операционной системы поддерживать его для запуска без модификаций на другой подобной системе, которая имеет в своем составе необходимые разделяемые библиотеки с учетом выполнения аналогичных требований. Другие ABI детализируют, например, такие как изменение имен C++ (C++ name mangling), распространение действия исключений (exception propagation) и установленные соглашения между компиляторами на одной и той же аппаратной платформе, но не требующие кросс-платформенной совместимости.

Поэтому 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

3.2 How to Set the Toolchain Version in Yocto

3.2 GNU Compiler Collections. Porting to GCC 10

Сайт разработан в соответствии с рекомендациями консорциума W3C для языка разметки HTML5.

Об авторе можно прочитать здесь.

Copyright © 2015-2019 Андрей Ржавсков