Как создать простой файл main.cpp с помощью samtools C API
Я пытаюсь скомпилировать (в Linux, используя G++) простую программу main.cpp, используя samtools C API ( https://github.com/samtools/samtools), которую я скачал в папку моего файла main.cpp. Я хотел бы иметь очень простой make-файл, компилирующий main.cpp (и в конечном итоге компилирующий код samtools). Однако, поскольку у меня очень мало знаний о make-файлах, я, вероятно, что-то делаю не так.
Вот мой make-файл:
SAMTOOLS=./samtools/
HTSLIB=${SAMTOOLS}htslib-1.9/
all: samtools htslib BAMCoverage
samtools:
${MAKE} -C ${SAMTOOLS}
htslib:
${MAKE} -C ${HTSLIB}
BAMCoverage: main.cpp
g++ -I./ -I${SAMTOOLS} -I${HTSLIB} -g -O2 -Wall ./main.cpp -o ./BAMCoverage -lz -L${SAMTOOLS} -L${HTSLIB} -lbam -lhts
И вот мой главный cpp:
#include "samtools/sam.h"
#include <string>
#include <iostream>
using namespace std;
int main (int argc, char *argv[]) {
string bam_file_path ("myfile.bam");
bamFile bam_file = bam_open (bam_file_path.c_str (), "rb");
if (bam_file == 0) {
cerr << "Failed to open BAM file " << bam_file_path << endl;
return 1;
}
bam_close (bam_file);
return 0;
}
Он компилируется без предупреждения, когда я запускаю "make", но во время выполнения он сообщает мне: "ошибка при загрузке общих библиотек: libhts.so.2 не может открыть файл общих объектов"
Любая помощь приветствуется! Заранее спасибо.
1 ответ
Это не проблема с вашим make-файлом как таковым; у вашего make-файла есть некоторые проблемы, но проблема, с которой вы сталкиваетесь, заключается в понимании того, как правильно связываться с общими библиотеками. Другими словами, если вы запустите тот же набор команд из командной строки оболочки, вместо использования make-файла, у вас возникнет та же проблема.
Вы должны искать документацию по вашей опции командной строки ссылки -L
и прочитайте о разнице между местоположением библиотеки времени выполнения и библиотеки времени выполнения.
-lfoo
опция сообщит компоновщику ссылку в библиотеку с именем foo
, -Lsome/dir
опция скажет компоновщику найти эту библиотеку foo
в каталоге some_dir
,
Если компоновщик находит статическую библиотеку libfoo.a
тогда любые части этой библиотеки, необходимые для связи вашей программы, будут включены непосредственно в вашу программу. Это делает вашу программу больше, но это означает, что во время выполнения ничего кроме вашей программы не нужно искать.
Если компоновщик находит общую библиотеку (также называемую динамической библиотекой) libfoo.so
тогда компоновщик просто вставляет ссылку на имя библиотеки libfoo.so в вашу программу (конечно, детали более сложные, чем эта, но это общая идея). Это делает вашу программу меньше, но это означает, что во время выполнения нужна не только ваша программа, но и общая библиотека, иначе ваша программа не сможет работать.
Это называется связыванием во время выполнения, и программа, используемая для разрешения всех этих общих ссылок при запуске вашей программы, называется компоновщиком во время выполнения. По очень веским причинам ссылка, которую компоновщик во время компиляции помещает в вашу программу, просто перечисляет имя библиотеки, а не полный путь к библиотеке. Это означает, что компоновщик времени выполнения должен знать, где искать общую библиотеку.
Компоновщик во время выполнения просматривает различные места, о которых можно узнать, прочитав его документацию; например, в GNU/Linux временный компоновщик называется ld.so
так что вы можете читать документы с man ld.so
,
Это сложная тема, и лучший способ сделать это зависит от ваших потребностей и потребностей.
Если вы просто хотите жестко прописать путь для поиска во время компиляции / компоновки, вы можете добавить -Rsome/dir
вариант для вашей линии связи, по одному для каждого -L
вариант, вот так:
BAMCoverage: main.cpp
g++ -I./ -I${SAMTOOLS} -I${HTSLIB} -g -O2 -Wall ./main.cpp -o ./BAMCoverage -lz -L${SAMTOOLS} -L${HTSLIB} -R${SAMTOOLS} -R${HTSLIB} -lbam -lhts
Это будет хорошо работать, пока SAMTOOLS
а также HTSLIB
каталоги существуют и до сих пор содержат правильные общие библиотеки в них. Очевидно, что это большое ограничение, но мы не можем догадаться, каковы ваши конечные требования.