编写生成文件以生成动态库

Writing a makefile to build dynamic libraries

本文关键字:动态 文件      更新时间:2023-10-16

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

我尝试了以下语法:

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.

谢谢

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

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

请注意,当我在这种情况下说"通配符"时,此通配符将目标与先决条件匹配,而不是像* glob 表达式中那样与文件系统匹配。


此外,虽然您的 hart 在正确的位置,但作为风格问题,您的 Makefile 可以更好:

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

你需要类似的东西

对象 = ...all: ${BIN}main ${SOBJECTS}     ...

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

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

除此之外,还有其他

风格点我会做不同的事情,但目前它们不会立即引起问题,所以我不会跑题,但我建议你看看一些教程,看看事情通常是如何完成的。
首先,看看Paul的Makefiles规则,以及如何不使用VPATH。