[英]What is the difference between using a Makefile and CMake to compile the code?
[英]Compile Pybind with header files in Makefile (not using cmake)
我正在嘗試用C++
編譯一個Pybind11
模塊,它在頂部調用幾個頭文件(.h)
。 由於我有很多頭文件,我決定做一個Makefile
,它可以正常工作,除了用於創建目標共享對象文件(so)
。 我需要這個共享對象文件才能在 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 <...>
之間的區別,但在所有編譯器中,我熟悉包含的<>
語法通常意味着,“這是一個系統-類型頭文件”和""
語法的意思是“這是一個本地類型的頭文件”。
在實踐中,這通常意味着在工作目錄中查找""
,然后在編譯器的-I
選項指定的目錄中,最后在系統默認目錄中查找,而<>
是相同的,只是它不在工作目錄中查找。
因此,您要么需要更改代碼以使用:
#include "population.h"
否則你需要添加-I.
到您的編譯行,以便編譯器知道查看當前目錄:
population.o: population.cpp population.h organism.h
g++ -I. -c population.cpp
就我個人而言,我會兩者都做,因為將您需要的目錄添加到編譯行是一種很好的做法,而且因為使用""
作為本地標頭是一種很好的做法,因此閱讀代碼的人會立即明白這是您的標頭而不是系統標頭.
對於您的第二個問題,編譯是否是為了使目標文件正確的共享目標文件我很抱歉,但我不明白您在問什么。
如果您詢問在 makefile 中定義的目標的順序,那么它們可以是任何順序,除了第一個目標將是默認目標(如果您運行沒有目標名稱的make
,那么 make 將構建第一個目標-- 以及第一個目標所需的任何先決條件)。
預計到達時間
好的,現在我們可以看到實際的錯誤是example.o
不存在。 為什么它不存在? 同樣,因為您已從問題中的示例中刪除了重要細節,我們無法確定。 當你寫下你的問題時:
example.so: //some .o files which are not important// HERE IS THE PROBLEM
作為example.so
先決條件出現的.o
文件究竟是什么?
你必須列出文件example.o
作為的前提example.so
如果你想make來構建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
它們在先決條件列表中出現的順序無關緊要,但它們必須全部存在。
經過幾個小時的閱讀、嘗試,也感謝 MadScientist 的提示,我讓它工作了,但原因仍然不清楚。 我只是通過將-shared -o example.so
放在前面而不是行尾來更改目標編譯中先決條件的順序,並且它起作用了。 整個文件如下:
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++ -shared -o 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
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 `python3 -m pybind11 --includes` -fPIC -c example.cpp
clean:
rm *.o *.so
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.