arm-linux-gnueabihf cross compilation linking dynamic libraries - gcc

I have pre-compiled binaries of the arm-linux-gnueabihf GCC toolchain. Host is x86_64 while the intended target is arm7 architecture. I am able to cross compile a sample program using this cross-compiler but it is not able to link with dynamic libraries. On the host, I use:
arm-linux-gnueabihf -c -o test test.c
The compiled executable with ldd command shows following output on host as well as target:
ldd ./test
not a dynamic executable
However, I use the same source code and compile natively on the target, I observe:
ldd ./test
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e29000)
/lib/ld-linux-armhf.so.3 (0xb6f18000)
The whole concept of linker seems tricky in case of cross-compilation. Is there a standard way to link shared dynamic libraries while cross compiling?

Related

Autoconf how to build static binary

I do cross-compile in my PC, and I want to build a static link binary. In order to run it on the target board without adding any shared library.
When compile a single file, I know I can use "-static" to build a binary without any shared library.
e.g.
$ aarch64-linux-gnu-gcc -o hello hello.c -static
$ file hello
hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked,
But when I use autoconf in the open source project, I can't build the binary static.
I have tried the following command, but failed:
$ ./configure --host=aarch64-linux-gnu --enable-static --disable-shared LDFLAGS="-static"
Is there any one know how to build a static binary with autoconf?

How to cross compile solaris 32-bit

We are currently building our Go executables for several platforms including Solaris 64-bit. We have requests for a 32-bit Solaris executable version as well and I am unable to get this to work (the person who setup the Solaris 64-bit cross compiler is gone and unreachable).
I tried just setting -m32 flag on go build using our existing solaris cross compilation, but that didn't work, so I am attempting to build a Solaris 32-bit specific cross compiler.
I googled and found some vague examples, so I am following this process:
Copy headers and libraries from a 32-bit Solaris machine to my Linux build machine.
D/L and build binutils and gcc pointing SYSROOT to the downloaded 32-bit Solaris headers and libraries where:
$TARGET=sparc-sun-solaris2.10
$SYSROOT=/path/to/solaris32/includes
$PREFIX=/path/to/gcc-output
binutils-2.31/configure -target=$TARGET --prefix=$PREFIX -with-sysroot=$SYSROOT -v
gcc-8.2.0/configure --target=$TARGET --with-gnu-as --with-gnu-ld --prefix=$PREFIX -with-sysroot=$SYSROOT --disable-libgcj --enable-languages=c,c++,go -v
Create a symlink to gogcc and put GCC on the path
Compile a trivial test go program like this:
go build --compiler gccgo --gccgoflags "-m32 -O3 -static-libgo -Wl,-dy -lnsl -lsocket -lrt -lsendfile" -o ${GOTOOLS}/${BINARIES}/${PROJECT_NAME}/test/solaris_sparc32 test/main.go
This fails as follows:
go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags
command-line-arguments
gccgo: error: may not use both -m32 and -m64
Clearly I don't know what I'm doing. Can anyone point me in the right direction?
Solaris 32-bit does not appear to be supported, according to the list of supported OS/arch targets:
The valid combinations of $GOOS and $GOARCH are:
$GOOS $GOARCH
...
solaris amd64
...
That is, Solaris 64-bit is explicitly listed as a supported platform but Solaris 32-bit is not listed.
As such, there is good reason to believe that go programs will not run reliably on Solaris 32-bit systems and you probably should not agree to support that platform (if you do happen to get that cross compilation working) mainly because the go team itself does not support it!

Link a "toy" OS using llvm/clang

