我正在尝试构建opentracker
。我的系统具有以下内容:
opentracker
查看| package | library | headers |
| lowfat | /usr/lib/libowfat.a | /usr/include/libowfat |
| dietlibc | /opt/diet/lib-x86_64/*.a | /usr/diet/include |
| glibc | /usr/lib/*.{a,so} | /usr/include |
的Makefile,我(基本上)看到以下内容:
opentracker
之前我没有针对替代项PREFIX?=..
LIBOWFAT_HEADERS=$(PREFIX)/libowfat
LIBOWFAT_LIBRARY=$(PREFIX)/libowfat
CFLAGS+=-I$(LIBOWFAT_HEADERS) -Wall -pipe -Wextra
LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lpthread -lz
opentrackers: $(OBJECTS) $(HEADERS)
cc -o $@ $(OBJECTS) $(LDFLAGS)
进行编译,因此,如果我做错了这一部分,我将包含此信息。调用libc
时,需要将其指向系统中存在make
和dietlibc
的位置。我正在这样做:
lowfat
好像有两个问题正在发生。
$ LDFLAGS=-L/opt/diet/lib-x86_64 make PREFIX=/opt/diet LIBOWFAT_HEADERS=/usr/include/libowfat LIBOWFAT_LIBRARY=/usr/lib
...
...
cc -o opentracker opentracker.o trackerlogic.o scan_urlencoded_query.o ot_mutex.o ot_stats.o ot_vector.o ot_clean.o ot_udp.o ot_iovec.o ot_fullscrape.o ot_accesslist.o ot_http.o ot_livesync.o ot_rijndael.o -L/opt/diet/lib-x86_64 -L/usr/lib -lowfat -pthread -lpthread -lz
/usr/bin/ld: /usr/lib/libowfat.a(io_fd.o):(.bss+0xb0): multiple definition of `first_deferred'; /usr/lib/libowfat.a(io_close.o):(.data+0x0): first defined here
...
... lots of warnings ...
/usr/bin/ld: opentracker.o: undefined reference to symbol '__ctype_b_loc@@GLIBC_2.3'
/usr/bin/ld: /usr/lib/libc.so.6: error adding symbols: DSO missing from command line
的多个定义我在first_deferred
和first_deferred
中都看到了对io_close
的引用,但它们位于不同的部分。
io_fd
在$ objdump -t /usr/lib/libowfat.a | egrep '^[^:]+.o:|first_deferred' | grep -B1 first_deferred
io_close.o: file format elf64-x86-64
0000000000000000 g O .data 0000000000000008 first_deferred
--
io_fd.o: file format elf64-x86-64
00000000000000b0 g O .bss 0000000000000008 first_deferred
--
io_waituntil2.o: file format elf64-x86-64
0000000000000000 *UND* 0000000000000000 first_deferred
中,有一个io/io_fd.c
,在该标头中,有一个#include io_internal.h
。在extern long first_deferred;
中定义为io/io_close.c
。因此,它似乎并没有在long first_deferred=-1
代码本身中被双重定义。我编译libowfat
错误吗?
[由于lowfat
试图针对Makefile
进行编译,所以我对dietlibc
的引用感到有些惊讶(但是,老实说,一点也不惊讶)。
这是glibc
的配方:
opentracker.o
这似乎没有用于主要可执行文件的cc -c -o opentracker.o -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -I/usr/include/libowfat -Wall -pipe -Wextra -O3 -DWANT_FULLSCRAPE opentracker.c
中的-L/opt/diet/lib-x86_64
参数。应该是?我不认为这是一个链接器参数,因此将其添加到compile命令中没有任何意义。我没有在目标文件中看到对LDFLAGS
的任何引用:
glibc
我无法为这些错误提供很好的解释,但是您的帖子帮助我对其进行了编译,因此我认为我要提及自己的所作所为。
“ first_deferred”错误似乎来自使用较新版本的$ objdump -t ./src/opentracker/opentracker.o | grep -c 'glib'
0
,我改用0.31克服了这个错误。
我没有遇到第二个错误,但是我遇到了“ __you_tried_to_link_a_dietlibc_object_against_glibc”错误,我通过卸载libowfat
并改为使用dietlibc
编译了libowfat
。
我以与AUR包相同的方式编译它们:
glibc
https://aur.archlinux.org/packages/opentracker/
尽管不是安装https://aur.archlinux.org/packages/libowfat/,我只是将其放在libowfat
目录中,并跳过了从CVS提取src
的操作。
我发现了两个排列来解决此问题。选项一是确保第一个libowfat
参数是-L
的lib目录的位置,以便所有符号都首先从该位置解析。
另一个排列是通过dietlibc
包装程序调用make。来自/opt/diet/bin/diet
the dietlibc
FAQ
据我所知,网站上的任何地方都没有解释包装程序的作用。由于所有特定于体系结构的dietlibc
,该代码令人讨厌阅读,但文件注释表明它只是以特定于体系结构的方式修改了Q: How do I install it? make install?
A: Yep. It will then install itself to /opt/diet, with the wrapper in
/opt/diet/bin/diet. Or you don't install it at all.
The diet libc comes with a wrapper called "diet", which can be found
in bin-$(ARCH)/diet, i.e. bin-i386/diet for most of us. Copy this
wrapper somewhere in your path (for example ~/bin) and then just
compile stuff by prepending diet to the command line, e.g. "diet gcc
-pipe -g -o t t.c".
Q: How do I compile programs using autoconf with the diet libc?
A: Set CC in the environment properly. For Bourne Shells:
$ CC="diet gcc -nostdinc" ./configure --disable-nls
That should be enough, but you might also want to set
--disable-shared and --enable-static for packages using libtool.
命令行。快速扫描表明相关的args修改包括:编译时为#ifdef
,链接时为gcc
,可能还包括-I/opt/diet/include
。
-nostdlib
的多个定义我对这里的解决方法不满意。该符号在-Os
中定义:
first_deferred
为什么对io_internal.h
关键字进行有趣的重新定义?继续阅读。此变量的初始化在#ifndef my_extern
#define my_extern extern
#endif
my_extern long first_deferred;
:
extern
这是有趣的一点。在io_close.c
:
#include "io_internal.h"
long first_deferred=-1;
为什么?谁知道。作者相信我猜他们很聪明,为自己节省了一些击键?这样的效果是io_fd.c
被定义为一个空字符串,因此当#define my_extern
#include "io_internal.h"
#undef my_extern
从标题中转写时,它会显示为my_extern
。这就是导致档案中该符号有两个位置的原因,因为有两个文件为该符号保留了空间。
我对我的“解决方案”不满意,该解决方案是从my_extern long first_deferred;
中删除静态初始化。从技术上讲,这意味着变量从随机堆内存开始。快速浏览一下它的用法表明这可能并不安全,但可能足够安全。该变量用作数组的索引。幸运的是long first_deferred;
进行了边界检查,因此io_close.c
很可能为false,并且该变量将被设置为iarray_get
。
if(e)