Создание файла библиотеки в makefile и компиляция после этого
Моя проблема довольно проста, но я просто не знаю, как ее решить. Я знаю, как компилировать и библиотековать и ссылаться на него, если я не использую make-файл, потому что тогда я могу просто вызывать ar отдельно, и все идет хорошо.
В любом случае я использую библиотеку petsc и использую make-файл, который они предоставили:
CFLAGS =
FFLAGS =
CPPFLAGS =
FPPFLAGS =
LOCDIR = /home/user/.../.../ # Working folder
EXAMPLESC = main.cpp class.cpp #.cpp file names here
EXAMPLESF =
#MANSEC = Mat I don't know what this is but it seems to work without it.
include ${PETSC_DIR}/conf/variables
include ${PETSC_DIR}/conf/rules
myProgram: main.o class.o chkopts
-${CLINKER} -o myProgram main.o class.o ${PETSC_MAT_LIB}
${RM} main.o class.o
include ${PETSC_DIR}/conf/test
ARFLAGS будет -rv по умолчанию, поэтому где я должен предоставить такую информацию, как
ar -rv libclassdll.a class.o
и куда мне добавить -L./-lclassdll?
Я довольно новичок с make-файлами, поэтому я немного потерян здесь:<
Я пытался изменить строку на
myProgram: main.o class.o chkopts
-${CLINKER} -o myProgram main.o class.o ${AR} libclassdll.a class.o ${PETSC_MAT_LIB}
${RM} main.o class.o
и затем моя команда компиляции выглядит как mpicxx -o myProgram main.o class.o /usr/bin/ar/ libclassdll.a class.o -L (здесь много ссылок) и по крайней мере она говорит: g++ classdll.a нет такого файла или реж.
Так что он не генерирует даже файл lib для меня. Так что любые идеи будут по достоинству оценены.
Новая проблема, когда я загрузил make-файл на другой компьютер, мой текущий make-файл выглядит так
LibMyClass.so: MyClass.o chkopts
-${CLINKER} -shared -Wl,-soname,${SONAME} -o ${VERS} *.o ${PETSC_MAT_LIB}
mv ${VERS} ${LIBADD}
ln -sf ${LIBADD}${VERS} ${LIBADD}${SOWOV}
ln -sf ${LIBADD}${VERS} ${LIBADD}${SONAME}
Это работает на одной машине, но другая машина дает следующую ошибку
/usr/bin/ld: MyClass.o: relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
MyClass.o: could not read symbols: Bad value
Конечно, я изменил пути, но, думаю, это указывает на другие проблемы, потому что даже если я наберу "g++ -shared -Wl,-soname,libmyclass.so.1 -o libmyclass.so.1.0 MyClass.o" или "g++ -fPIC -share... "Я получу ту же ошибку.
2 ответа
В идеале вы должны сначала создать библиотеку, а затем использовать ее так же, как "вручную".
Чтобы создать (или обновить) библиотеку, вам нужно правило примерно так:
libclassdll.a: class.o
ar -rv libclassdll.a class.o
Или более кратко, как это:
libclassdll.a: class.o
ar $(ARFLAGS) $@ $^
Тогда правило для myProgram
будет выглядеть так:
# Assuming CLINKER is something civilized, like gcc
myProgram: main.o libclassdll.a chkopts
-${CLINKER} -o myProgram main.o -L. -lclassdll ${PETSC_MAT_LIB}
или лучше:
myProgram: main.o libclassdll.a chkopts
-${CLINKER} -o $@ $< -L. -lclassdll ${PETSC_MAT_LIB}
Таким образом, в вашем make-файле вы должны заменить
myProgram: main.o class.o chkopts
-${CLINKER} -o myProgram main.o class.o ${PETSC_MAT_LIB}
${RM} main.o class.o
с
myProgram: main.o libclassdll.a chkopts
-${CLINKER} -o $@ $< -L. -lclassdll ${PETSC_MAT_LIB}
libclassdll.a: class.o
ar $(ARFLAGS) $@ $^
Вы можете внести другие улучшения, но этого должно быть достаточно.
Сделайте myProgram зависимым от main.o и libclass.a (не называйте это libclassdll.a; это не DLL, а статическая библиотека).
Общая суть решения:
# $@ means "the target of the rule"
# $^ means "the prerequisites: main.o and libclass.a"
myProgram: main.o libclass.a
$(CC) -o $@ $^ # additional arguments for other libraries, not built in this make
libclass.a: class.o
# your $(AR) command goes here to make the library