Manquant d'inclure «bits / c ++ config.h» lors de la compilation croisée d'un programme 64 bits sur 32 bits dans Ubuntu

181

J'utilise la version 32 bits d'Ubuntu 10.10 et j'essaie de croiser la compilation vers une cible 64 bits. Sur la base de mes recherches, j'ai installé le package g ++ - multilib.

Le programme est un bonjour tout simple:

#include <iostream>

int main( int argc, char** argv )
{
  std::cout << "hello world" << std::endl;
  return 0;
}

Compiler:

g++ -m64 main.cpp

Erreur:

In file included from main.cpp:1:
/usr/include/c++/4.4/iostream:39: fatal error: bits/c++config.h: No such file or directory
compilation terminated.

J'ai trouvé un c++config.hfichier , mais ils résident sous le i486-linux-gnuet i686-linux-gnurépertoires /usr/include/c++/4.4/Il n'y a pas c++config.hdans /usr/include/c++/bits.

Des idées sur ce qui me manque? La compilation sans l' -m64indicateur fonctionne correctement (a.out est créé et s'exécute correctement).

Edit Grâce à l'indication de @nightcracker, j'ai fait un peu plus d'enquête sur la structure d'inclusion sur les systèmes 32 et 64 bits. J'ai ajouté une réponse ci-dessous qui "corrige" le problème temporairement mais je pense que cela se cassera lors de la prochaine mise à jour. Fondamentalement, il me manque un répertoire appelé /usr/include/c++/4.4/i686-linux-gnu/64qui devrait contenir un sous-répertoire appelé contenant bitsle fichier include manquant. Avez-vous une idée du paquet qui devrait s'en occuper?

Jesse Vogt
la source
1
Wow ... j'ai eu ce problème aussi. GCC 4.8 sur un ARMv7-a CubieTruck (Cortex-A7) exécutant Ubuntu. La chose bizarre (pour moi) est que la réponse d'Anthony l'a corrigé. Whatever ...
jww

Réponses:

308

L'ajout de cette réponse en partie parce que cela a résolu mon problème du même problème et que je peux donc ajouter cette question moi-même.

J'ai pu résoudre ce problème en procédant comme suit:

sudo apt-get install gcc-multilib g++-multilib

Si vous avez installé une version de gcc/ g++qui n'est pas livrée par défaut (comme g++-4.8sur lucid), vous voudrez également faire correspondre la version:

sudo apt-get install gcc-4.8-multilib g++-4.8-multilib
Anthony Sottile
la source
30
Assurez-vous de faire correspondre les versions de gcc and g++installé sur votre système. Sur Ubuntu 14.04, j'avais gcc-4.8et g++-4.8installé, donc j'ai installé gcc-4.8-multilib et à la g++-4.8-multilibplace.
Zoltán
3
Cela a résolu mon problème lors de la compilation avec -m32 sur une machine 64 bits. Merci
nic
41
Merci pour le pointeur, mais sudo apt-get install gcc-multilib g++-multilibsemble mieux (il se résout automatiquement à votre version gcc).
leesei
^ peut-être pas! La suggestion de @ Zoltan a cependant fonctionné pour moi. Anthony Sottile, vous devriez peut-être intégrer le commentaire de Zoltan dans votre réponse?
Man
@Man, n'hésitez pas à suggérer une modification, lorsque je l'ai initialement publiée, je correspondais à la version posée dans la question, elle a depuis changé par rapport aux modifications des autres
Anthony Sottile
11

Avez-vous essayé d'ajouter -I/usr/include/c++/4.4/i486-linux-gnuou -I/usr/include/c++/4.4/i686-linux-gnu?

orlp
la source
Cela fonctionne vraiment. Une idée sur pourquoi j'aurais besoin de faire cela pour seulement 64 bits? J'essaie de configurer cette machine pour aider avec les versions 64 bits distribuées et je veux éviter trop de personnalisation.
Jesse Vogt
2
Je suis désolé, je n'en ai aucune idée, je viens de poser une solution de travail hacky rapide :)
orlp
5

Lors de la compilation dans RHEL 6.2 (x86_64), j'ai installé les packages libstdc ++ - dev 32 bits et 64 bits, mais j'ai eu le problème "c ++ config.h no such file or directory ".

Résolution:

Le répertoire /usr/include/c++/4.4.6/x86_64-redhat-linuxétait manquant.

J'ai fait ce qui suit:

cd /usr/include/c++/4.4.6/
mkdir x86_64-redhat-linux
cd x86_64-redhat-linux
ln -s ../i686-redhat-linux 32

Je suis maintenant capable de compiler des binaires 32 bits sur un système d'exploitation 64 bits.

Pekmez
la source
1
Sur OpenSUSE I didcd /usr/include/c++/4.6;ln -s x86_64-suse-linux i586-suse-linux
Julian
3

Semble être une erreur de frappe dans ce paquet de gcc. La solution:

