Das fehlende Include "bits / c ++ config.h" beim Cross-Compilieren eines 64-Bit-Programms auf 32-Bit in Ubuntu

180

Ich verwende die 32-Bit-Version von Ubuntu 10.10 und versuche, die Kompilierung auf ein 64-Bit-Ziel zu übertragen. Aufgrund meiner Recherchen habe ich das g ++ - Multilib-Paket installiert.

Das Programm ist eine sehr einfache Hallo Welt:

#include <iostream>

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

Kompilieren:

g++ -m64 main.cpp

Error:

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.

Ich habe eine c++config.hDatei gefunden, aber sie befinden sich unter den Verzeichnissen i486-linux-gnuund i686-linux-gnuin. /usr/include/c++/4.4/Es gibt keine c++config.hin /usr/include/c++/bits.

Irgendwelche Ideen, was mir fehlt? Das Kompilieren ohne -m64Flag funktioniert einwandfrei (a.out wird erstellt und wird ordnungsgemäß ausgeführt).

Bearbeiten Dank des Hinweises von @nightcracker habe ich die Include-Struktur auf den 32- und 64-Bit-Systemen etwas genauer untersucht. Ich habe unten eine Antwort hinzugefügt , die das Problem vorübergehend "behebt", aber ich denke, es wird beim nächsten Update kaputt gehen. Grundsätzlich fehlt mir ein Verzeichnis mit dem Namen /usr/include/c++/4.4/i686-linux-gnu/64, das ein Unterverzeichnis bitsmit der fehlenden Include-Datei enthalten sollte. Irgendeine Idee, welches Paket sich darum kümmern sollte?

Jesse Vogt
quelle
1
Wow ... ich hatte auch dieses Problem. GCC 4.8 auf einem ARMv7-a CubieTruck (Cortex-A7) unter Ubuntu. Das Bizarre (für mich) ist, dass Anthonys Antwort es behoben hat. Was auch immer ...
jww

Antworten:

306

Diese Antwort wurde teilweise hinzugefügt, da dadurch mein Problem mit demselben Problem behoben wurde und ich diese Frage selbst mit einem Lesezeichen versehen kann.

Ich konnte das Problem wie folgt beheben:

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

Wenn Sie eine Version von gcc/ installiert haben g++, die nicht standardmäßig ausgeliefert wird (z. B. g++-4.8auf lucid), möchten Sie auch die Version anpassen:

sudo apt-get install gcc-4.8-multilib g++-4.8-multilib
Anthony Sottile
quelle
30
Stellen Sie sicher, dass die gcc and g++auf Ihrem System installierten Versionen übereinstimmen . Unter Ubuntu 14.04 hatte gcc-4.8und g++-4.8installierte ich, also installierte ich gcc-4.8-multilib und g++-4.8-multilibstattdessen.
Zoltán
3
Dies löste mein Problem beim Kompilieren mit -m32 auf einem 64-Bit-Computer. Danke
Nic
41
Vielen Dank für den Zeiger, sudo apt-get install gcc-multilib g++-multilibscheint aber besser zu sein (er wird automatisch in Ihre gcc-Version aufgelöst).
Leesei
^ vielleicht nicht! @ Zoltans Vorschlag hat bei mir aber funktioniert. Anthony Sottile, vielleicht sollten Sie Zoltans Kommentar in Ihre Antwort aufnehmen?
Mann
@Man zögern Sie nicht, eine Änderung vorzuschlagen, als ich es anfänglich veröffentlichte, stimmte ich mit der in der Frage gestellten Version überein, es hat sich seitdem von den Änderungen anderer geändert
Anthony Sottile
11

Haben Sie versucht, -I/usr/include/c++/4.4/i486-linux-gnuoder hinzuzufügen -I/usr/include/c++/4.4/i686-linux-gnu?

orlp
quelle
Das funktioniert tatsächlich. Irgendeine Idee, warum ich dies für nur 64 Bit tun müsste? Ich versuche, diesen Computer so einzurichten, dass er bei verteilten 64-Bit-Builds hilft, und möchte zu viele Anpassungen vermeiden.
Jesse Vogt
2
Es tut mir leid, ich habe keine Ahnung, ich habe gerade eine schnelle hackige Arbeitslösung gestellt :)
orlp
5

