我想创建一个使用ncurses实现TUI接口的静态库。我是这个主题的新手,应用这些答案并不奏效 出来给我。
我想在库中链接varViewer.c。我使用此代码编译示例文件。
编译src / example.c和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
将obs / example.o链接到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按预期工作。我试图编译一个合适的目标文件:
编译src / viewer / varViewer.c:
gcc -Wall -Wextra -Wnonnull -Isrc/viewer/
-c src/viewer/varViewer.c -o lib/objects/varViewer.o
-lncurses -fPIC -O2
并将其放入库中:
ar -cvr lib/libvarViewer.a lib/objects/varViewer.o
当我尝试在其他项目中使用它时,请使用
包含它-L .... / src / viewer / lib -lvarViewer
标志但是我从ncurses库和。中使用的函数的所有引用 string.h未定义:
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
调用ar的正确方法是什么?我已经尝试过生产一种“瘦身”的产品。库使用-T选项。
答案 0 :(得分:0)
命令
gcc -Wall -Wextra -Wnonnull -Isrc/viewer/
-c src/viewer/varViewer.c -o lib/objects/varViewer.o
-lncurses -fPIC -O2
将简单地编译varViewer.c文件,因此将忽略库,因为它不会链接到最终的可执行文件。
因此,目标文件varViewer.o将在varViewer.c中未定义的符号中具有未定义的引用(在U
中报告nm
,如您所示)。这些不仅包括libncurses库,还包括常规libc库(提供strlen
,strncpy
等符号)。但是,请记住编译器会自动将libc
添加到链接阶段,除非您另有说明。
您可以使用命令ar x
从其他静态库中提取目标文件(.o),然后再次使用ar
生成新库。虽然这是可能的,但我并不认为将所有库包含在您的库中是一个好主意。我认为最好链接所有需要的库,因为这可以确保应用程序与最新版本的链接相关联 - 而如果您将一个库嵌入到您的库中,那么在升级之前将坚持使用该版本。