2015-07-21 10 views
7

Tak jak mówi tytuł, chcę utworzyć bibliotekę współdzieloną z trzech plików cpp iz pewną biblioteką statyczną.Utwórz bibliotekę współdzieloną z plików cpp i biblioteki statycznej za pomocą g ++

Basicly chcę zrobić to

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

To mój file1.cpp:

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

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

To mój 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 ""; 
    } 
}; 

A to moja plik3. 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 
    } 
}; 

myślę, że trzeba utworzyć trzy .o plików (file1.o file2.o file3.o), a następnie połączyć je jak ten

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

Kiedy mam file.o Przypuszczam, że wtedy muszę powiedzieć:

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

, ale nie wiem jak skompilować pliki .cpp do plików .o. wiem, że mogę to zrobić jak ten

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

ale muszę również bibliotekę statyczną do tego polecenia, ponieważ file1.cpp (i inne pliki) dziedziczy klasę, która jest zdefiniowana w/usr/local/include/TestSetIterator .hpp, ale jest zaimplementowana w /usr/local/lib/libAlgatorc.a Z powodu -c nie mogę powiedzieć -L/usr/local/lib -lAlgatorc

Na koniec chcę udostępnić bibliotekę tych trzech klasy tak, że w głównej funkcji mogę załadować tę bibliotekę do mojego programu i mogę wywołać metody z tych trzech klas. Tak więc chcę udostępnić bibliotekę ze wszystkimi symbolami z biblioteki statycznej (libAlgatorc.a) i ze wszystkich trzech plików cpp (file1.cpp, file2.cpp i file3.cpp)

Używam 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

Czy to nie jest dup pytanie, które już wskazałem? http://stackoverflow.com/questions/2649735/how-to-link-static-library-into-dynamic-library-in-gcc –

+0

Nie. Nie ma wspólnej biblioteki zbudowanej z biblioteki statycznej i plików cpp. Istnieje wspólna biblioteka zbudowana tylko z biblioteki statycznej. Chcę to połączyć. – golobich

+0

Nadal jest w zasadzie taki sam. Po prostu dodaj do tego polecenia pliki '.o' w tej odpowiedzi. Chodzi o to, że druga odpowiedź pokazuje, jak zapewnić, by wszystkie symbole z biblioteki statycznej trafiły do ​​wspólnej biblioteki, co jest dokładnie twoim problemem. –

Odpowiedz

14

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

Powinieneś raczej użyć g++ połączyć, nie zadzwonić ld bezpośrednio. Przechodząc .o pliki do GCC spowoduje to, aby wywołać łącznik dla ciebie, tak to działa:

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

Mówisz:

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

po prostu skompilować z -c (a jeśli chcesz umieścić obiekt złożyć w udostępnionej biblioteki następnie również -fPIC):

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

but I must also provide static library to this command

Nie, ponieważ polecenie z -c kompiluje się, a nie łączy, więc nie można zapewnić bibliotek, ponieważ są one używane tylko podczas łączenia.

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)

Następnie trzeba przeczytać odpowiedź już wskazywano na: https://stackoverflow.com/a/2649792/981959

Może powinieneś przeczytać tutorial na oprogramowanie budynku w środowiskach UNIX-podobnych, może coś jak An Introduction to GCC aby wiedzieć, oddzielna kroki potrzebne i co każde polecenie robi.

Aby skompilować każdy plik:

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

(nie trzeba opcje -o tutaj, domyślnie GCC skompiluje plik, takich jak file1.cpp do file1.o podczas korzystania z opcji -c.)

Alternatywnie, można to zrobić w jednym kroku:

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

ty nie może użyć tutaj opcji , ponieważ istnieją trzy różne pliki .o, które zostały wygenerowane jako dane wyjściowe kroku -c, więc nie można określić pojedynczego pliku wyjściowego.

Aby połączyć je wszystkie w udostępnionej biblioteki, która obejmuje również symbole z libAlgatorc.a:

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

Albo w jednym poleceniu, które zestawiają wszystkie trzy pliki, a następnie połączyć je (uwaga nie ma -c opcja tutaj):

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

NB zbędne jest powiedzenie -I /usr/local/include lub -L /usr/local/include, ponieważ te ścieżki są zawsze przeszukiwane domyślnie.

Prostszym rozwiązaniem jest napisać makefile:

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 

to wszystko, czego potrzebujesz w makefile, bo Producent już wie, jak stworzyć file1.o z wejścia file1.cpp (i ustawienie CXXFLAGS dla .o kierowana, zapewnia podczas kompilacji tych plików zostanie użyte -fPIC). Ponieważ nie masz pewności, jakie są właściwe polecenia, sugeruję, aby Make to dobrze dla Ciebie.

+0

Jeśli zrobię to tak jak ty, otrzymam to: /usr/bin/ld : /usr/local/lib/libAlgatorc.a(ParameterSet.o): relokacja R_X86_64_32 przeciwko '.rodata.str1.1 'nie może być używana podczas tworzenia obiektu współdzielonego; rekompilacja z -fPIC /usr/local/lib/libAlgatorc.a(ParameterSet.o): nie można odczytać symboli: Bad value collect2: error: ld zwrócił 1 status wyjścia – golobich

+0

Oznacza to, że obiekty w 'libAlgator.ca' nie są relokowalne i dlatego nie mogą być używane w bibliotece współdzielonej. Musisz albo pobrać nową wersję 'libAlgatorc', gdzie zawartość jest zbudowana z' -fPIC' (może dostać '.so ') lub nie możesz tego zrobić, i będzie musiał połączyć twój główny plik wykonywalny z '-lAlgatorc' zamiast dodawać go do' libProject.so' –

+1

Znacznie lepiej! To polecenie 'g ++ -fPIC plik1.cpp plik2.cpp plik3.cpp -shared -o libProject.so -Wl, - całe-archiwum -lAlgatorc -Wl, - nie-całe-archiwum" działa jak urok! Problem dotyczył również statycznej lib. static lib nie jest skompilowany z -fPIC, ale musi tak być, ponieważ dodajemy te symbole do biblioteki współdzielonej. Idealna odpowiedź naprawdę! :) Dziękuję Ci za całą twoją pomoc! – golobich

Powiązane problemy