La liaison C de C++ dans OS X Mavericks
Soit passé à OS X Mavericks et XCode 5.0.1, je ne peux plus gracieusement lien compilé C (fichiers de sortie de gcc) pour un projet C++ (la sortie de g++).
La délinquance de la paire de commandes de produits à partir de mon makefile:
gcc `pkg-config --cflags glib-2.0` -g -Wall -O3 `pkg-config --cflags flann` -c -o vec.o vec.c
g++ `pkg-config --cflags glib-2.0` -g -Wall -O3 -stdlib=libstdc++ -lstdc++ layoutquality.cpp vec.o `pkg-config --libs glib-2.0` -L/usr/local/Cellar/flann/1.8.4/lib -lflann -o layoutquality
À qui l'éditeur de liens se plaint:
Les symboles non définis pour l'architecture x86_64:
"load_dmat(char const*)", référencé à partir de:
_main dans layoutquality-I8HOqy.o
ld: symbole(s) ne se trouvent pas pour l'architecture x86_64
Où load_dmat
est juste une fonction dans le fichier vec.c . Si je remplace l' gcc
avec g++
dans la première ligne, puis tout se compile et des liens bien, mais clang dit:
clang: avertissement: le traitement de " c "entrée" c++", alors qu'en C++, ce comportement est déconseillé
Est-il inoffensif, non-déconseillé façon de les compiler et de les relier? La liaison avec g++
avec les fichiers objets du gcc
fonctionnait bien avant que je mis à niveau vers OS X Mavericks et les nouveaux outils de ligne de commande. Aucune information sur ce qui a changé et comment aller de l'avant serait super, merci.
extern "C"
dans la déclaration de la load_dmat
qui est compilé dans un module C++? Si non, un compilateur C++ pourrait s'attendre à une déformation du nom.Non, je ne le fais pas, où faut-il aller? Dans l'en-tête vec.h ou la source de vec.c? Cependant, j'hésite à modifier vec.* car il est utilisé par d'autres projets.
Dans l'en-tête, joignez à votre déclaration comme:
extern "C" { void load_dmat(char const*); }
. Utilisation #ifdef __cplusplus
(comme dans la réponse ci-dessous) pour maintenir les projets C intacte.Vous pouvez remplacer "gcc" avec "bruit" et "g++" avec "clang++" de toute façon, pour obtenir dans l'habitude de ne pas utiliser obsolète les liens symboliques à clang.
Ne pense pas que c'est le nom d'amputation. Voir ma réponse à @Inspiré
OriginalL'auteur stephen f | 2013-10-28
Vous devez vous connecter pour publier un commentaire.
L'ajout d'un "-x c" (sans les guillemets) avant de "vec.c" devrait résoudre le problème.
Si vous compiler plusieurs .c/.cpp les fichiers dans la même ligne que vous pouvez utiliser l'option "-x c" ou "-x c++" avant chaque liste de C ou de C++ les noms de fichiers à changer le contexte de façon appropriée. Par exemple:
error: invalid argument '-std=c++11' not allowed with 'C/ObjC'
maintenant. Est il possible de le faire en une ligne, construire avec les deux c++ et c fichiers, en précisant le c++11?Non, je ne connais pas de moyen de le faire en une ligne, g++ construire avec un fichier C et C++ 11 fichier, bien que la compilation d'un niveau intermédiaire .o fichiers et de les relier entre eux doivent travailler.
OriginalL'auteur AbePralle
Voici un exemple
Makefile
qui nous permettent d'utiliserC++
code/fonction dans unC
programme.Comme vous pouvez le voir, nous générons nos objets séparément à l'aide d'
CXXFLAGS
etCFLAGS
dans deux appels distincts pour le compilateur. Dans le contexte de Mac avec Xcode est clang, clang (CC
) et clang++ (CXX
) sont en fait la même chose. Seules les différents drapeaux de la matière. Je suis juste d'être pointilleux en précisant les définitions deCC
etCXX
dans l'exemple ci-dessusMakefile
.Une fois que l'objet de fichiers sont générés, nous sommes bons pour aller à les relier ensemble.
Noter, cependant, que vous avez à faire une étape supplémentaire pour rendre votre
C++
code utilisable par le programme C.Dans
CPP.h
dans cet exemple, vous devez utiliser explicitementextern "C"
pour spécifier lien pour votreC++
code pour une utilisation parC
.Par exemple, comme ceci:
Les macros du préprocesseur
#ifdef __cplusplus
et#endif
sont à faire en sorte que notre fichier d'en-tête ne cause pas de C-mode d'erreurs de compilation et n'est en effet au cours de C++en mode de compilation.Cet exemple complet comprend seulement 4 fichiers.
La
Makefile
source etCPP.h
sont expliqués ci-dessus.Pour une compréhension complète, je suis notamment
main.c
etCPP.cpp
ici.main.c
:CPP.cpp
:J'espère que cette explication et un exemple pour illustrer la façon dont nous pouvons mettre en place notre
Makefile
, spécifiez le#ifdef __cplusplus
macro préprocesseur etextern "C"
lien déclaration de permettre à C++-C interop, et sans erronée clang avertissement lorsque nous lancer make.OriginalL'auteur Calvin Cheng
Le plus probablement vous êtes une victime de Name mangling. Pour éviter l'amputation des noms en C++, l'utilisation
extern "C"
autour des déclarations comme: l'Merci pour le pointeur vers le nom de déformation, mais malheureusement, cela ne résout pas le problème. J'ai ajouté le modifier à ma vec.h et l'éditeur de liens d'erreur persiste.
OriginalL'auteur Inspired