在makefile中创建库文件并在此之后进行编译 [英] Creating a library file in makefile and compiling after that

查看:369
本文介绍了在makefile中创建库文件并在此之后进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

无论如何,我使用 petsc 库,我正在使用makefile提供的内容:

  CFLAGS = 
FFLAGS =
CPPFLAGS =
FPPFLAGS =
LOCDIR = / home / user /.../.../#工作文件夹
EXAMPLESC = main.cpp class.cpp#.cpp这里的文件名
EXAMPLESF =
#MANSEC = Mat我不知道这是什么,但它似乎没有它的工作。

包括$ {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的新手,所以我就是为什么在这里输了:< / p>

我试图将这一行更改为

  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没有这样的文件或dir。

所以它甚至不会生成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:重新定位R_X86_64_32S针对`.rodata'制作时无法使用共享对象;使用-fPIC 
重新编译MyClass.o:无法读取符号:错误值

我做了改变路线,但我想这表明其他类型的问题,因为即使我键入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)$ @ $ ^

然后, code> myProgram 变成:

 #假设CLINKER是文明的,比如gcc 
myProgram:main.o libclassdl l.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

with

  myProgram:main.o libclassdll.a chkopts 
- $ {CLINKER} -o $ @ $< -L。 -lclassdll $ {PETSC_MAT_LIB}

libclassdll.a:class.o
ar $(ARFLAGS)$ @ $ ^

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


My problem is fairly easy but I just don't know how to solve it. I know how to compile and library and link against it if I'm not using a make file because then I can just call ar separately and everything goes right.

Anyway I'm using a petsc library and I'm using a makefile what they provided:

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 will be -rv as a default so where should I provide such a information as

ar -rv libclassdll.a class.o

and where should I add -L./-lclassdll ?

I'm quite a rookie with makefiles so that's why I'm a bit lost here :<

I tried to change the line to

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

and then my compiling command seems to be mpicxx -o myProgram main.o class.o /usr/bin/ar/ libclassdll.a class.o -L ( a lot of linking here ) and at least it says: g++ classdll.a no such a file or dir.

So it doesn't generate even a lib file for me. So any ideas will be really appreciated.

A new problem when I uploaded makefile on the different machine, my current makefile looks like this

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}

That works on one machine but other machine gives following error

/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

I did change the paths of course but I guess that indicates other kind of problem because even if I type "g++ -shared -Wl,-soname,libmyclass.so.1 -o libmyclass.so.1.0 MyClass.o" or "g++ -fPIC -share... " I'll get the same error.

解决方案

Ideally you should construct the library first, then use it, just as you would "by hand".

To construct (or update) the library, you need a rule something like this:

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

Or more concisely, like this:

libclassdll.a: class.o
    ar $(ARFLAGS) $@ $^

Then the rule for myProgram becomes:

# Assuming CLINKER is something civilized, like gcc
myProgram: main.o libclassdll.a  chkopts
    -${CLINKER} -o myProgram main.o -L. -lclassdll ${PETSC_MAT_LIB}

or better:

myProgram: main.o libclassdll.a  chkopts
    -${CLINKER} -o $@ $< -L. -lclassdll ${PETSC_MAT_LIB}

So in your makefile, you would replace

myProgram: main.o class.o  chkopts
    -${CLINKER}  -o myProgram main.o class.o ${PETSC_MAT_LIB}
    ${RM} main.o class.o

with

myProgram: main.o libclassdll.a  chkopts
    -${CLINKER} -o $@ $< -L. -lclassdll ${PETSC_MAT_LIB}

libclassdll.a: class.o
    ar $(ARFLAGS) $@ $^

There are other refinements you can make, but that should be enough for now.

这篇关于在makefile中创建库文件并在此之后进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