У меня проблема с привязкой файла .so к моему main1.c
Сначала я использовал приведенную ниже команду для создания файла .so из нескольких исходных файлов c и файлов заголовков.
Arm-linux-gnueabi-gcc -shared -o ~/Docs/examples/libmylib1.so -fPIC *.c -lpthread -ldl -lm
Затем я создал файл main1.c в той же папке (~/Docs/examples) и использовал следующую команду для создания другого файла .so для main1.c, использующего libmylib1.so.
Arm-linux-gnueabi-gcc -shared -o libmain2.so main1.c -L ~/Docs/examples -lmylib1 -lpthread -ldl -lm
Когда я копирую файл libmylib1.so в другую папку и пытаюсь использовать его с другим файлом code.c, он не работает. Новая папка содержит только libmylib1.so и code.c. Вот команда, которую я использовал.
Arm-linux-gnueabi-gcc -shared -o libcode1.so code.c -L ~/Docs/newlocation -lmylib1 -lpthread -ldl -lm
Но когда я добавляю {-idirafter ~/Docs/examples} и включаю исходное местоположение libmylib1.so, кажется, что это работает.
Вот некоторые из моих попыток:
**abc@abc-TULPAR-T5-V21-4:~/Docs/newlocation$** ls
Code.c libmylib1.so
**abc@abc-TULPAR-T5-V21-4:~/Docs/newlocation$** arm-linux-gnueabi-gcc -shared -o libcode1.so code.c -L ~/Docs/newlocation -lmylib1 -lpthread -ldl -lm
Code.c:1:10: фатальная ошибка: comm_genlib.h: нет такого файла или каталога
1 | #include "comm_genlib.h"
| ^~~~~~~~~~~~~~~
Компиляция прекращена.
**abc@abc-TULPAR-T5-V21-4:~/Docs/newlocation$** arm-linux-gnueabi-gcc -shared -o libcode1.so code.c -L ~/Docs/newlocation -idirafter ~/ Документы/примеры -lmylib1 -lpthread -ldl -lm
**abc@abc-TULPAR-T5-V21-4:~/Docs/newlocation$** ls
Code.c libcode1.so libmylib1.so
Я не знаю, почему это работает, когда я добавил -idirafter ~/Docs/examples
Как это исправить?
См. TLDP — общие библиотеки
Во время компиляции есть две важные фазы: преобразование исходного кода в необработанный двоичный файл и упаковка всех необработанных двоичных файлов, необходимых для формирования исполняемого файла или общей библиотеки.
На первом этапе компилятор должен иметь доступ ко всем исходным файлам: '.c', указанному в командной строке, а также ко всем другим исходным файлам, на которые есть ссылки в этих '.c' по #include инструкциям.
Чтобы найти эти источники, компилятор просматривает некоторые специфичные для компилятора каталоги, например /usr/include; он также выполняет поиск в текущем каталоге.
Но каталог ~Docs/examples не является частью каталогов поиска по умолчанию. Таким образом, ссылка на comm_genlib.h не может быть разрешена, и происходит сбой компиляции.
Опция -idirafter добавляет этот каталог в пути поиска. Вот почему компиляция работает при добавлении.
На этом первом этапе двоичные файлы, такие как файлы .so, не используются. Они будут на втором этапе компиляции. В любом случае, .h файлы не включаются в бинарные файлы; они используются только как текстовые файлы на первом этапе.
У проблемы, с которой вы столкнулись, нет конкретного решения, потому что, в конце концов, это не проблема, а то, как работает компилятор C.
Означает ли это, что я не могу скопировать libmylib1.so (сгенерированный из нескольких файлов, включая файлы comm_genlib) отдельно в другое место и использовать его с другими кодами, которые зависят от libmylib1.so?
Общая библиотека '.so' обычно поставляется с файлами заголовков '.h', которые ее описывают. Вы можете использовать только «.so», но если вы ссылаетесь на файл «.h», он должен присутствовать.
Большое спасибо. Я включил файлы заголовков вместе с файлом .so. Теперь проблема решена.
После перемещения вашей библиотеки в ~/Docs/newlocation она больше не может быть найдена компоновщиком или библиотекой, загруженной как часть среды выполнения. Вы можете либо установить LD_LIBRARY_PATH=/home/youruser/Docs/newlocation:${LD_LIBRARY_PATH} и export LD_LIBRARY_PATH, либо скомпилировать любые последующие библиотеки, либо main с -Wl,-rpath=/home/youruser/Docs/newlocation (-rpath= осуждается). Лучше просто поместить библиотеки в стандартные места. Как /usr/local/lib (или lib64), которые уже являются частью обычного пути поиска.