Ошибка компилятора при замене устаревшей void _init () на __attribute ((конструктор)) - PullRequest
0 голосов
/ 27 июля 2010

Я решил, что это будет забавный сторонний проект - поработать над tsocks, так как он не видел обновлений за 8 лет. Хостинг здесь на GitHub.

Пока я только внес косметические изменения в код, но теперь я столкнулся с ошибкой компилятора. Согласно dlopen(3):

Устаревшие символы _init () и _fini ()

[...]

Использование этих подпрограмм [...] не рекомендуется. Их использование может привести к нежелательному поведению, поскольку процедуры конструктора / деструктора не будут выполняться (если не будут приняты специальные меры).

Вместо этого библиотеки должны экспортировать подпрограммы с использованием атрибутов функции __attribute __ ((конструктор)) и __attribute __ ((деструктор)).

К сожалению, это изменение (commit f785c8e), похоже, является источником ошибки компилятора:

gcc -fPIC -g -O2 -Wall -I. -c  tsocks.c -o tsocks.o
gcc -fPIC -g -O2 -Wall -I. -c  common.c -o common.o
gcc -fPIC -g -O2 -Wall -I. -c  parser.c -o parser.o
gcc -fPIC -g -O2 -Wall -I. -static -o saveme saveme.c
gcc -fPIC -g -O2 -Wall -I. -o inspectsocks inspectsocks.c common.o -lc
gcc -fPIC -g -O2 -Wall -I. -o validateconf validateconf.c common.o parser.o -lc
gcc -fPIC -g -O2 -Wall -I. -o libtsocks.so.1.8 tsocks.o common.o parser.o  -ldl  -lc -rdynamic
/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status

Кто-нибудь может мне помочь? Я в тупике.

1 Ответ

1 голос
/ 27 июля 2010

Вы пытаетесь создать общую библиотеку, как если бы она была исполняемым файлом. Это то, что вы хотите:

SONAME = libtsocks.so.1

$(SHLIB): $(OBJS) $(COMMON).o $(PARSER).o
    $(SHCC) -shared -Wl,-soname,$(SONAME) $(CFLAGS) $(INCLUDES) -o $(SHLIB) \
    $(OBJS) $(COMMON).o $(PARSER).o $(SPECIALLIBS) $(LIBS) -rdynamic
    ln -sf $(SHLIB) $(SONAME)
    ln -sf $(SONAME) libtsocks.so

Важной частью является добавление -shared. Я также установил, что у вас есть soname , который вы должны иметь и правильно обрабатывать, если вы хотите, чтобы дистрибутивы Linux собирали вашу библиотеку, но если вы не знаете, что это такое, не беспокойтесь об этом пока вы не дойдете до того, что захотите сделать официальный релиз - в этот момент, время, чтобы прочитать его во всех подробностях. К сожалению, я не знаю хорошего места, на которое можно указать вам.

Это на самом деле не имеет ничего общего с _init / _fini против __attribute__((constructor)) - я удивлен, что это сработало вообще.

...