web-dev-qa-db-ja.com

gppを使用してcppファイルと静的ライブラリから共有ライブラリを作成する

タイトルが言っているように、3つのcppファイルから静的ライブラリを使用して共有ライブラリを作成します。

基本的にこれをやりたい

g++ libProject.so file1.cpp file2.cpp file3.cpp -I /usr/local/include -L /usr/local/lib -lAlgatorc 

これは私のfile1.cppです:

#include <iostream>
#include <TestSetIterator.hpp>

class SortingTestSetIterator : public TestSetIterator {
public: 
    TestCase *get_current(){
         //TODO: implement method
         return nullptr; 
    }
};

これは私のfile2.cppです

#include<iostream>
#include<TestCase.hpp>
#include<Entity.hpp>
#include<ParameterSet.hpp>

class SortingTestCase : public TestCase {
public: 
    std::string print() { 
         //TODO: implement method
        return "";
    }
};

そして、これは私のfile3.cppです

#include <iostream>
#include <AbsAlgorithm.hpp>
#include "SortingTestCase.cpp"
class SortingAbsAlgorithm : public AbsAlgorithm {
private: 
    SortingTestCase Sorting_test_case;
public:
    bool init (TestCase &test) {
         //TODO: implement method
         return true; 
    }

    void run() {
         //TODO: Implement method 
    }

    void done() {
         //TODO: Implement method 
    }
};

3つの.oファイル(file1.o file2.o file3.o)を作成し、次のように結合する必要があると思います

ld -r file1.o file2.o file3.o -o file.o

File.oがあるとき、これを言う必要があると思います。

g++ -shared -o libProject.so file.o

しかし、.cppファイルを.oファイルにコンパイルする方法がわかりません。私はこのようにできることを知っています

g++ -std=gnu++11 -o file1.o -fPIC -c file1.cpp -I /usr/local/include

ただし、file1.cpp(およびその他のファイル)は/usr/local/include/TestSetIterator.hppで定義されているが/usr/local/lib/libAlgatorc.aで実装されているクラスを継承するため、このコマンドに静的ライブラリも提供する必要があります。 -cのため、-L/usr/local/lib -lAlgatorcとは言えません

最後に、主な機能でこのライブラリをプログラムにロードし、この3つのクラスからメソッドを呼び出せるように、この3つのクラスの共有ライブラリが必要です。したがって、静的ライブラリ(libAlgatorc.a)および3つのcppファイル(file1.cpp、file2.cpp、file3.cpp)のすべてのシンボルを含む共有ライブラリが必要です。

Ubuntu 12.04 x64を使用しています。

> g++ --version
g++ (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
golobich

ld -r file1.o file2.o file3.o -o file.o

ldを直接呼び出すのではなく、おそらくg++を使用してリンクする必要があります。 .oファイルをGCCに渡すと、GCCがリンカーを呼び出すため、これは機能します。

g++ file1.o file2.o file3.o -o file.o

あなたは言う:

しかし、.cppファイルを.oファイルにコンパイルする方法がわかりません。

-cでコンパイルするだけです(オブジェクトファイルを共有ライブラリに配置する場合は、-fPICも):

g++ -c file1.cpp -fPIC -o file1.o

しかし、このコマンドに静的ライブラリも提供する必要があります

いいえ、-cを含むコマンドはリンクではなくコンパイル中なので、リンク時にのみ使用されるため、ライブラリを提供することはできません。

したがって、静的ライブラリ(libAlgatorc.a)および3つのcppファイル(file1.cpp、file2.cpp、file3.cpp)のすべてのシンボルを含む共有ライブラリが必要です。

次に、すでに指摘した答えを読む必要があります: https://stackoverflow.com/a/2649792/981959

多分 An Introduction to GCC のようなunixライクな環境でのソフトウェアの構築に関するチュートリアルを読む必要があります。そうすれば、必要な個別のステップと各コマンドの動作を理解できます。

各ファイルをコンパイルするには:

g++ -c -fPIC file1.cpp
g++ -c -fPIC file2.cpp
g++ -c -fPIC file3.cpp

(ここで-oオプションは不要です。デフォルトでは、GCCはfile1.cppオプションを使用すると、file1.oなどのファイルを-cにコンパイルします。

または、1ステップでそれを行うことができます。

g++ -c -fPIC file1.cpp file2.cpp file3.cpp

できないここで-oオプションを使用します。これは、.oステップの出力として生成される3つの異なる-cファイルがあり、指定できないためです。単一の出力ファイル。

それらをすべてlibAlgatorc.aのシンボルも含む共有ライブラリにリンクするには:

g++ file1.o file2.o file3.o -shared -o libProject.so -Wl,--whole-archive libAlgatorc.a -Wl,--no-whole-archive

または、3つのファイルすべてをコンパイルしてリンクする単一のコマンドで(ここに-cオプションがないことに注意してください):

g++ -fPIC file1.cpp file2.cpp file3.cpp -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive

N.B. -I /usr/local/includeまたは-L /usr/local/includeと言うのは冗長です。これらのパスは常にデフォルトで常に検索されるためです。

より簡単なアプローチは、メイクファイルを書くことです:

libProjects.so: file1.o file2.o file3.o
        $(CXX) -shared $^ -o $@ -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive

file1.o file2.o file3.o : CXXFLAGS+=-fPIC

Makeは、入力ファイルfile1.oからfile1.cppを作成する方法をすでに知っているので、makefileで必要なすべてです(そして、.oターゲットにCXXFLAGSを設定すると、-fPICは、これらのファイルをコンパイルするときに使用されます)。これを行うための適切なコマンドに自信がないので、Makeを使用して適切なコマンドを取得することをお勧めします。

28
Jonathan Wakely