Beim Kompilieren in RHEL 6.2 (x86_64) habe ich sowohl 32-Bit- als auch 64-Bit-libstdc ++ - dev-Pakete installiert, aber ich hatte die "c ++ config.h" keine solche Datei oder kein solches Verzeichnis Problem ".

Auflösung:

Das Verzeichnis /usr/include/c++/4.4.6/x86_64-redhat-linux fehlte.

Ich habe folgendes gemacht:

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

Ich kann jetzt 32-Bit-Binärdateien auf einem 64-Bit-Betriebssystem kompilieren.

Pekmez
quelle
1
Auf OpenSUSE habe ichcd /usr/include/c++/4.6;ln -s x86_64-suse-linux i586-suse-linux
Julian
3

Scheint ein Tippfehler in diesem Paket von gcc zu sein. Die Lösung:

mv /usr/include/c++/4.x/i486-linux-gnu /usr/include/c++/4.x/i686-linux-gnu/64
Tanzen tanzen
quelle
2

Auf meinem 64-Bit-System habe ich festgestellt, dass das folgende Verzeichnis vorhanden ist:

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

Es wäre dann sinnvoll, dass auf meinem 32-Bit-System, das für das 64-Bit-Cross-Compilieren eingerichtet wurde, ein entsprechendes Verzeichnis vorhanden sein sollte wie:

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

Ich habe es doppelt überprüft und dieses Verzeichnis existierte nicht. Das Ausführen g++mit dem ausführlichen Parameter zeigte, dass der Compiler tatsächlich an dieser Stelle nach etwas suchte:

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.

Der Fehler bezüglich ignoring nonexistent directorywar der Hinweis. Leider weiß ich immer noch nicht, welches Paket ich installieren muss, damit dieses Verzeichnis angezeigt wird. Deshalb habe ich das /usr/include/c++/4.4/x86_64-linux-gnu/bitsVerzeichnis einfach von meinem 64-Bit-Computer /usr/include/c++/4.4/i686-linux-gnu/64/bitsauf meinen 32-Computer kopiert .

Jetzt -m64funktioniert nur das Kompilieren richtig. Der Hauptnachteil ist, dass dies immer noch nicht die richtige Vorgehensweise ist und ich vermute, dass bei der nächsten Installation von Update Manager und der Aktualisierung auf g ++ möglicherweise Probleme auftreten.

Jesse Vogt
quelle
1

Grundsätzlich wird es in HeapOverflows oder anderen Umkehrproblemen verwendet. Probleme, dh wenn Sie eine 64-Bit-ELF in eine 32-Bit-ELF ändern möchten und beim Konvertieren ein Fehler angezeigt wird.

Sie können die Befehle einfach ausführen

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

Dadurch werden Ihre Bibliotheken aktualisiert. Aktualisierte Pakete:

Die folgenden zusätzlichen Pakete werden installiert: g ++ - 8-Multilib gcc-8-Multilib lib32asan5 lib32atomic1 lib32gcc-8-dev lib32gomp1 lib32itm1 lib32mpx2 lib32quadmath0 lib32stdc ++ - 8-dev lib32ubsan1 libc-dev-bin libc6 libc6-dbc libc6 -i386 libc6-dev-x32 libc6-i386 libc6-x32 libx32asan5 libx32atomic1 libx32gcc-8-dev libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc ++ - 8-dev libx32stdc ++ 6 libx32b ++ 8-dbg glibc-doc Die folgenden NEUEN Pakete werden installiert:g ++ - 8-multilib g ++ - multilib gcc-8-multilib gcc-multilib lib32asan5 lib32atomic1 lib32gcc-8-dev lib32gomp1 lib32itm1 lib32mpx2 lib32quadmath0 lib32stdc ++ - 8-dev lib32ubsan1 libc6-dev-i386 libx 8-dev libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc ++ - 8-dev libx32stdc ++ 6 libx32ubsan1

Ähnliches wird Ihrem Terminal angezeigt

Luftatako
quelle
0

Aus meiner Erfahrung sudo apt-get install gcc-multilib g++-multilibhilft. Aber mein anderes Problem ist, dass ich VERGESSEN habe, das Verzeichnis zu bereinigen, damit ich immer noch den gleichen Fehler bekomme. Es ist das erste Mal, dass Clang oder Cmake verwendet werden. Also lösche ich einfach mein ursprüngliches Verzeichnis und kompiliere es neu und es funktioniert. Hoffe es hilft jemandem wie mir.

Kohärenz
quelle