在makefile中创建库文件并在之后进行编译

时间:2012-03-06 22:57:41

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

我的问题相当简单但我不知道如何解决它。如果我没有使用make文件,我知道如何编译和库并链接它,因为那时我可以单独调用ar,一切顺利。

无论如何,我使用的是petsc库,而且我使用的是makefile:

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没有这样的文件或目录。< / p>

所以它甚至不能为我生成一个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

我确实改变了路径,但我想这表明其他类型的问题,因为即使我键入&#34; g ++ -shared -Wl,-soname,libmyclass.so.1 -o libmyclass.so.1.0 MyClass的.o&#34;或&#34; g ++ -fPIC -share ...&#34;我会得到同样的错误。

2 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:1)

使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