Compiling .c files to a single LLVM IR and link multiple libraries during the compilation.
An example here with gcc:
gcc -c -Wall -g3 -DVERSION=\"1.1.2\" ssl_proxy.c -o ssl_proxy.o
gcc -o ssl_proxy ssl_proxy.o -lssl -lcrypto
Now, I want to compile the ssl_proxy.c to ssl_proxy.ll, simply using llvm-gcc -S -emit-llvm won't work as it will not let me link -lssl -lcrypto libraries.
Through this example I hope people can explain a bit more details about compilation with llvm-gcc (not clang), so that all visitors can learn from it and know how to compile complex multiple sources into one LLVM IR.
Compiling source files into LLVM IR does not perform linking, so it does not require any libraries - it just needs the headers.
Related
I am trying to statically link SDL2 on Linux, with the goal of creating a binary that doesn't require any libraries to be required on the system. I understand this will require statically linking more than just SDL2, such as SDL2's dependencies and things like libc, so help on that front would be appreciated as well. But right now I can't get SDL2 to statically link at all.
I am using GCC, and SDL 2.0.16 that I compiled and installed myself with the default configuration, which includes static libraries. I already had SDL2 installed through my package manager, so my installation went to /usr/local/include/SDL2 and /usr/local/lib.
Running /usr/local/bin/sdl2-config --cflags --static-libs gives:
-I/usr/local/include/SDL2 -D_REENTRANT
-L/usr/local/lib -lSDL2 -lm -ldl -lpthread -lrt
No amount of messing around with these flags and -static have been able to produce a binary that doesn't dynamically link to SDL2. How can I do it?
Other flags I am using for other reasons are -std=c89 -Wall -Wno-unknown-pragmas -DNDEBUG -Os -g0 -s
Being able to cross compile and do this would be great, but I understand that's a lot more complex. I've been trying to compile with zig cc as that would allow cross-compilation later, but couldn't get it to work. I was able to get a build that didn't dynamically link to SDL2, but it would segfault.
In response to comments:
Running pkg-config --static --cflags --libs /usr/local/lib/pkgconfig/sdl2.pc gives:
-I/usr/local/include/SDL2 -D_REENTRANT -L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -lSDL2 -lm -ldl -lpthread -lrt
Using that creates a dynamically-linked executable, so not what I want. If I add -static I get the error:
/usr/bin/ld: /usr/local/lib/libSDL2.a(SDL_dynapi.o): in function `get_sdlapi_entry':
/home/makeworld/Software/SDL2-2.0.16/src/dynapi/SDL_dynapi.c:237: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Thanks to #HolyBlackCat and #keltar, I have been able to statically link SDL2.
I basically just used the output of pkg-config as provided in my question, but with the addition of -Wl,-Bstatic before -lSDL2 and -Wl,-Bdynamic after it. This statically links SDL2, but dynamically links all the other libraries.
The final command is:
gcc your_code.c -o your_executable -I/usr/local/include/SDL2 -D_REENTRANT \
-L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags \
-Wl,-Bstatic -lSDL2 -Wl,-Bdynamic -lm -ldl -lpthread -lrt
If your build of SDL2 is installed elsewhere, just change the /usr/local/include/SDL2 and /usr/local/lib part of the command to point to where the header files and .a files are respectively.
If I figure out how to cross-compile this setup, I will update this answer.
I have an installation of DPDK and I'm trying to compile code with it. This worked on my WSL machine, however on the test server, with the same install of dpdk, I'm getting the error:
/usr/local/include/rte_mempool.h: error: unknown type name 'ssize_t'
I've noticed this header does not include /sys/types.h, but it also doesn't include that on the machine that this works on. I don't know where it's supposed to come from, but it's coming from somewhere.
How do I get these headers to be aware of ssize_t?
As noted in a comment:
The compiler options include -std=c99 -O3 -march=native -I/usr/local/include -include rte_config.h, and a whole bunch of -l options (dpdk's make structure adds these in). This prompted me to run gcc --version and the working one is Ubuntu gcc 9.3.0 and the broken one is gcc 5.4.0. Seems like it might be an incompatibility between dpdk and the gcc installed.
As mentioned in the comments by #JonathanLeffier, the root cause of the issue is including sys/types.h when gcc option --std=c99 is passed. The easiest fix without modifying the DPDK or sample code is to include the path to types.h as part of cflags.
If the native build is for x86_64 target, follow these steps:
execute find /usr/include/ -name types.h to identify the right file for local build (this is because the current cflags has -march=native)
modify the CFLAGS from -std=c99 -O3 -march=native -I/usr/local/include -include rte_config.h to -std=c99 -O3 -march=native -I/usr/local/include -include rte_config.h --include=/usr/include/[target-machine]/sys/types.h
Note: In my humble suggestion please use pkg-config for populating the right CFLAGS and LDFLAGS for both shared and static binary.
I am unsure of what could be causing this as I have tried recompiling libcurl and using pre-compiled binaries.
My compiler command
x86_64-w64-mingw32-gcc -Wall -Lwin-lib -Iwin-lib -I./ -D WIN32 -D CURL_STATICLIB -mwindows ... -o win-export/SLM.exe -lm -lraylib -ltmx -lxml2 -lzlibstatic -lcurl
There aren't any compiler errors or linker errors. Is this a problem with my compiler? Or one the other libraries I am using?
My directory structure is:
── bin
│ ├── mylib-osx.so.1.72
│ ├── mylib.so.1.72
├── my.c
I am trying to compile my.c and link mylib-osx.so.1.72 (I'm on a macOS), but to no avail:
ld: library not found for -l:PhotoDNAx64.so.1.72
I tried:
gcc -o my -lmylib-osx my.c
gcc -o my -lmylib-osx.so.1.72 my.c
gcc -o my -lmylib my.c
gcc -o my -L./bin -lmylib-osx my.c
gcc -o my -L./bin -l:"mylib-osx.so.1.72" my.c
What am I doing wrong and why cannot the library be found?
What am I doing wrong and why cannot the library be found?
Read about Invoking GCC. You was wrong in not reading that (or any other documentation of gcc).
Order of program arguments to gcc matters a lot (and in practice several arguments are very useful, e.g. both -Wall and -g at least, and probably -v sometimes). You want something like
gcc -v -Wall -g my.c -lmylib-osx -o my
(also try variants of that), since gcc is running some ld or equivalent linker command, and if you want to pass some -Llib-directory use something like
gcc -v -Wall -g my.c -L./bin -lmylib-osx -o my
and you also need to read the documentation of MacOSX linker (probably named ld). You could also read Levine's Linkers and loaders book.
If you are not happy with gcc (but please use a recent version, so GCC 8 in 2019, not the crappy software sold by Apple named gcc) consider using Clang (a recent version too, e.g. Clang 8 in 2019). It has the same limitation regarding order of program arguments than gcc does (since order of program arguments even mattered for Unix or POSIX cc).
In general, read the documentation of a command before asking questions here about that command. A minima, man gcc on your Apple (or Linux) computer.
PS. The last time I have used some MacOSX was in 2004. My biased recommendation is to install and use Linux (which I use since 1993; I tried MacOSX around 2004 during less than a year, and have been disappointed both by the operating system, including its display server and GUI desktop environment, and by the Apple hardware).
I am attempting to compile
me#e:~/Dir$ gcc -O4 -o new new.c -Wall -pedantic -std=gnu11 -lm -fopenmp -static
which gives a warning
/usr/lib/gcc/x86_64-linux-gnu/5/libgomp.a(target.o): In function `gomp_target_init':
(.text+0xba): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
The goal is to make this program statically linked so 'new' will run on my laptop and the server.
how can I use 'shared libraries from the glibc version used for linking' in gcc or clang?