簡體   English   中英

使用 Makefile 中的頭文件編譯 Pybind(不使用 cmake)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM