c++ - 在 makefile 中创建一个库文件,然后编译

标签 c++ makefile g++ mpic++

我的问题相当简单,但我就是不知道如何解决。如果我不使用 make 文件,我知道如何编译、库和链接它,因为那样我就可以单独调用 ar,一切正常。

反正我用的是petsc库,我正在使用他们提供的生成文件:

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 ?

我是 makefile 的菜鸟,所以我在这里有点迷路:<

我试图将行更改为

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 文件。所以任何想法都会非常感激。

当我在不同的机器上上传makefile时出现了一个新问题,我当前的makefile是这样的

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...”我会得到同样的错误。

最佳答案

理想情况下,您应该先构建库,然后再使用它,就像“手动”一样。

要构建(或更新)库,您需要这样的规则:

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}

因此在您的 makefile 中,您将替换

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) $@ $^

您还可以进行其他改进,但现在应该足够了。

关于c++ - 在 makefile 中创建一个库文件,然后编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9593286/

相关文章:

vim - ctags 无法找到包含连字符的变量

C++20:自动生成的运算符在派生类中不可引用?

c++ - Boost 1.64 在 solaris 上构建错误

c++ - 有限空间内存

c++ - 构建 obj 和 exe 文件的最佳目录结构是什么?

c - 使用 getopt() 查找目标

c++ - 字符串文字连接的正确行为(C++11 翻译的第 6 阶段)

c++ - 关于 C++ 和命名管道的基本问题

c++ - 为什么这个生成随机数的代码总是产生相同的数字?

android - 针对 android 工具链上的 C++ 标准库进行编译