MacOS - как связать динамическую библиотеку с относительным путем с помощью gcc/ld
Если вы пытаетесь понять динамическое связывание, этот вопрос, вероятно, будет интересен.
Один из ответов на этот вопрос дает прекрасный пример создания и использования динамической библиотеки. Основываясь на этом, я несколько простых файлов:
main.c:
extern void someFunction (int x);
int main (int argc, char** argv ) {
someFunction(666);
}
mylibrary.c:
#include <stdio.h>
void someFunction (int x) {
printf ("\nsomeFunction called with x=%d\n", x);
}
Makefile:
main: mylibrary.c main.c
gcc -c mylibrary.c
gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
gcc -c main.c
gcc -v main.o ./libmylibrary.dylib -o main
clean:
rm *.o
rm main
rm *.dylib
Пока все работает отлично. Если я сделаю, а затем введите. /main в командной строке, я увижу ожидаемый результат:
someFunction called with x=666
Теперь я хочу немного перепутать. Я создал каталог hidelib, который является подкаталогом моего основного каталога. И я добавляю одну строку в свой make файл:
main: mylibrary.c main.c
gcc -c mylibrary.c
gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
gcc -c main.c
mv libmylibrary.dylib hidelib # this is the new line
clean:
rm *.o
rm main
rm hidelib/*.*
Теперь я хочу добавить еще одну строку в make файл, чтобы найти libmylibrary.dylib в подкаталоге hidelib. Я хочу иметь возможность запускать. /main таким же образом. Как я могу это сделать?
EDIT: Спасибо за ответ. Имея много вариантов, замечательно, но новичок просто хочет, чтобы один конкретный вариант работал. Вот что я пытаюсь сделать для последней строки, но, очевидно, я ничего не понимаю. Makefile выполняется без ошибок, но во время выполнения он говорит, что "библиотека не найдена".
gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main
Ответы
Ответ 1
Один конкретный вариант, который работает, - установить флаг install_name
при связывании .dylib
.
gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib
Затем вы можете просто подключиться к библиотеке:
gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main
Ответ 2
Вероятно, вам нужен флаг -L
для компилятора/компоновщика, который добавляет путь поиска для библиотек.
Я пытаюсь переместить объекты после ссылки, вам понадобится переменная среды dyld
для поиска. man dyld
, и вы сможете получить дополнительную информацию о DYLD_LIBRARY_PATH
и других переменных среды.
Как правило, вы устанавливаете имя для установки библиотеки, прежде чем ссылаться на что-то с флагом -install_name
linker на что-то вроде @rpath/mylibrary.dylib
в качестве значения, затем задайте пути поиска пути запуска в основном исполняемом файле при компиляции с флаг -rpath
на @executable_path/hidelib
.
Для получения дополнительной информации см. install_name_tool
и -rpath
и -install_name
аргументы ld
.
В принципе, есть много вариантов того, что вы пытаетесь сделать.