You are not logged in.
Pages: 1
I'm using the Clang compiler (on i686) and would like to cross-compile for x86-64.
The command I'm using is:
$ clang -ccc-host-triple x86_64-unknown-linux [...]
It seems to generate valid 64-bit assembler code but it's compiled in x86 mode.
/tmp/cc-J3OsmS.s: Assembler messages:
/tmp/cc-J3OsmS.s:36: Error: bad register name `%rbp'
/tmp/cc-J3OsmS.s:38: Error: bad register name `%rsp'
/tmp/cc-J3OsmS.s:40: Error: bad register name `%rdi'
/tmp/cc-J3OsmS.s:41: Error: bad register name `%rbp)'
...
/tmp/cc-J3OsmS.s:186: Error: `movabs' is only supported in 64-bit mode
...
What's the recommended way of solving it?
Clang uses the GCC assembler. Can I specify a different one, say nasm?
So far, I only managed to find GCC cross-compile packages for ARM and some other architectures but not for x86-64.
Any help is appreciated.
Last edited by tindzk (2010-08-01 12:03:27)
Offline
Am not sure if my understanding is accurate, but don't you need a 64-bit kernel to be able to cross-compile for 64-bit. Recall Allan saying something to that effect before.
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline
Am not sure if my understanding is accurate, but don't you need a 64-bit kernel to be able to cross-compile for 64-bit. Recall Allan saying something to that effect before.
True, but I'm using the default i686 repositories and the assembler only seems to produce x86 code.
My initial question was how this problem is usually tackled under Arch Linux; is there a third-party repository for cross-compilers? Do I need to compile a package from AUR? Or can I use what I've got and just change a variable in the assembler to also accept 64-bit code?
Offline
ngoonee wrote:Am not sure if my understanding is accurate, but don't you need a 64-bit kernel to be able to cross-compile for 64-bit. Recall Allan saying something to that effect before.
True, but I'm using the default i686 repositories and the assembler only seems to produce x86 code.
My initial question was how this problem is usually tackled under Arch Linux; is there a third-party repository for cross-compilers? Do I need to compile a package from AUR? Or can I use what I've got and just change a variable in the assembler to also accept 64-bit code?
Cross-compilation in Arch is typically done the other way around, on a 64-bit system compiling for 32-bits. Allan has a blog post detailing how he runs a 64-bit kernel with a 32-bit userspace (ie everything else), this allows him to compile for either 32 or 64-bits with cross32-gcc (I think that's the name of the package).
A bit of searching should turn up what you need.
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline
That might be a solution but I'd prefer to continue using i686 packages. Wouldn't Allan's approach arise conflicts? The GCC packages in the x86_64 repository are called the same as in i686, aren't they?
Offline
That might be a solution but I'd prefer to continue using i686 packages. Wouldn't Allan's approach arise conflicts? The GCC packages in the x86_64 repository are called the same as in i686, aren't they?
Like I said, he's using a 64-bit kernel with 32-bit userspace. In other words, all his packages are 32-bit, except the kernel-related ones.
I don't really know more than that. In my opinion, just go 64-bit if you're going to want to cross-compile. I would not do it any other way, and hence can't help you if you do want to.
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline
Yes, I got that but it won't work because for cross-compiling, you also need an assembler that's supporting the architecture you're compiling for. A 64-bit kernel alone doesn't suffice.
Offline
I don't think you need the 64bit kernel, try adding the -m64 flag to your clang command.
Offline
I don't think you need the 64bit kernel, try adding the -m64 flag to your clang command.
Sorry, still the same errors.
Offline
Yes, I got that but it won't work because for cross-compiling, you also need an assembler that's supporting the architecture you're compiling for. A 64-bit kernel alone doesn't suffice.
Hence you need a parallel version of gcc. Have you searched for Allan's instructions?
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline
Hence you need a parallel version of gcc. Have you searched for Allan's instructions?
All I could find was this (http://wiki.archlinux.org/index.php/Cro … s_Proposal) but it's about building cross-compiler packages. It only describes how to build binutils for MinGW but what about the other packages? So I searched in AUR but couldn't find anything.
Are you sure I need GCC at all? Binutils seems to be the crucial package because it contains ld and as. Wouldn't it suffice?
Offline
If Clang produces x86_64 asm, then all you need is to build a cross-binutils.
Then tell clang where to find these new as and ld.
To cross compile binutils, something like this should work (not tested):
_target=x86_64-unknown-linux-gnu
_sysroot=/usr/lib/cross-${_target}
pkgname=cross-${_target}-binutils
_pkgname=binutils
pkgver=2.20.1
pkgrel=1
pkgdesc="Arm linux binutils"
url="http://www.gnu.org/software/binutils/"
license=('GPL')
arch=('i686' 'x86_64')
depends=('glibc>=2.10.1' 'zlib')
options=('!libtool' '!distcc' '!ccache')
source=(http://ftp.gnu.org/gnu/${_pkgname}/${_pkgname}-${pkgver}.tar.bz2)
md5sums=('9cdfb9d6ec0578c166d3beae5e15c4e5')
build () {
cd ${srcdir}/${_pkgname}-${pkgver}
mkdir build && cd build
# Unset CFLAGS
unset CFLAGS
unset CXXFLAGS
../configure --prefix=${_sysroot} \
--bindir=/usr/bin \
--with-sysroot=${_sysroot} \
--build=$CHOST \
--host=$CHOST \
--target=${_target} \
--with-gcc \
--with-gnu-as \
--with-gnu-ld \
--enable-shared \
--without-included-gettext \
--disable-nls \
--disable-debug
make || return 1
}
package () {
cd ${srcdir}/${_pkgname}-${pkgver}/build
make DESTDIR=${pkgdir}/ install || return 1
# remove docs
rm -r ${pkgdir}/${_sysroot}/share/{info,man}
}
Offline
You do need a full toolchain that supports outputting 64 bit binaries. If you need help setting up such a toolchain yourself, you can check out the CLFS project for pointers.
Got Leenucks? :: Arch: Power in simplicity :: Get Counted! Registered Linux User #392717 :: Blog thingy
Offline
Compiling your PKGBUILD worked perfectly, thanks. I also added "--enable-64-bit-bfd" (cf. http://wiki.osdev.org/GCC_Cross-Compiler_for_x86_64)
Modifying the PATH variable spawns at least the right "as"...
export PATH=/usr/lib/cross-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/bin/:$PATH
...but the errors posted above still remain, because "as" is getting passed "--32".
So after lots of experimenting I came up with the following parameters:
CC = clang -include config.h
CC += -ccc-host-triple x86_64-unknown-linux
CC += -m64
CC += -Wa,--64
CC += -Wl,"-L/usr/lib/cross-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/lib"
CC += -Wl,"-melf_x86_64"
CC += -v
It's very hackish because Clang doesn't support proper cross-compiling on Linux. By the way, other architectures seem to have much more sophisticated heuristics: http://clang.llvm.org/doxygen/ToolChain … ource.html
This all works fine for the assembler and I also managed to eliminate some errors with "ld" but it's not working completely. "ld" gets called like this:
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker /lib/ld-linux.so.2 -o a.out /usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.5.0/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.5.0 -L/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../.. -L/usr/lib/cross-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/lib -melf_x86_64 /tmp/cc-AIbI5G.o /tmp/cc-UiUGe7.o /tmp/cc-Kj0Hnx.o /tmp/cc-AIILwX.o /tmp/cc-yj4RFn.o /tmp/cc-6KT0ON.o /tmp/cc-ooccYd.o /tmp/cc-GTVp7D.o /tmp/cc-0DiGg4.o /tmp/cc-C7lZpu.o /tmp/cc-6OUkzU.o /tmp/cc-QwMVIk.o /tmp/cc-cY4MSK.o /tmp/cc-E2WG2a.o /tmp/cc-YwgDcB.o /tmp/cc-SFTBm1.o /tmp/cc-ki0Cwr.o /tmp/cc-IOEGGR.o /tmp/cc-C7CMQh.o /tmp/cc-sCQV0H.o /tmp/cc-cAB7a8.o /tmp/cc-I2Olly.o /tmp/cc-KttCvY.o /tmp/cc-wwrVFo.o /tmp/cc-ujWgQO.o /tmp/cc-gqUE0e.o /tmp/cc-4Ra5aF.o /tmp/cc-24Mxl5.o /tmp/cc-WtH2vv.o /tmp/cc-oeaAGV.o /tmp/cc-KzU9Ql.o /tmp/cc-WheM1L.o /tmp/cc-ONPqcc.o /tmp/cc-AuW8mC.o /tmp/cc-4NYUx2.o /tmp/cc-MujJIs.o /tmp/cc-W5eATS.o /tmp/cc-6UBt4i.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/4.5.0/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../crtn.o
Interestingly, I'm experiencing exactly the same issue described in the sources:
// FIXME: Figure out some way to get gcc's libdir
// (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
// crtbegin.o/crtend.o/etc., and want static versions of various
// libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
// get away with using shared versions in /usr/lib, though.
// We could fall back to the approach we used for includes (a massive
// list), but that's messy at best.
Can I still use the 32-bit crtend.o or will it conflict?
However, the command fails with:
/usr/lib/cross-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/bin/ld: skipping incompatible /usr/lib/gcc/i686-pc-linux-gnu/4.5.0/libgcc.a when searching for -lgcc
/usr/lib/cross-x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/bin/ld: cannot find -lgcc
What do I need libgcc for? Can I disable it? Looks like I have to compile the complete GCC toolchain otherwise.
Last edited by tindzk (2010-08-03 13:13:42)
Offline
Pages: 1