mv /usr/include/c++/4.x/i486-linux-gnu /usr/include/c++/4.x/i686-linux-gnu/64
Danse Danse
la source
2

Sur mon système 64 bits, j'ai remarqué que le répertoire suivant existait:

/usr/include/c++/4.4/x86_64-linux-gnu/32/bits

Il serait alors logique que sur mon système 32 bits qui avait été configuré pour la compilation croisée 64 bits, il devrait y avoir un répertoire correspondant comme:

/usr/include/c++/4.4/i686-linux-gnu/64/bits

J'ai vérifié deux fois et ce répertoire n'existait pas. L'exécution g++avec le paramètre verbose a montré que le compilateur recherchait réellement quelque chose à cet emplacement:

jesse@shalored:~/projects/test$ g++ -v -m64 main.cpp 
Using built-in specs.
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) 
COLLECT_GCC_OPTIONS='-v' '-m64' '-shared-libgcc' '-mtune=generic'
 /usr/lib/gcc/i686-linux-gnu/4.4.5/cc1plus -quiet -v -imultilib 64 -D_GNU_SOURCE main.cpp -D_FORTIFY_SOURCE=2 -quiet -dumpbase main.cpp -m64 -mtune=generic -auxbase main -version -fstack-protector -o /tmp/ccMvIfFH.s
ignoring nonexistent directory "/usr/include/c++/4.4/i686-linux-gnu/64"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../i686-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/4.4
 /usr/include/c++/4.4/backward
 /usr/local/include
 /usr/lib/gcc/i686-linux-gnu/4.4.5/include
 /usr/lib/gcc/i686-linux-gnu/4.4.5/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C++ (Ubuntu/Linaro 4.4.4-14ubuntu5) version 4.4.5 (i686-linux-gnu)
    compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 3.0.0-p3.
GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128197
Compiler executable checksum: 1fe36891f4a5f71e4a498e712867261c
In file included from main.cpp:1:
/usr/include/c++/4.4/iostream:39: fatal error: bits/c++config.h: No such file or directory
compilation terminated.

L'erreur concernant le ignoring nonexistent directoryétait l'indice. Malheureusement, je ne sais toujours pas quel package je dois installer pour que ce répertoire s'affiche, je viens donc de copier le /usr/include/c++/4.4/x86_64-linux-gnu/bitsrépertoire de ma machine 64 bits /usr/include/c++/4.4/i686-linux-gnu/64/bitssur ma machine 32.

Maintenant compiler avec juste les -m64travaux correctement. L'inconvénient majeur est que ce n'est toujours pas la bonne façon de faire les choses et je suppose que la prochaine fois qu'Update Manager sera installé et mis à jour vers g ++, les choses risquent de se casser.

Jesse Vogt
la source
1

Fondamentalement, il est utilisé dans HeapOverflows ou d'autres problèmes de type inverseur, c'est-à-dire si vous souhaitez changer un ELF 64 bits en ELF 32 bits et qu'il affiche une erreur lors de la conversion.

Vous pouvez simplement exécuter les commandes

apt-get install gcc-multilib g++-multilib

qui mettra à jour vos bibliothèques Packages mis à jour:

Les packages supplémentaires suivants seront installés: g ++ - 8-multilib gcc-8-multilib lib32asan5 lib32atomic1 lib32gcc-8-dev lib32gomp1 lib32itm1 lib32mpx2 lib32quadmath0 lib32stdc ++ - 8-dev lib32ubsan1 libc-dev-bin libc6 libc6-dev-dbgc6 -i386 libc6-dev-x32 libc6-i386 libc6-x32 libx32asan5 libx32atomic1 libx32gcc-8-dev libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc ++ - 8-dev libx32stdc ++ 6stdc ++ - 8-dev libx32stdc ++ 6stdc ++ - 8-dev libx32stdc ++ 6x32ubsan suggérés 8-dbg glibc-doc Les NOUVEAUX packages suivants seront installés:g ++ - 8-multilib g ++ - multilib gcc-8-multilib gcc-multilib lib32asan5 lib32atomic1 lib32gcc-8-dev lib32gomp1 lib32itm1 lib32mpx2 lib32quadmath0 lib32stdc ++ - 8-dev lib32ubsan1 libc6-libc6-lib-i386 libc6-dev-x32 libc6-x32 8-dev libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc ++ - 8-dev libx32stdc ++ 6 libx32ubsan1

similaire à celui-ci sera affiché sur votre terminal

Luftatako
la source
0

D'après mon expérience, ça sudo apt-get install gcc-multilib g++-multilibaide. Mais mon autre problème est que j'OUBLIE de nettoyer le répertoire afin que j'obtienne toujours la même erreur. C'est la première fois que vous utilisez clang ou cmake. Donc je supprime simplement mon répertoire d'origine et recompile et ça marche. J'espère que ça aide quelqu'un comme moi.

La cohérence
la source