I want to create a static library implementing a TUI interface using ncurses. I'm new to this topic and applying these answers didn't work out for me.
I want to link varViewer.c in a library. I use this code to compile a example file.
Compiling src/example.c and src/viewer/varViewer.c:
gcc -Wall -Wextra -Wnonnull -Isrc/viewer/
-c src/example.c -o obs/example.o -lncurses
-fsanitize=undefined -fprofile-arcs -ftest-coverage -Winline -O2
gcc -Wall -Wextra -Wnonnull -Isrc/viewer/
-c src/viewer/varViewer.c -o obs/viewer/varViewer.o -lncurses
-fsanitize=undefined -fprofile-arcs -ftest-coverage -Winline -O2
Linking obs/example.o to bin/example:
gcc -o bin/example -Isrc/viewer/
obs/example.o obs/viewer/varViewer.o -lncurses
-fsanitize=undefined -fprofile-arcs -ftest-coverage -Winline -O2
bin/example works as expected. I tried to compile a suitable object file:
Compiling src/viewer/varViewer.c:
gcc -Wall -Wextra -Wnonnull -Isrc/viewer/
-c src/viewer/varViewer.c -o lib/objects/varViewer.o
-lncurses -fPIC -O2
and put it into library:
ar -cvr lib/libvarViewer.a lib/objects/varViewer.o
when I try to use it in other projects, a include it using
-L ..../src/viewer/lib -lvarViewer
flags but all references to functions I used from ncurses library and string.h are undefined:
nm /lib/libvarViewer.a
....
U __snprintf_chk
U __stack_chk_fail
U start_color
U stdscr
U strchr
U strlen
U strncmp
U strncpy
U strnlen
U waddnstr
U wborder
U wclear
U wcolor_set
U wgetnstr
U winsdelln
U winsnstr
U wmove
U wrefresh
What is the correct way to call ar? I already tried to produce a "thin" library using -T option.
The command
gcc -Wall -Wextra -Wnonnull -Isrc/viewer/
-c src/viewer/varViewer.c -o lib/objects/varViewer.o
-lncurses -fPIC -O2
will simply compile the varViewer.c file and thus, will ignore the libraries because it won't link to a final executable.
Consequently, the object file varViewer.o will have undefined references (U
reported in nm
as you have shown) to the symbols not defined within varViewer.c. These not only include the libncurses library but also the regular libc library (which provides symbols such as strlen
, strncpy
, ...). However, remember that libc
will be automatically added into your link stage by the compiler unless you explicitly state otherwise.
You could use the command ar x
to extract the object files (.o) from other static libraries and then use ar
again to generate a new library. While this is possible I don't think that including all the libraries into yours is a good idea. I think that it is better to link against all the libraries needed because that ensures that the application is linked against the latest version available -- while if you embed one library into yours, then will stick to that version until you upgrade it.