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.

В принципе, есть много вариантов того, что вы пытаетесь сделать.