Search code examples
cgccstatic-librariesncursesunix-ar

Create static library including ncurses


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.


Solution

  • 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.