2015-07-21 10 views
7

Genau wie der Titel sagt, ich möchte gemeinsame Bibliothek aus drei cpp-Dateien und mit einigen statischen Bibliothek erstellen.Erstelle gemeinsam genutzte Bibliothek aus cpp-Dateien und statische Bibliothek mit g ++

Basicly Ich möchte diese

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

Das ist mein file1.cpp tun:

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

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

Das ist mein 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 ""; 
    } 
}; 

Und das ist mein 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 
    } 
}; 

Ich denke, dass ich drei .o Dateien erstellen müssen (file1.o file2.o file3.o) und dann wie diese

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

kombinieren Wenn ich file.o nehme ich an, dass dann ich brauche Um das zu sagen:

aber ich weiß nicht, wie .cpp-Dateien in O-Dateien kompilieren. Ich weiß, dass ich es wie diese

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

tun können, aber ich muß auch statische Bibliothek zu diesem Befehl liefern, weil file1.cpp (und andere Dateien) erben Klasse, die in/usr/local/include/TestSetIterator definiert ist .hpp aber ist in /usr/local/lib/libAlgatorc.a implementiert. Wegen -c kann ich nicht sagen -L/usr/local/lib -lAlgatorc

Am Ende möchte ich eine gemeinsame Bibliothek dieser drei Klassen, so dass ich in der Hauptfunktion diese Bibliothek in mein Programm laden kann und Methoden aus diesen drei Klassen aufrufen kann. Also, ich möchte shared library mit allen Symbolen aus der statischen Bibliothek (libAlgatorc.a) und aus allen drei cpp-Dateien (file1.cpp, file2.cpp und file3.cpp)

Ich benutze 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. 
+1

Ist das nicht eine Frage, auf die ich bereits hingewiesen habe? http://stackoverflow.com/questions/2649735/how-to-link-static-library-into-dynamic-library-in-gcc –

+0

Nein. Es gibt keine gemeinsam genutzte Bibliothek aus statischen Bibliotheken und CPP-Dateien. Es gibt eine gemeinsam genutzte Bibliothek, die nur aus einer statischen Bibliothek erstellt wird. Ich möchte das beides kombiniert. – golobich

+0

Es ist immer noch im Grunde das Gleiche. Fügen Sie einfach die '.o' Dateien zum Befehl in dieser Antwort hinzu. Der Punkt ist, dass die andere Antwort zeigt, wie sichergestellt werden kann, dass alle Symbole aus einer statischen Bibliothek in einer gemeinsam genutzten Bibliothek landen, was genau Ihr Problem ist. –

Antwort

14

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

Sie sollten wahrscheinlich g++ verwenden zu verknüpfen, ld nicht direkt aufrufen. Vorbei .o Dateien GCC wird dazu führen, dass die Linke für die Sie aufzurufen, so funktioniert das:

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

Sie sagen:

but I don't know how to compile .cpp files into .o files.

Sie kompilieren nur mit -c (und wenn Sie möchten, um das Objekt setzen Datei in einer gemeinsamen Bibliothek dann auch -fPIC):

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

but I must also provide static library to this command

Nein, weil ein Befehl mit -c kompiliert, nicht verknüpft wird. Daher können Sie keine Bibliotheken bereitstellen, da sie nur beim Verknüpfen verwendet werden.

So, I want shared library with all symbols from static library (libAlgatorc.a) and from all three cpp files (file1.cpp, file2.cpp and file3.cpp)

Dann müssen Sie die Antwort lesen Ich deutete bereits an: https://stackoverflow.com/a/2649792/981959

Vielleicht sollten Sie sich auf die Erstellung von Software in Unix-ähnlichen Umgebungen ein Tutorial lesen, vielleicht so etwas wie An Introduction to GCC, so dass Sie die separate verstehen Schritte benötigt und was jeder Befehl tut.

Um jede Datei kompilieren:

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

(Sie hier die -o Optionen nicht benötigen, werden standardmäßig GCC eine Datei wie file1.cpp in file1.o kompilieren, wenn Sie die -c Option.)

Alternativ

, können Sie, dass in einem Schritt tun:

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

Sie kann nicht verwenden Sie die -o Option hier, da gibt es drei verschiedene .o Dateien als Ausgabe des -c Schritt, so dass Sie keine einzelne Ausgabedatei angeben können.

Um sie alle in eine gemeinsame Bibliothek zu verknüpfen, die die Symbole aus libAlgatorc.a umfasst auch:

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

Oder in einem einzigen Befehl, der alle drei Dateien kompiliert und dann verknüpfen (beachten Sie, es gibt keine -c hier Option):

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

NB es ist überflüssig, -I /usr/local/include oder -L /usr/local/include zu sagen, weil diese Pfade immer standardmäßig gesucht werden.

Ein einfacher Ansatz ist es, eine Make-Datei zu schreiben:

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

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

Das ist alles, was Sie in der Make-Datei benötigen, weil Make bereits weiß, wie file1.o aus dem Eingang file1.cpp (und Einstellung CXXFLAGS für die .o Ziele sicher erstellen dass -fPIC wird beim Kompilieren dieser Dateien verwendet werden). Da Sie nicht die richtigen Befehle dafür haben, schlage ich vor, dass Sie sich auf Make verlassen, um es für Sie richtig zu machen.

+0

Wenn ich dies wie Sie getan habe, bekomme ich das: /usr/bin/ld : /usr/local/lib/libAlgatorc.a(ParameterSet.o): Verschiebung R_X86_64_32 gegen '.rodata.str1.1 'kann nicht verwendet werden, wenn ein gemeinsames Objekt erstellt wird; kompilieren Sie mit -fPIC /usr/local/lib/libAlgatorc.a(ParameterSet.o): Symbole konnten nicht gelesen werden: Ungültiger Wert Collect2: Fehler: ld gab 1 Exit-Status zurück – golobich

+0

Das bedeutet, dass die Objekte in 'libAlgator.ca' nicht verlagerbar sind und daher nicht in einer gemeinsam genutzten Bibliothek verwendet werden können. Sie müssen entweder eine neue Version von 'libAlgatorc' erhalten, wo der Inhalt mit' -fPIC' erstellt wird (vielleicht ein '.so' intead) oder Sie können dies nicht machen und müssen Ihre Haupt-Programmdatei mit verknüpfen '-lAlgatorc' anstelle von 'libProject.so' –

+1

Viel besser! Der Befehl 'g ++ -fPIC datei1.cpp datei2.cpp datei3.cpp -shared -o libProject.so -Wl, - ganzes -archiv -lAlgatorc -Wl, - kein-ganzes-Archiv' funktioniert wie ein Zauber! Problem war auch in statischen lib. static lib ist nicht mit -fPIC kompiliert, aber es muss sein, weil wir diese Symbole zur shared library hinzufügen. Perfekte Antwort wirklich! :) Danke für all deine Hilfe! – golobich

Verwandte Themen