gpt4 book ai didi

c++ - 使用 Makefile 中的头文件编译 Pybind(不使用 cmake)

转载 作者:行者123 更新时间:2023-12-02 10:21:00 31 4
gpt4 key购买 nike

我正在尝试编译 Pybind11 C++ 中的模块它调用了几个头文件(.h)在上面。由于我有很多头文件,我决定做一个 Makefile ,没有问题,除了创建目标共享对象文件(s.o) .我需要这个共享对象文件才能在 Python 中调用 Pybind 模块。

但是,在编译时,我得到:

g++ -shared -fPIC neat.o network.o nnode.o link.o trait.o gene.o innovation.o organism.o species.o genome.o population.o example.o -o example.so
/usr/bin/ld: example.o: relocation R_X86_64_PC32 against symbol `_ZTI3Pet' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'example.so' failed
make: *** [example.so] Error 1

我的问题基本上是:编译目标文件以创建目标时我做错了什么?

任何帮助将不胜感激。提前感谢您的回复。

生成文件
example.so: neat.o network.o nnode.o link.o trait.o gene.o innovation.o organism.o species.o genome.o population.o example.o
g++ neat.o network.o nnode.o link.o trait.o gene.o innovation.o organism.o species.o genome.o population.o example.o -shared -o example.so

neat.o: neat.cpp neat.h
g++ -c -O3 -Wall -fPIC neat.cpp

network.o: network.cpp network.h
g++ -c -O3 -Wall -fPIC network.cpp

nnode.o: nnode.cpp nnode.h
g++ -c -O3 -Wall -fPIC nnode.cpp

link.o: link.cpp link.h
g++ -c -O3 -Wall -fPIC link.cpp

trait.o: trait.cpp trait.h
g++ -c -O3 -Wall -fPIC trait.cpp

gene.o: gene.cpp gene.h
g++ -c -O3 -Wall -fPIC gene.cpp

innovation.o: innovation.cpp innovation.h
g++ -c -O3 -Wall -fPIC innovation.cpp

organism.o: organism.cpp organism.h genome.h genome.cpp species.h species.cpp
g++ -c -O3 -Wall -fPIC organism.cpp

species.o: species.h species.cpp organism.cpp organism.h genome.h genome.cpp
g++ -c -O3 -Wall -fPIC species.cpp

genome.o: genome.cpp genome.h
g++ -c -O3 -Wall -fPIC genome.cpp

population.o: population.cpp population.h organism.h
g++ -c -O3 -Wall -fPIC population.cpp

experiments.o: experiments.cpp experiments.h
g++ -c -O3 -Wall -fPIC experiments.cpp

example.o:
g++ -O3 -Wall -std=c++11 -fopenmp -I -fPIC `python3 -m pybind11 --includes` -c example.cpp

clean:
rm *.o *.so

示例.cpp
#include <pybind11/pybind11.h>
#include <iostream>
#include <string>
#include "population.h"

namespace py = pybind11;

int create_neat(){
Population *the_pop=0;
return 0;
}
PYBIND11_MODULE(example, m){

m.def("create_neat", &create_neat, "create a pop object");

}

最佳答案

该标准并未完全定义 #include "..." 之间的区别。和 #include <...> , 但在所有编译器中我都熟悉 <> include 的语法通常意味着“这是一个系统类型的头文件”和 ""语法意味着“这是一个本地类型的头文件”。

在实践中,这通常意味着 ""在工作目录中查找,然后在 -I 指定的目录中查找编译器的选项,最后在系统默认目录中,而 <>是相同的,只是它不在工作目录中查找。

因此,您要么需要更改代码以使用:

#include "population.h"

否则你需要添加 -I.到您的编译行,以便编译器知道在当前目录中查找:
population.o: population.cpp population.h organism.h
g++ -I. -c population.cpp

就我个人而言,我会同时做这两件事,因为将你需要的目录添加到你的编译行是很好的卫生习惯,并且因为使用 "" 是一种很好的做法。对于本地 header ,因此阅读代码的人会立即明白这是您的 header 而不是系统 header 。

对于您的第二个问题,为了使共享对象文件与对象文件正确而进行的编译很抱歉,但我不明白您在问什么。

如果您询问 makefile 中定义的目标的顺序,那么它们可以是任何顺序,除了第一个目标将是默认目标(如果您运行 make 没有目标名称,那么 make 将构建第一个目标——以及第一个目标所需的任何先决条件)。

预计到达时间

好的,现在我们可以看到实际的错误是 example.o不存在。为什么它不存在?同样,因为您已从问题示例中删除了重要细节,我们无法确定。当你写你的问题时:
example.so: //some .o files which are not important// HERE IS THE PROBLEM
.o 到底是什么显示为 example.so 的先决条件的文件?

您必须列出文件 example.o作为 example.so 的先决条件如果你想构建 example.o在尝试构建 example.so 之前.您需要列出创建共享库所需的所有目标文件。所以这应该是:
example.so: population.o example.o neat.o network.o nnode.o link.o trait.o gene.o innovation.o organism.o species.o genome.o

它们出现在先决条件列表中的顺序无关紧要,但它们都必须在那里。

关于c++ - 使用 Makefile 中的头文件编译 Pybind(不使用 cmake),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60176046/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com