C - Compile with dependencies included - c

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

Related

Why does SDL2 need both static and dynamic libraries for compilation

Basically when using SDL2 library why do I need to use both SDL2.dll (dynamic) file and .a (static) for compilation?
For an example to compile a simple program I need to tell gcc where lib files (static .a) are located to compile the program. Why not just use the .dll file instead?
My first thought is that .a files are needed for the compiler to check if program can compile with the library and .dll is only needed when running the program (and program is not statically linked in the end), but still that wouldn't explain why do i need the .a files instead of just .dll file.
example:
gcc -I src/include src/lib -o main.exe main.c -lmingw32 -lSDL2main -lSDL2
There are two .a files: libSDL2.a and libSDL2.dll.a (not counting libSDL2main.a, which is always static).
The first one is a true static library. -lSDL2 doesn't prefer it by default, it prefers libSDL2.dll.a. And if you force it to use the former, because the latter is unavailable, the resulting app won't depend on SDL2.dll.
The second one is an import library. In the old days, MinGW couldn't link against a .dll directly, and you had to use those. Modern MinGW can link .dlls directly, and those should in theory be unnecessary.
I'd still recommend using the import library if it's available, just because it's more common and more widely tested.

Is it a compiled library portable?

I have a conceptual question about writing a library in plain c. I have some functions that I have to use in different programs in the same folder, so I was thinking about writing a library to host these functions. I have to write the whole code in a folder that will be copied to another computer (where the programs will run). If I create and compile the library in this folder, will be the user able to run the programs without rebuilding the library from source or he might have some unpredictable errors? The user will build the programs that use the library anyway, he won't build the lib itself.
Thanks
Lorenzo
In general, no, it is not portable in the sense that a compiled library can be linked on an arbitrary other system. The compiled library has to be compatible to the target architecture, the OS, the compiler system, to name some.
But you have another choice, concluded from your comment: It seems that you also provide some shell script or makefile to build the programs.
Because a library consists of "just" a set of compiled translation units before some of them get linked into the programs, you can take the set of sources of these translations unit and compile them with the sources of each program, where appropriate.
As an example, let's say you have 2 functions (each in its own source file) you use in different combinations in 3 programs. "prg1" uses func1(), "prg2" uses func2(), and "prg3" uses both.
This can be the commands to build the programs with a (static) library:
gcc -c func1.c -o func1.o
gcc -c func2.c -o func2.o
ar -r lib.a func1.o func2.o
gcc prg1.c lib.a -o prg1
gcc prg2.c lib.a -o prg2
gcc prg3.c lib.a -o prg3
Instead of the library you compile the programs' sources directly:
gcc prg1.c func1.c -o prg1
gcc prg2.c func2.c -o prg2
gcc prg3.c func1.c func2.c -o prg3
The results are the same, at least as long as you had linked statically to the library.
But even with a shared (dynamic) library the approach will be the same. Shared libraries "only" save some RAM if several programs using them are run concurrently. If only one program runs at a time, a dynamically linked program might need more RAM and loads slower.

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.

How do I do a static build with uclibc

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.

Two method for linking a object using GCC?

I've known that I should use -l option for liking objects using GCC.
that is gcc -o test test.c -L./ -lmy
But I found that "gcc -o test2 test.c libmy.so" is working, too.
When I use readelf for those two executable I can't find any difference.
Then why people use -l option for linking objects? Does it have any advantage?
Because you may have either a static or a shared version of the library in your library directory, e. g. libmy.a and libmy.so, or both of them. This is more relevant to system libraries: if you link to libraries in your local build tree, you know which version you build, static or shared, but you may not know other systems' configuration and libraries mix.
In addition to that, some platforms may have different suffixes. So it's better to specify it in a canonical way.
The main reason is, -lname will search for libname.a (or libname.so, etc.) on the library search list. You can add directories to the library search list with the -L option. It's a convenience built into the compiler driver program, making it easier to find libraries that have been installed in standard places on the system.

Resources