LINUX.ORG.RU

[Язык C] Линковка объектников с кольцевыми звисимостями друг на друга. Как разрулить?


0

2

Здравствуйте!

Дали мне тут исходники одного проекта, пытаюсь заставить его компилироваться под Linux с помощью gcc.

Первый этап прошел - все исходники смог скомпилировать в o-файлы.

Следующий этап - линковка конечного исполняемого файла. И тут загвоздка. В GCC есть зависимость от перечисления объектников. То есть, объектники надо перечислить в такой последовательности, чтобы при подлинковывании каждого последующего объектника вся информация об используемых функциях уже была известна.

А в этом проекте код организован так, что встречаются файлы A и B, причем в файле A используются функции B, а в B используются функции A (некоторые не так прямо, а по цепочке через другие файлы).

Вариант линковки 1:

gcc -lc -lSDL -lSDL_mixer -o prog a.o b.o
a.o: In function `init':
a.c:(.text+0x1c): undefined reference to `setDefParams'

- ошибка из-за того, что функция setDefParams() определена в b.o, и на момент линковки файла a.o неизвестна.

Вариант линковки 2:

gcc -lc -lSDL -lSDL_mixer -o prog b.o a.o
b.o: In function `openData':
b.c:(.text+0x9c): undefined reference to `printLog'

- ошибка из-за того, что функция printLog() определена в a.o, и на момент линковки файла b.o неизвестна.

Вопрос. Как разрулить такие кольцевые зависимости?

★★★★★

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

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

note173 ★★★★★
()

В смысле cyclic-dependencies? Емнип, в винде костылей больше, у ld же есть --start-group / --end-group - вроде то. Но обычно советуют реорганизовать код.

anonymous
()

Упакуй свои бинарники в статическую библиотеку (ar cru mylib.a a.o b.o) и линкуйся с ней. Для пущей убедительности можно будет еще заключить ее в -Wl,-( и -Wl,-)

Но самый переносимый вариант — переписать свою поделку по-человечески.

red_eyed_peguin
()
Ответ на: комментарий от note173

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

Потому что половина проекта на ассемблере.

Xintrea ★★★★★
() автор топика

инкрементально линкуй.

а вообще странно.

$ cat a.c
int b();
int main() { b(); }
$ cat b.c
int main();
int b() { main(); }
$ gcc -c a.c
$ gcc -c b.c
$ gcc -o prog a.o b.o 
$ _

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

Упакуй свои бинарники в статическую библиотеку (ar cru mylib.a a.o b.o) и линкуйся с ней.

Н увот как попробовал сделать:

ar cru libasm.a emucore.o emucpu.o emuio.o emukeyb.o emumisc.o emurom.o interf.o

gcc -L./ -lc -lSDL -lSDL_mixer -lasm -o emu80 sound.o main.o menus.o misc.o scrdraw.o sdllayer.o emuinit.o 

main.o: In function `main':
main.cpp:(.text+0x1c): undefined reference to `SetDefParams'

Функция SetDefParams() находится в объектнике emucore.o, который засунут в libasm.a.

В main.cpp прописано:

extern "C" void SetDefParams();
...
SetDefParams();

Вопрос. Почему не видится сия функция?

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

> А 3 файла?

$ gcc -c a.c
$ gcc -c b.c
$ gcc -c main.c
$ gcc -o prog main.o a.o b.o 
$ cat main.c
int a();
int main() { a(); }
$ cat a.c
int b();
int a() { b(); }
$ cat b.c
int main();
int b() { main(); }
$ _
arsi ★★★★★
()

слинкуй несколько раз, то есть "-lc -lSDL -lSDL_mixer" повтори несколько раз, должно помочь, но вообще если так происходит - значит что-то не так в архитектуре :)

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

покажи nm emucore.o

Да вот весь проект:

http://rghost.ru/36018752

Makefile - это я написал. Всё остальные файлы - это исходники, которые под виндой вроде как собираются. Для сборки нужны gcc и nasm.

red_eyed_peguin, shty, arsi посмотрите тоже. Может, кто сможет лучше меня причесать.

PS: Я попробовал через CMake сделать сборку, но она искаропки не работает с NASM. Есть даже модули для NASM, но они позволяют делать только конечный исполнимый файл из asm-файла, сборка проекта из кусков не работает - пишет что нужны какие-то еще модули CMake.

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

Во первых, *.cpp надо g++ собирать, тащемта.

Там код C-шный, плюсами там и не пахло. ghjcnj afqks gj rfrjq-nj ghbxbyt *.cpp названы.

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

gcc -L./ -lc -lSDL -lSDL_mixer -lasm -o emu80 sound.o main.o menus.o misc.o scrdraw.o sdllayer.o emuinit.o

Попробуй поставить libasm.a последней

Нет, так тоже не линкуется.

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

во-первых, g++, а не gcc.

во-вторых, в линуксе к глобальным функциям/переменным не добавляется в начале «_».

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

в линуксе к глобальным функциям/переменным не добавляется в начале «_».

Ага, в этом была проблема. Собрал. Меня сам автор уверял, что подчеркивание необходимо при extern «C».

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

Собрал, патч выкладывать или уже не надо?

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

Собрал, но имеем сразу сегфолт.

Что бы означала вот эта запись:

// Выделяем область памяти под сегмент 8080
mempage0=new unsigned char[65536+32]+16;

?

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

> Собрал, но имеем сразу сегфолт.

$ ulimit -c unlimited
$ ./prog
…
$ gdb ./prog core
> bt
…
> q
$ _

> Что бы означала вот эта запись

выделяется 64к + 32 байта памяти и переменной mempage0 присваивается адрес 16-го байта от начала выделенного фрагмента…

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

Кароче, похоже что дали мне не все файлы. Должен быть файл fonts/symgen.bin.

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

Функция SetDefParams() находится в объектнике emucore.o, который засунут в libasm.a.

U r doing it wrong. Библиотеки _всегда_ должны идти после объектников, потому что в момент подключения библиотеки компоновщик ищет в ней неразрешенные на текущий момент символы. Оберни все это дело в -Wl,-( .. -Wl,-). И, кстати, зачем -L. -lasm, когда можно просто указать libasm.a в списке файлов?

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