Autoconf how to build static binary - makefile

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?

Related

arm-linux-gnueabihf cross compilation linking dynamic libraries

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?

gcc 6.4.0 how to generate EXEC binary on x86_64?

Consider a.c as containing:
void _start(void);
void _start(void) { while (1); }
With gcc 5.4.0 on Ubuntu, the following command generates an ELF file with type EXEC and no external dependencies:
gcc -o ./a -x c ./a.c -nostartfiles -nostdlib -nodefaultlibs
However, the same command with gcc 6.4.0 on Gentoo yields an ELF file with type DYN that requests the standard program interpreter /lib64/ld-linux-x86-64.so.2.
So, how do I generate a truly standalone EXEC binary with gcc 6.4.0?
You need to build in non-PIE mode to create a position-dependent executable. This consists of two steps:
Compile with -fno-pie.
Link with -no-pie.
Linking code compiled as PIE into a position-dependent executable works, but will results in a performance loss and a larger executable.
Found it. One must specify -no-pie.

Build go binary with static library

I'm trying to cross compile (from Arch Linux to Windows) a go binary with the openal library statically linked.
I use MinGW to cross compile to Windows and to MinGW package I have install and intend to use to link the static libary is mingw-w64-openal.
My build command looks like this:
CC='i686-w64-mingw32-gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -lssp' GOOS=windows CGO_ENABLED=1 GOARCH=386 go build --ldflags '--extldflags "-static"' -v -o bin/game.exe -tags='deploy' game.go
The .go files (linked below) that is using the library has the following cgo code to lookup the static library for MinGW to use:
#cgo windows LDFLAGS: /usr/i686-w64-mingw32/lib/libOpenAL32.dll.a
I get no errors during compilation but when I try run the binary file on windows I get the typical The program can't start because OpenAL32.dll is missing error. I want a completely portable executable so redistributing the .dll with the executable won't do.
The go openal package that I've modified to compile to windows:
https://github.com/golang/mobile/blob/master/exp/audio/al/al_notandroid.go
https://github.com/golang/mobile/blob/master/exp/audio/al/alc_notandroid.go

Building shared libraries for Ada

I'm having some trouble building shared libraries from Ada packages without using GPR's.
I have a package, Numerics, in files "numerics.ads" and "numerics.adb". They have no dependencies. There is a small build script which does:
gnatmake -Os numerics.ad[bs] -cargs -fPIC
gcc -shared numerics.o -o libnumerics.so -Wl,-soname,libnumerics.so
The .so and .ali files are installed at /usr/lib, and the .ads file is installed at /usr/include.
gnatls -v outputs the following relevant parts:
Source Search Path:
<Current_Directory>
/usr/include
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adainclude
Object Search Path:
<Current_Directory>
/usr/lib
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adalib
So GNAT should have no problem finding the files.
Then, trying to compile a package that depends on Numerics:
gnatmake -O2 mathematics.ad[bs] -cargs -fPIC
outputs:
gcc -c -fPIC mathematics.adb
gcc -c -I./ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error
This error has me thinking GNAT doesn't recognize the shared library, and is trying to rebuild Numerics.
I'd like to be building shared libraries, and only supply the spec for reference/documentation purposes.
edit:
So, it looks like gprbuild does two things I'm not doing. The first, is also passing -lnumerics to the compiler. The second, which shouldn't matter since libnumerics.so is in a standard directory anyways, is -L«ProjectDirectory». GPRbuild is obviously not doing desired behavior either, even though it's building the dependent project. It should be using the installed library /usr/lib/libnumerics.so, but instead is using «path»/Numerics/build/libnumerics.so. Furthermore, after building Numerics with GPRbuild, and then renaming the body to make it as if the body didn't exist (like with the installed files), when building Mathematics with GPRbuild, it complains about the exact same problem. It's as if the libraries aren't even shared, and GPRBuild is just making them look that way (except readelf reports the correct dependencies inside the libraries).
Adding -lnumerics to the build script accomplishes nothing; the build error is exactly the same. I'm completely lost at this point.
edit:
Following the link from Simon, the buildscript has changed to:
gnatmake -O2 mathematics.ad[bs] \
-aI/usr/include \
-aO/usr/lib \
-cargs -fPIC \
-largs -lnumerics
The error is essentially the same:
gcc -c -O2 -I/usr/include/ -fPIC mathematics.adb
gcc -c -I./ -O2 -I/usr/include/ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error
I thought to check libnumerics.so is actually a correct shared library. ldd reports:
linux-vdso.so.1 (0x00007ffd944c1000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f50d3927000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f50d3ed4000)
So I'm thinking yes, the library is fine, and gnatmake still isn't recognizing it.
In general, you need to install the body of the packages as well (numerics.adb in your case). Also, I suspect you want to set the ALI files
(numerics.ali) as read-only, so that gnatmake does not try to recompile them.

Building crti.o for i386

I am trying to build a cross-compiler with x86_64 being the host and i386 being the target. I'm getting the (all to common) crti.o: No such file error. Instead of grabbing an already built crti.o and crtn.o from a distro... how might I go about building these files explicitly from glibc (or possibly gcc) sources?
FYI, I am well aware of the -m32 option for x86_64 compilers. I'd prefer to just have a 32bit-only compiler environment. Also, the reason I don't want to use any of the gazillion already build i386 compilers is because I plan on mixing and matching glibc/binutils/gcc versions depending on my testing needs.
Thanks,
Chenz
Here's one possibility (from here)
You need to install your distro's 32
bit libc-dev package, or you need to
--disable-multilib which will result in a compiler that doesn't support 32
bit mode.
Are you sure you're using configuring the cross-compile correctly? It should be
CBUILD = CHOST = x86_64-pc-linux-gnu
CTARGET = i386-pc-linux-gnu
as you're running a build on an x86_64, for a compiler to run on an x86_64, which generates code for an i386.
If you used CHOST = i386-pc-linux-gnu, you'll be trying to generate 32-bit binaries, which will need to link with a 32-bit libc. Which is fine, if you already have a 32-bit libc, but it sounds like you don't.
i.e.
$ tar xvjf gcc-*.tar.bz2
$ cd gcc-*/
$ mkdir build
$ cd build
$ ../configure --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=i386-pc-linux-gnu

Resources