How do I do a static build with uclibc - c

I have a uclibc toolchain that works. I can compile a simple hello.c program statically (arm-linux-gcc hello.c -o hello -static -s) but source packages are automatically compiled dynamically. How can I change the default to static?

You have to edit the makefile of the source packet you are compiling (extra LDFLAG -static, just as you did for the hello.c file). Most of the time source packets are delivered with autoconf. In that case you can probably pass the --enable-static-link flag to configure. See configure --help for the set of possible arguments.
Other note: be careful when cross compiling packages which need other libraries. You do not want to link in your host machine libraries statically.

Related

Does gcc links to libc.a or libc.so by default?

I am using gcc 5.4.0 on Ubuntu 16.04 64 bit. When I compile a program:
gcc -o prog prog.c
GCC automatically links to the C standard library, so I don't have to specifically do that.
How can I see which C library does gcc link against to, libc.a or libc.so, or something else?
In what circumstance does it link to libc.so? Does libc.so need to be specified at run time like other shared libraries?
Thanks in advance.
How can I see which C library does gcc links against to, libc.a or libc.so, or something else?
You can use ldd command to see all linked shared libraries. If libc.so is found, it's dynamic linking.
In what circumstance does it links to libc.so?
gcc uses dynamic linking and links to libc.so by default. If you want static linking, pass -static flag.
Does libc.so need to be specified at run time like other shared libraries?
Normally no, since it's configured by compiler automatically.

GCC have include but not library

I'm writing my own kernel for fun, and in doing so I've needed to install glibc to use the standard C libraries. However, after installing the library to the desired directory, my kernel.c program includes the stdio.h header and attempts to use fopen, however I come across this error:
kernel.c:(.text+0x238): undefined reference tofopen'`
After looking around I noticed that I don't have any actual code to all of the header files, just the header files themselves. So I went and added the -L flag to GCC to add the lib folder that was created during the compilation of glibc and what I've found out is that the lib folder has nothing of what I need.
I poked around and found that the build directory I used when compiling glibc has the .o files I'm looking for (e.g it has iofopen.o for the fopen method).
So what's going on?
If needed, the commands I am using to compile my kernel are:
#!/bin/bash
nasm -felf32 boot.asm -o boot.o
/home/noah/opt/cross/bin/i686-elf-gcc -I/home/noah/Documents/NoahOS/include/ -L/home/noah/Documents/glibc/build -c *.c -std=gnu99 -ffreestanding -Wall -Wextra
/home/noah/opt/cross/bin/i686-elf-gcc -I/home/noah/Documents/NoahOS/include/ -L/home/noah/Documents/glibc/build -T linker.ld -o noahos.bin -ffreestanding -O2 -nostdlib *.o -lgcc
First line builds the boot file, which is assembly.
Second line runs gcc on all of the C language .c files and creates their object files.
Third line links all of the files together with linker.ld and outputs the final kernel to noahos.bin which is a runnable kernel using
qemu-system-i386 -kernel noahos.bin
If needed more information can be provided. Please ask.
You are correctly compiling your kernel using -nostdlib because the kernel can't use the standard library. Why not? Because it doesn't make sense: the standard library is the interface between user programs and the kernel, so that application developers don't need to know the system call specification for your kernel, all that is required is a port of the C library.
Oh, there's the answer. You need a port of the C library to use your own system calls. Starting with glibc might not be the easiest to port (it comes with the kitchen sink).

How to make a .so executable on OSX?

I have a simple C library that I compile to a .so file on my linux machine. I'd like to do the same on my Mac, but after I compile and move the library to /usr/local/lib, but I'm not sure how to link it seeing as ldconfig isn't a thing.
How would I go about doing this?
While Linux has .so files, OSX has .dylib files. The process is similar, you just invoke compiler as in
clang -dynamiclib -o libname.dylib sources.c

How to configure a non-standard linker for an autotooled build?

I wanted to configure an autotooled project to invoke a non-standard
linker (the gold linker),
using the stock autotools of Linux Mint 16/Ubuntu 13.10
I believed I would achieve this by:
libtoolize-ing the project
Running ./configure LD=/path/to/my/linker ... etc.
However this has been ineffective. libtoolize has been successful. After
a standard ./configure; make I now see that libtool is doing the
linking:
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -o helloworld helloworld.o
But passing LD=/path/to/my/linker to configure makes no difference. Experimentally,
I even ran:
./configure LD=/does/not/exist
expecting to provoke an error, but I didn't. The output contains:
checking if the linker (/does/not/exist -m elf_x86_64) is GNU ld... no
checking whether the g++ linker (/does/not/exist -m elf_x86_64) supports shared libraries... yes
And thereafter a make continues to link, successfully, invoking g++ exactly as before.
What is the right way to configure a non-standard linker?
But passing LD=/path/to/my/linker to configure makes no difference
This is because LD is almost never and should almost never be used to link any user-space program. Correct links are performed by using the appropriate compiler driver (gcc, g++, etc) instead.
What is the right way to configure a non-standard linker?
If you have /some/path/ld and you want gcc to use that ld, pass -B/some/path flag to gcc.
It then follows that you likely want:
./configure CC='gcc -B/some/path' CXX='g++ -B/some/path' ...
I landed on this via a Google search, though my scenario is a bit different from yours; there was no libtool involved. An old open source program's Makefile was hard-coding ld to create an object file with a symbol from binary data.
This is what I ended up doing to work around the lack of $(LD) being recognized when passed to configure:
https://github.com/turboencabulator/tuxnes/commit/bab2747b175ee7f2fc3d9afb28d69d82db054b5e
Basically I added to configure.ac:
AC_CHECK_TOOL([LD], [ld])
Leaving this answer here for if someone else lands via a google search.

C - Compile with dependencies included

I have some code which I want to run on a machine which I do not have root access to.
That machine does not have some of the libraries needed to run this code.
Is there any way to include all dependencies when I compile? I realize the resultant file may be quite large.
What you're looking for is static compiling. Performing static compilation includes all of the libraries into the executable itself, so you don't have to worry as much about dependency chains on a specific system, distribution, etc.
You can do this with:
gcc -Wl,-Bstatic -llib1 -llib2 file.c
The -Wl passes the flags following to the linker, -Bstatic tells it to link static if possible, and then lib1, lib2, are the libs you intend to link.
Alternatively, try:
gcc -static file.c
The compilation will still need to match the architecture of the non-privileged system. And you need to have the static libraries installed on the compiling system (lib.a)
If compiled properly, it should show "not a dynamic executable" when you run:
ldd a.out

Resources