«Неопределенная ссылка» при связывании кода C в Linux - PullRequest
0 голосов
/ 01 ноября 2010

У меня есть библиотека кода (полностью написанная на C), которую я обычно компилирую под Windows, в .DLL.

Я хочу скомпилировать ее под Linux, чтобы ее можно было распространять.Мне все равно, распространю ли я его как .a, .so или набор файлов .o.

Все отдельные файлы .c успешно компилируются.Но когда я пытаюсь скомпилировать исполняемый файл теста, который включает все файлы .o, я получаю кучу неопределенных ошибок ссылок.

Все файлы .o находятся в командной строке как полные пути, иЯ не получаю ошибок об отсутствующих файлах.

cc testctd.c -o testctd.out -lm -lc $LIBRARY-PATH/*.o

У меня также есть неопределенные ссылки на _open, _write и т. Д.

Ответы [ 2 ]

2 голосов
/ 01 ноября 2010

У вас есть опции -l в неправильном месте

-llibrary

-l библиотека

Поиск библиотеки с именем библиотека при компоновке.(Второй вариант с библиотекой в ​​качестве отдельного аргумента предназначен только для соответствия POSIX> и не рекомендуется.)

Разница в том, где в команде вы пишете эту опцию;компоновщик ищет и обрабатывает библиотеки и объектные файлы в указанном порядке.Таким образом,

foo.o -lz bar.o

ищет библиотеку z после файла foo.o, но перед bar.o.Если bar.o ссылается на функции в z, эти функции могут не загружаться.

Компоновщик ищет стандартный список каталогов для библиотеки, который на самом деле является файлом с именем liblibrary.a.Затем компоновщик использует этот файл, как если бы он был указан точно по имени.

2 голосов
/ 01 ноября 2010

Вы не предоставили достаточно информации для полного ответа, но мне кажется, я знаю одну о ваших проблемах: функции open, read, write, close и т. Д.У них есть подчеркивания перед их именами в Windows, но они не в Linux (или любом другом Unix в этом отношении).При компиляции файлов .c компилятор должен был предупредить вас об этом - если это не так, включите предупреждения!В любом случае, вам придется удалить все эти подчеркивания.Я бы порекомендовал заголовочный файл, который выполняет что-то вроде следующего:

#ifdef _WIN32
#define open(p, f, m) _open(p, f, m)
#define read(f, b, n) _read(f, b, n)
#define write(f, b, n) _write(f, b, n)
#define close(f) _close(f)
/* etc */
#endif

, а затем использует только имена без подчеркивания в вашем фактическом коде.

Кроме того, -l параметры (такие каккак -lm) должен быть помещен после всех объектных файлов.Нет необходимости указывать -lc (и это может вызвать проблемы при слишком таинственных обстоятельствах).

...