编写makefile来构建动态库

时间:2011-04-06 11:55:13

标签: c++ makefile dynamic-linking

我的src目录中有一个makefile。 makefile应构建数据结构,这些数据结构位于DataStructures /中,然后迭代计算中的所有cpp文件,并在../ bin / computation中创建相应的.so文件

我尝试了以下语法:

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

但它显然不起作用,因为我得到以下输出:

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

感谢

2 个答案:

答案 0 :(得分:2)

您需要在all:目标中明确指定先决条件。

在Makefile中,%是一个可以在自动规则中使用的通配符。但是,all:目标是一个没有这种通配符的简单目标,因此${BIN}${COMPS}%.so在该上下文中是错误的。

请注意,当我在此上下文中说'wildcard'时,此通配符会根据先决条件匹配目标,而不是像glob表达式中*那样的文件系统。


此外,虽然你的哈特是在正确的地方,但作为一种风格,你的Makefile可以更好:

  • 中介对象不应是all目标的先决条件,而应仅是您希望发布的最终目标。
  • 有自动和简单规则的混合来指定对象的创建。
  • 通常,人们不会为%.so编写自动规则,因为库通常由多个对象构成。
  • 对象和头文件之间的依赖关系是一个复杂的问题。简而言之,您需要指定生成的对象取决于*.cpp(或.c)以及*.cpp文件包含的所有标头(直接和间接)。
  • 按照惯例,GNU make很好地支持,而不是像你一样使用${COMPILE},你应该使用$(CXX)作为C ++编译器,$(CXXFLAGS)作为标准标记你希望传递给那个编译器。

答案 1 :(得分:1)

你需要像

这样的东西
SOBJECTS = ...

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

您需要一种方法来收集变量SOBJECTS中的所有* .so名称。您可以手动执行此操作,也可以使用make的某些内部函数来扫描源目录。

另请注意,我从*.o目标中删除了两个all文件作为依赖项。它们不是构建的最终目标(我假设),因此您不需要在那里提及它们。

除了这个还有其他风格点,我会做不同的,但目前它们不会造成直接问题,所以我不会离题,但我建议你看看一些教程,看看事情是怎样的一般地完成。
首先,请查看Paul's Rules of MakefilesHow Not to Use VPATH