web-dev-qa-db-fra.com

Créer une bibliothèque partagée à partir de fichiers cpp et d'une bibliothèque statique avec g ++

Tout comme le titre le dit, je veux créer une bibliothèque partagée à partir de trois fichiers cpp et avec une bibliothèque statique.

Fondamentalement, je veux le faire

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

Voici mon fichier1.cpp:

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

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

Ceci est mon fichier2.cpp

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

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

Et voici mon fichier3.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 
    }
};

Je pense que je dois créer trois fichiers .o (file1.o file2.o file3.o) puis les combiner comme ceci

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

Quand j'ai file.o, je suppose que je dois dire ceci:

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

mais je ne sais pas comment compiler des fichiers .cpp en fichiers .o. Je sais que je peux le faire comme ça

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

mais je dois également fournir une bibliothèque statique à cette commande, car file1.cpp (et d'autres fichiers) hérite de la classe définie dans /usr/local/include/TestSetIterator.hpp mais implémentée dans /usr/local/lib/libAlgatorc.a À cause de -c, je ne peux pas dire -L/usr/local/lib -lAlgatorc

À la fin, je veux une bibliothèque partagée de ces trois classes afin que dans la fonction principale je puisse charger cette bibliothèque dans mon programme et que je puisse appeler des méthodes de ces trois classes. Donc, je veux une bibliothèque partagée avec tous les symboles de la bibliothèque statique (libAlgatorc.a) et des trois fichiers cpp (file1.cpp, file2.cpp et file3.cpp)

J'utilise 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 fichier1.o fichier2.o fichier3.o -o fichier.o

Vous devriez probablement utiliser g++ pour lier, pas appeler ld directement. Qui passe .o les fichiers vers GCC le feront invoquer l'éditeur de liens pour vous, donc cela fonctionne:

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

Vous dites:

mais je ne sais pas comment compiler des fichiers .cpp en fichiers .o.

Vous venez de compiler avec -c (et si vous souhaitez placer le fichier objet dans une bibliothèque partagée, alors également -fPIC):

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

mais je dois également fournir une bibliothèque statique à cette commande

Non, car une commande avec -c est en cours de compilation, pas de liaison, vous ne pouvez donc pas fournir de bibliothèques car elles ne sont utilisées que lors de la liaison.

Donc, je veux une bibliothèque partagée avec tous les symboles de la bibliothèque statique (libAlgatorc.a) et des trois fichiers cpp (file1.cpp, file2.cpp et file3.cpp)

Ensuite, vous devez lire la réponse que je vous ai déjà indiquée: https://stackoverflow.com/a/2649792/981959

Peut-être que vous devriez lire un tutoriel sur la construction de logiciels dans des environnements de type Unix, peut-être quelque chose comme An Introduction to GCC afin de comprendre les différentes étapes nécessaires et ce que fait chaque commande.

Pour compiler chaque fichier:

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

(vous n'avez pas besoin du -o options ici, par défaut GCC compilera un fichier tel que file1.cpp en file1.o lorsque vous utilisez le -c option.)

Alternativement, vous pouvez le faire en une seule étape:

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

Vous ne pouvez pas utiliser le -o option ici, car il existe trois .o fichiers produits en sortie du -c étape, vous ne pouvez donc pas spécifier un seul fichier de sortie.

Pour les lier tous dans une bibliothèque partagée qui comprend également les symboles de libAlgatorc.a:

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

Ou dans une seule commande qui compilera les trois fichiers, puis les liera (notez qu'il n'y a pas de -c option ici):

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

N.B. il est redondant de dire -I /usr/local/include ou -L /usr/local/include parce que ces chemins sont toujours recherchés par défaut de toute façon.

Une approche plus simple consiste à écrire un makefile:

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

C'est tout ce dont vous avez besoin dans le makefile, car Make sait déjà comment créer file1.o depuis l'entrée file1.cpp (et en définissant CXXFLAGS pour le .o cibles garantit que -fPIC sera utilisé lors de la compilation de ces fichiers). Étant donné que vous n'êtes pas sûr des bonnes commandes pour ce faire, je vous suggère de vous fier à Make pour le faire pour vous.

28
Jonathan Wakely