web-dev-qa-db-fra.com

"référence non définie" lors de la liaison avec une bibliothèque statique

g ++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5

J'ai la bibliothèque statique suivante appelée sdpAPI.a. J'ai des problèmes pour essayer de le lier à mon application de test. Je me demande juste si je fais quelque chose de mal. La bibliothèque statique a été construite avec g ++;

Mon répertoire est le suivant:

/projects/unit_test/main.c
/projects/unit_test/sdp/inc/sdpAPH.h
/projects/unit_test/sdp/lib/sdpAPI.a

Mon code source est le suivant:

#include <stdio.h>

#include "sdpAPI.h"

int main(void)
{
    printf("----- TEST SDP ------\n");

    try {
        sdpSessionDescription sdp;
        sdp.clear();
    }
    catch(...) {
        printf("----- TEST FAILED --------\n");
        return 0;
    }

    printf("------ TEST SUCCESSFULL ------\n");

    return 0;
}

Et mon Makefile est le suivant:

OBJECT_FILES = main.o
CC = g++
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0
TARGET = sdp_demo

INC_PATH = -I sdp/inc
LIB_PATH = -L sdp/lib/sdpAPI.a

$(TARGET): $(OBJECT_FILES)
 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)

main.o: main.c
 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c

clean:
 rm -f $(TARGET) $(OBJECT_FILES) *~

Ce sont les erreurs de l'éditeur de liens que j'obtiens:

undefined reference to `sdpSessionDescription::sdpSessionDescription()'
undefined reference to `sdpSessionDescription::clear()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'

Merci beaucoup pour toutes suggestions,

25
ant2009

-L Spécifie la bibliothèque chemin, pas une bibliothèque spécifique. Vous voulez probablement que -L sdp/lib -l sdpAPI Spécifie à la fois le chemin et le nom de la bibliothèque.

Bien qu'il essaiera de préfixer et de postfixer le nom de votre bibliothèque avec lib et soit .a Soit .sl (Ou similaire).

Vous devrez peut-être également renommer votre bibliothèque en libsdpAPI.a Conformément à la page de manuel gcc:

-l xyz
L'éditeur de liens recherche une liste standard de répertoires pour la bibliothèque, qui est en fait un fichier nommé libxyz.a.


Gardez également à l'esprit que l'ordre des choses dans la ligne de commande est important. En faisant $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (bibliothèques avant les objets), il n'y a pas de symboles non résolus au point où vous listez la bibliothèque, donc rien ne sera importé de cette bibliothèque.

Ensuite, lorsque vous apportez enfin les objets (avec leurs symboles non résolus), ils restent non résolus car il n'y a pas de bibliothèques répertoriées après cela.

Vous devriez généralement faire des bibliothèques après des objets:

$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET)

pour vous assurer que tous les symboles non résolus sont connus avant de vérifier les bibliothèques.

Cela n'attrapera pas tous les problèmes (tels que les bibliothèques co-dépendantes qui peuvent être corrigées par d'autres moyens) mais cela garantira que tous les symboles non résolus dans les fichiers objet sont connus avant de regarder les bibliothèques.

De la même section de la page de manuel citée ci-dessus:

Cela fait une différence où, dans la commande, vous écrivez cette option; l'éditeur de liens recherche et traite les bibliothèques et les fichiers d'objets dans l'ordre où ils sont spécifiés. Ainsi, foo.o -lz bar.o Recherche dans la bibliothèque z après le fichier foo.o Mais avant bar.o. Si bar.o Fait référence à des fonctions dans z, ces fonctions peuvent ne pas être chargées.

44
paxdiablo
  • -L est utilisé pour spécifier un chemin de bibliothèque :

    -LdirAjouter le répertoire du répertoire à la liste des répertoires à rechercher -l.

  • -l est ce dont vous avez besoin pour spécifier la bibliothèque avec laquelle effectuer le lien:

    -l bibliothèque Rechercher la bibliothèque nommée bibliothèque lors de la liaison.

Vous avez probablement besoin de -L sdp/lib/ -l sdpAPI

10
icecrime

Comment exactement les différentes options en particulier -l et -static fonctionnaient m'ont longtemps dérouté. Enfin, un homme gcc a obtenu plus de détails que je n'ai pas pu trouver en ligne. J'espère que cela aide aussi quelqu'un d'autre

-llibrary -l bibliothèque Recherche la bibliothèque nommée bibliothèque lors de la liaison. (La deuxième alternative avec la bibliothèque comme argument séparé est uniquement pour la conformité POSIX et n'est pas recommandée.)

       It makes a difference where in the command you write this option;
       the linker searches and processes libraries and object files in the
       order they are specified.  Thus, foo.o -lz bar.o searches library z
       after file foo.o but before bar.o.  If bar.o refers to functions in
       z, those functions may not be loaded.

       The linker searches a standard list of directories for the library,
       which is actually a file named liblibrary.a.  The linker then uses
       this file as if it had been specified precisely by name.

       The directories searched include several standard system
       directories plus any that you specify with -L.

       Normally the files found this way are library files---archive files
       whose members are object files.  The linker handles an archive file
       by scanning through it for members which define symbols that have
       so far been referenced but not defined.  But if the file that is
       found is an ordinary object file, it is linked in the usual
       fashion.  The only difference between using an -l option and
       specifying a file name is that -l surrounds library with lib and .a
       and searches several directories.

-static Sur les systèmes qui prennent en charge la liaison dynamique, cela empêche la liaison avec les bibliothèques partagées. Sur d'autres systèmes, cette option n'a aucun effet.

       This option will not work on Mac OS X unless all libraries
       (including libgcc.a) have also been compiled with -static.  Since
       neither a static version of libSystem.dylib nor crt0.o are
       provided, this option is not useful to most people.

-Ldir Ajouter le répertoire dir à la liste des répertoires à rechercher -l.

2
mna

Trois drapeaux à connaître:

-Ldir -lLIB -statique

Puisque vous souhaitez créer un lien avec une bibliothèque statique, vous avez besoin du troisième indicateur. Sinon, vous vous retrouverez avec une liaison avec une bibliothèque dynamique.