In my c/c++ mixed project, I'm building the source files of individual folders, archiving them with ar
into their own .a
files and then linking them all together at the final stage. So far so good. My question is, is it possible to hint any dynamic library dependencies at the ar
stage so, they don't have to be specified explicitly at the linking stage?
I mean, if a component depends on pthread and the final binary will need to link against it, possibly dynamically, can it not add this dependency to the archive, to be resolved later by the linker?
Would using the linker instead of ar
to create partially linked objects rather than archives provide any such facility to hint dynamic lib dependencies to be satisfied at the final linking stage?
You can use the 'l' option of GNU ar
.
As the man pages say:
l Specify dependencies of this library. The dependencies must immediately
follow this option character, must use the same syntax as the
linker command line, and must be specified within a single argument.
I.e., if multiple items are needed, they must be quoted to form
a single command line argument. For example
L "-L/usr/local/lib -lmydep1 -lmydep2"
ar
stores this data in a member "__.LIBDEP" which is embedded in the .a file and can be accessed with ar p mylib.a __.LIBDEP
$ cat static_lib_test.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <unistd.h>
_Noreturn void *start(void *arg)
{
fprintf(stderr, "child (%d) won!\n", gettid());
syscall(SYS_exit_group, EXIT_SUCCESS);
}
int main(int argc, const char *argv[])
{
pthread_t thread;
if (pthread_create(&thread, NULL, start, (void *) 0) < 0)
{
fprintf(stderr, "error: unable to create new thread\n");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Race begin!\n");
fprintf(stderr, "parent (%d) won!\n", gettid());
syscall(SYS_exit_group, EXIT_SUCCESS);
}
Compile:
$ gcc -Wall -c static_lib_test.c -o static_lib_test.o
Archive:
$ ar rcvsl "-L/usr/lib -lpthread" static_lib_test.a static_lib_test.o
Link:
$ gcc $(ar p static_lib_test.a __.LIBDEP | tr '\0' '\n') -o static_lib_test static_lib_test.a
Example run: $ ./static_lib_test
Race begin!
parent (13547) won!
Tested on: Linux arch 5.11.13-zen1-1-zen, GNU ar (GNU Binutils) 2.36.1