2012-03-06 42 views
1

我的问题很简单,但我不知道如何解决它。如果我不使用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没有这样的文件或目录。

因此,它甚至不会为我生成一个lib文件。所以任何想法都会非常感激。

当我上传生成文件在不同的机器上的一个新的问题,我现在的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-分享......“我会得到同样的错误。

+0

$ {AR}不应该在行的最开始?毕竟,这是命令,不是吗? – celtschk 2012-03-06 23:18:11

+0

您已经在链接的目标文件中包含class.o以生成程序可执行文件,因此链接由class.o创建的库也是毫无意义/多余的。 – Kaz 2012-03-06 23:18:16

+0

如果您已经使用'ar'构建了库并编译了'main.o',那么您将使用什么命令将它们链接在一起并构建'myProgram'? – Beta 2012-03-06 23:21:24

回答

3

理想情况下,你应该先构建库,然后用它,就像你“手动”。

构建(或更新)库中,你需要一个规则是这样的:

libclassdll.a: class.o 
    ar -rv libclassdll.a class.o 

或者更简洁,就像这样:

libclassdll.a: class.o 
    ar $(ARFLAGS) [email protected] $^ 

然后为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 [email protected] $< -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 [email protected] $< -L. -lclassdll ${PETSC_MAT_LIB} 

libclassdll.a: class.o 
    ar $(ARFLAGS) [email protected] $^ 

还有其他的改进可以使,但应该现在就足够了。

+0

非常感谢! – Mare 2012-03-07 18:09:27

+0

由于某种原因,我仍然在编译时遇到以下错误: 对MyClass :: Class :: Function()的未定义引用... 我已经搜索了许多使用lib之外的函数的方法,现在我关注http://msdn.microsoft.com/en-us/library/ms235627.aspx所以我的链接仍然有问题吗? – Mare 2012-03-07 21:51:48

+0

或者我应该以某种方式创建dll,如http://msdn.microsoft.com/en-us/library/ms235636.aspx? – Mare 2012-03-07 22:31:40

1

使myProgram取决于main.o和libclass.a(不要称之为libclassdll.a;它不是一个DLL,而是一个静态库)。

解决方案的总要点:

# [email protected] means "the target of the rule" 
# $^ means "the prerequisites: main.o and libclass.a" 

myProgram: main.o libclass.a 
     $(CC) -o [email protected] $^ # additional arguments for other libraries, not built in this make 

libclass.a: class.o 
     # your $(AR) command goes here to make the library 
+0

感谢您的澄清。 – Mare 2012-03-07 18:09:48

相关问题