简体   繁体   English

编写makefile以构建动态库

[英]Writing a makefile to build dynamic libraries

I have a makefile in my src directory. 我的src目录中有一个makefile。 The makefile should build the data structures, which are in DataStructures/, and then iterate over all cpp files in calculations/ and create a corresponding .so file in ../bin/calculations Makefile应该构建DataStructures /中的数据结构,然后遍历Calculations /中的所有cpp文件,并在../bin/calculations中创建相应的.so文件。

I tried the following syntax: 我尝试了以下语法:

DAST = DataStructures/ 
COMPS = computations/ 
BIN = ../bin/ 
OBJECTS = ${DAST}Atom.o ${DAST}Molecule.o
COMPILE = g++ -Wall -g -c -std=c++0x -I/usr/local/include/openbabel-2.0 LINK = g++ -Wall -g -std=c++0x ${OBJECTS} -lopenbabel -I/usr/local/include/openbabel-2.0

all: ${BIN}main ${DAST}Molecule.o ${DAST}Atom.o ${BIN}${COMPS}%.so

${BIN}main: ${OBJECTS} main.cpp
    ${LINK} main.cpp -o ${BIN}main

${DAST}Molecule.o: ${DAST}Molecule.h ${DAST}Molecule.cpp    
    ${COMPILE} ${DAST}Molecule.cpp -o ${DAST}Molecule.o

${DAST}Atom.o: ${DAST}Atom.h ${DAST}Atom.cpp
    ${COMPILE} ${DAST}Atom.cpp -o ${DAST}Atom.o

${BIN}${COMPS}%.o: ${COMPS}%.cpp
    gcc -Wall -fPIC -c -lopenbabel $< -I/usr/local/include/openbabel-2.0 -std=c++0x

${BIN}${COMPS}%.so: ${COMPS}%.o
    gcc -shared -Wl,-soname,libcsmtest.so.1 -o libcsmtest.so $@

clean:
    rm -rf ${OBJECTS}

.PHONY: all clean

But it obviously doesn't work, as I get the following output: 但这显然不起作用,因为我得到以下输出:

shai@ubuntu:~/csm/csm2/src$ make all
make: *** No rule to make target `../bin/computations/%.so', needed by 'all'.  Stop.

thanks 谢谢

You need to specify in the all: target, the prerequisites explicitly. 您需要在all:目标中明确指定前提条件。

In Makefile parlance, % is a wildcard that can be used in automatic rules. 用Makefile的话来说,%是通配符,可以在自动规则中使用。 However, the all: target is a simple target with no such wildcard, thus ${BIN}${COMPS}%.so is wrong in that context. 但是, all:目标是没有这种通配符的简单目标,因此${BIN}${COMPS}%.so在这种情况下是错误的。

Please note that when I say 'wildcard' in this context, this wildcard matches the target against the prerequisites, not against the filesystem like * do in glob expressions. 请注意,当我在这种情况下说“通配符”时,该通配符将先决条件与目标匹配,而不是像glob表达式中的* do那样匹配文件系统。


Also, while your hart is in the right place, as a matter of style, your Makefile can be better: 同样,当您的位置合适时,就样式而言,Makefile会更好:

  • Intermediary objects, should not be prerequisites of the all target, but only the final targets you wish to ship. 中间对象不应作为all目标的先决条件,而应仅是您希望交付的最终目标。
  • There is a mix of automatic and simple rules to specify the creation of objects. 有自动和简单规则的混合来指定对象的创建。
  • Typically one doesn't write an automatic rule for %.so , because a library is often constructed from more than one object. 通常,不会为%.so编写自动规则,因为一个库通常是由多个对象构成的。
  • The dependencies between an object and header files is a complex issue. 对象和头文件之间的依赖关系是一个复杂的问题。 In short you need to specify that the resulting object depends on the *.cpp (or .c ) as well as all the headers included (directly and indirectly) by the *.cpp file. 简而言之,您需要指定结果对象取决于*.cpp (或.c )以及*.cpp文件包含的所有标头(直接和间接)。
  • By convention, that is well supported by GNU make, instead of using ${COMPILE} as you do, one should use $(CXX) for your C++ compiler, and $(CXXFLAGS) for the standard flags you wish to pass to that compiler. 按照惯例,GNU make很好地支持了这一点,而不是像您那样使用${COMPILE} ,应该将$(CXX)用于C ++编译器,将$(CXXFLAGS)用于您希望传递给该编译器的标准标志。

You need something like 你需要类似的东西

SOBJECTS = ...

all: ${BIN}main ${SOBJECTS}
     ...

You need a way to gather all the *.so names in the variable SOBJECTS . 您需要一种方法来收集变量SOBJECTS中的所有* .so名称。 You can do this manually, or use some of make 's internal functions to scan the source directory. 您可以手动执行此操作,也可以使用make的一些内部函数来扫描源目录。

Also notice that I removed the two *.o files as dependencies from the all target. 还要注意,我从all目标中删除了两个*.o文件作为依赖项。 They are not final goals of the build (I assume), so you don't need to mention them there. 它们不是构建的最终目标(我认为),因此您无需在其中提及它们。

Besides this there are other stylistic points which I would do differently, but at the moment they are not causing immediate problems, so I won't digress, but I advise you to have a look at some tutorials to see how things are done generally. 除此之外,还有其他风格上的问题,我将采取不同的方式,但是目前它们不会引起直接的问题,因此我不会偏离主题,但我建议您看一下一些教程以了解总体上的工作方式。
For starters, look at Paul's Rules of Makefiles , and How Not to Use VPATH . 首先,请看Paul的Makefile规则 ,以及如何不使用VPATH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM