2013-11-18 6 views
4

У меня есть проект GCC для микроконтроллера. Есть некоторые функции в время выполнения, которые должны быть заменены, чтобы адаптировать окружающую среду:Ссылка на конкретную библиотеку

_write_r 
_sbreak_r 

Я выполнил функции в файл sys.c. Когда я связываю файл sys.o с моим проектом, он работает так, как ожидалось. Но когда я добавил sys.o в библиотеку bsp.a и связал библиотеку с моим проектом, реализация libc.a имеет приоритет, и моя замена больше не работает.

Как я могу связать линкер с тем, что он сначала связывает мою библиотеку, прежде чем принимать определения из libc? Я бы предпочел решение, в котором скрипт компоновщика управляет этим приоритетом.

Редактировать: GCC вызывается средой разработки для этапа связывания. Он управляет вызовом ld, а параметры командной строки ld не могут контролироваться напрямую.

Редактировать: Центральный процессор Cotex-M3 NXP LPC1788.

Когда я запускаю ССАГПЗ, связывающую команду с опцией -v я получаю эту информацию:

c:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/collect2.exe 
--sysroot=arm\bin\../arm-none-eabi 
-X 
-o bin/test.elf 
-n arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crti.o arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crtbegin.o arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/crt0.o 
-LD:/mylibs 
-LC:\arm\lib 
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m 
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m 
-Lc:/arm/bin/../arm-none-eabi/lib/armv7-m 
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4 
-Lc:/arm/bin/../lib/gcc 
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib 
-Lc:/arm/bin/../arm-none-eabi/lib @C:\Users\harper\AppData\Local\Temp\cc9FN35g 
--start-group -lgcc -lc --end-group 
c:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crtend.o 
c:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crtn.o 
-T src\LPC1788_Flash.ld 

Очевидно, есть --start-group -gcc -lc --end-groupcollect2.exe аргумент. Но еще не удалось добавить мою библиотеку.

Файл LPC1788_Flash.ld имеет это содержание:

ENTRY(Reset_Handler) 
MEMORY { 
    FLASH (rx) : ORIGIN = 0, LENGTH = 512K 
    RAM (xrw) : ORIGON = 0x10000000, LENGTH = 64K 
} 
SECTIONS { 
    // a lot of input and output sections, like ... 
    .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) } >FLASH 
    .data : { ... } >RAM 
    .bss : { ... } >RAM 
    /DISCARD/ : { 
    libc.a (*) 
    libm.a (*) 
    libgcc.a (*) 
    } 
} 
+0

Это не должно быть сложнее, чем вставлять им правильный порядок в вызове компоновщика. http://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking/ – auselen

+0

@auselen Это предположение верно только в том случае, если вы рассматриваете библиотеки пользователей или вы вызываете компоновщик вручную. (см. мое редактирование). – harper

+0

Это что-то не может быть разрешено опцией gcc «-Wl»? Этот переключатель передает параметры компоновщику. – auselen

ответ

0

Это очень просто:
библиотеки Glibc сами справиться с этой проблемой: большинство функций должны быть связана статический, но некоторые из них могут быть использованы динамически и используются в общем объекте.
Кроме того, в статическом архиве есть дубликат некоторых функций, обнаруженных в общем объекте Glibc.

Итак, на всех платформах Glibc можно использовать по умолчанию, скрипт компоновщика установлен со статической версией Glibc. Независимо от ОС файл находится в каталоге /lib/libc.so (или /lib64/libc.so, если вы используете 64-разрядные). Он содержит следующее:

/* GNU ld script 
    Use the shared library, but some functions are only in 
    the static library, so try that secondarily. */ 
OUTPUT_FORMAT(elf64-x86-64) 
GROUP (/lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED (/lib64/ld-linux-x86-64.so.2)) 

Я не знаю, какой LibC вы используете (это может быть μClibc), но файл libc.so никогда не приводят к бинарным (если она существует).

Итак, вам необходимо либо изменить его или создать его:

OUTPUT_FORMAT(the_format_used_by_your_micro-controller_architecture) 
GROUP(/the_path_to_your_custom_library_binary /the_path_your_libc_binary AS_NEEDED (/the path the_path_your_interpreter_binary)) 

Порядок, в котором вы указываете в GROUP() материи: если экспорт-символы существует в обеих библиотеках бинарных файлов, то они будут должен быть обеспечен первым двоичным кодом в GROUP().

+0

При добавлении одной или обеих строк OUTPUT_FORMART ("elf32-littlearm") GROUP (d: /path/to/mylib.ad :/path/to/libc.a) к сценарию LD Я просто получаю сообщение " синтаксическая ошибка "для строки с первой добавленной строкой. – harper

+0

@harper: Этот значок elf32-littlearm является недопустимым именем (для gnu ld POV). Я понимаю, что найти правильное имя сложно. Но вы не сказали, какой процессор вы используете. Помните, что есть несколько версий арки ARM (arm5; arm7; arm12 ...), каждый из которых несовместим с другими. Вы также использовали стиль окна пути (frive letter). Независимо от того, какую оболочку вы используете, вам нужно понять, что вы должны использовать [стиль пути UNIX] (https://en.wikipedia.org/wiki/Unix_path#Unix_style «Википедия»). Корневой каталог относится к корню вашей установки обертки/средства разработки. – user2284570

+0

objcopy получает именно этот аргумент: 'objcopy -I binary -O elf32-littlearm -B arm - раздел -определение .data = .rodata foo.png fpp \ FatalError.o' Как найти действительное имя (для GNU ld POV) (или для COLLECT2, если это отличается)? – harper

0

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

Это может быть сделано путем явной ссылки на символ этого файла.

extern int _write_r(); 
void *magic = &_write_r; 

Этот код должен быть размещен так, чтобы компилятор не пропускал его из-за оптимизации.

Использование сценария компоновщика для создания группы, включая пользовательскую библиотеку с системными библиотеками, к сожалению, невозможно. Определения GROUP сценария компоновщика обрабатываются после групп, определенных встроенными правилами.

+0

+1 Ну, это временное решение, но оно также может работать ... :) – user2284570

+0

Нет, это не время выполнения, так как во время выполнения ничего не будет. Но он находится на уровне исходного кода и требует загрязнения кода, и вы получаете переменную 'magic', что может добавить уровень путаницы. Для комментариев нужно добавить дополнительные усилия, чтобы показать, почему никто не должен удалять этот хак. Поэтому это относится только к категории обходного пути. – harper

Смежные вопросы