Is it possible (within reason) to build a "toy" OS on a mac using llmv/clang (and the other "normal" build tools)? By "toy" OS, I mean the simple, "Hello, World" examples found on OSDev (http://wiki.osdev.org/Bare_Bones) and x86 Bare Metal (https://github.com/cirosantilli/x86-bare-metal-examples).
My main problem is I can't figure out how to specify precisely where the linker should place the code (i.e., that the starting point should be 0x7c00, that bytes 510 and 511 need to be 0xaa55, etc.).
I would say yes it is possible within reason, at least if you consider waiting for a build of lld (and its dependency llvm) reasonable. Instructions to build lld can be found on their website or as part of this answer.
Compiling and linking for a different target than the host is relatively easy with clang. You just have to set a target, for example -target i386-none-elf for an ELF binary. Cross-compilation using clang is explained in more detail here.
As for macOS, as Micheal Petch noted, you have to use another linker than the standard ld installed. You could in theory install binutils to get an ELF ld but then you have to compile it yourself to set the target. My recommendation is to use lld which can target many architectures without the need to recompile.
With clang and a lld in place we can compile sources with
clang -c -o file.o file.c -target i386-none-elf # freestanding flags omitted
and then link them with
clang -o kernel.bin file.o -target i386-linux-elf -nostdlib -Wl,linkerscript.ld -fuse-ld=lld
Note that for linking I am using i386-linux-elf because there is a bug in clang where they just forward their input to gcc. But when using -nostdlib it is essentially the same.
If you want to see a complete example ready to build, you can take a look at https://github.com/Henje/x86-Toy-OS.

On Solaris, are libraries compiled with gcc usable the same way as for libs generated with cc?

I am currently trying to compile libxml2 on Solaris. When I run the ./configure script provided with the sources, the gcc and g++ compilers are automatically used. However, I would like to use cc and CC compilers. So I run :
./configure CC=cc CXX=CC
It works but then, when I run "make", I get some errors which prevent the libraries to be generated.
When gcc and g++ are used, everything goes well with no errors, so I was wondering: can I use the librairies generated with gcc/g++ the same way I would have used them if I had successively generated them with cc/CC?
What are the differences between a lib generated with cc and the same lib generated with gcc on Solaris?
You can use either the gcc or cc C compilers pretty much interchangeably.
You can mix the g++ and CC C++ compilers in certain ways, but only on x86 Solaris and if your CC compiler is new enough to have the -compat=g option available.
The GNU g++ and the Solaris Studio CC C++ compilers default to completely different ABIs and C++ run-time libraries. On x86 Solaris platforms, newer versions (since version 12.?, if I remember correctly) provide a -compat=g option to use the g++ ABI and run-time libraries. The Studio 12.4 CC compiler adds a -std=v option to select different versions of the g++ or Sun C++ ABI and run-time libraries:
c++03 (zero-3, not oh-3)
Equivalent to the -compat=g option. It selects C++ 03 dialect and g++ ABI; it is binary compatible with g++ on Solaris and Linux It
sets the __SUNPRO_CC_COMPAT preprocessor macro to 'G'.
c++11
Selects C++ 11 dialect and g++ binary compatibility. It sets the __SUNPRO_CC_COMPAT preprocessor macro to 'G'.
c++0x (zero-x, not oh-x)
Equivalent to c++11.
and
The -std=c++03 provides compatibility with the gcc/g++ compiler on
all Oracle Solaris and Linux platforms.
With -std=c++03, binary compatibility extends only to shared
(dynamic or .so) libraries, not to individual .o files or archive (.a)
libraries. The gcc headers and libraries used are those provided with
the compiler, rather than the version of gcc installed on the system.
Note that the Studio 12.4 CC compiler uses the g++ headers and libraries supplied bundled with the CC compiler itself. 12.3 and earlier use the g++ headers and libraries installed on the system under /usr/sfw.
On SPARC Solaris, you have to use either g++ or CC for the entire application.

Why my cross compiler toolchain not static link?

I want to build my cross compile tool chain, I build it successful.
It can use normally, but when I move it, it cannot work!!
It print error while loading shared libraries: libcloog-isl.so.3, libcloog-isl is not install in my host.
I configure the gcc with --disable-shared, but when I run ldd to the cc1 in my cross compile tool chain, I found that ppl, gmp, moc, libgcc_s and some other link to my host library. why it cannot static link into cc1 when I use --disable-shared.
I found that Sourcery CodeBench's tool chain can run anywhere, its cc1 not link my host library.
What should I do to static link in cc1 instead of dynamic link host library?
You may already be aware that the ld command (as well as gcc) will accept the -static option, but you may also need to use -static-libgcc and/or -static-libstdc++ to make sure you are linking statically to all libraries.

Resources