Compilers and Targets¶
Support Matrix¶
compiler |
Compile command | Static library | Shared library | Executable |
|---|---|---|---|---|
gxx |
gcc (.c) / g++ (others) |
ar |
g++ -shared |
g++ -s |
llvm |
clang |
ar |
clang++ -shared (untested) |
clang++ -s (untested) |
msvc |
cl |
ar |
Not implemented, exits with an error | Not implemented, exits with an error |
The compile command is chosen by the source file suffix: .c goes to the C compiler, .cc / .cpp to the C++ compiler.
Why shared libraries and executables are linked through the compiler driver
Early versions called ld -shared directly, which produced shared libraries without runtime dependencies such as libstdc++; loading them with dlopen or from a plain C host failed on undefined C++ symbols. Everything now goes through the compiler driver, which brings in the crt and the caller's runtime libraries.
Target Types¶
target_type |
Artifact | Link command essentials |
|---|---|---|
static |
lib<project>.a |
ar csr, followed by an automatic strip --strip-unneeded after the build |
shared |
lib<project>.so |
-shared -o, with -lm linked explicitly |
exe |
<project> |
-s, plus compile_args and whatever link arguments you configured |
Shared Library Notes¶
Compile arguments need -fPIC, otherwise object files cannot go into a shared library. The template generated by antel init already includes it, and the tool will not add it again automatically:
Link arguments starting with -l (such as -lpthread) are recognized as system libraries:
Versioned Shared Libraries¶
Give a shared library a version number and antel produces libX.so.<version> (e.g. libX.so.1.0.0) and automatically creates the symlinks libX.so.1 and libX.so, adding -Wl,-soname to the link command:
{
"target_type": "shared",
"version": "1.0.0",
"soname": "libX.so.1", // optional; defaults to the major version of `version`
"rpath": ["$ORIGIN/lib"] // optional; where consumers look for the library at runtime
}
Consumers link and load against the SONAME ($ORIGIN in rpath expands at runtime to the executable's directory, so copying the whole output tree still works):
Verification: readelf -d shows the SONAME, and ldd resolves against the SONAME rather than by file name. See the antelstats demo in Examples for a complete example.
Switching Compilers¶
To build the same project with a different compiler, use a different configuration file; the two output directories do not interfere with each other:
antel rebuild -f gcc # reads gcc.json, outputs to <project>_gcc/
antel rebuild -f clang # reads clang.json, outputs to <project>_clang/
FAQ¶
Error Command execution failed (exit code 127) ... command not found or not executable: cl
It means msvc was used, but the current environment has no cl (or that compiler's link path is not implemented yet). Use gxx or llvm on Linux.
Undefined symbols at link time
First check log/linkInfor, which holds the linker's full output. A common cause in C++ projects is source files being compiled as C (the suffix was written as .c), or missing link arguments of the -l form.
The generated executable's size looks wrong
exe targets link with -s, which removes the symbol table; static libraries are stripped with strip --strip-unneeded after the build. To keep debug symbols, add -g to compile_args and take out these stripping steps yourself.