views:

109

answers:

1

I decided it would be a fun side project to do some work on tsocks, since it hasn't seen any updates in 8 years. It's hosted here on GitHub.

I only made cosmetic changes to the code so far, but now I've run into a compiler error. According to dlopen(3):

The obsolete symbols _init() and _fini()

[...]

Using these routines [...] is not recommended. Their use may result in undesired behavior, since the constructor/destructor routines will not be executed (unless special measures are taken).

Instead, libraries should export routines using the __attribute__((constructor)) and __attribute__((destructor)) function attributes.

Unfortunately, this change (commit f785c8e) seems to be the source of the compiler error:

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

Can anyone help me? I'm stumped.

+1  A: 

You're trying to create a shared library as if it were an executable. This is what you want:

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

The critical part is the addition of -shared. I also fixed you to have a soname, which you must have and handle correctly if you want Linux distributions to pick up your library, but if you don't know what it is, don't worry about it till you get it to the point of wanting to make an official release - at which point, time to read up on it in all gory detail. I don't, unfortunately, know a good place to point you at.

This doesn't actually have anything to do with _init/_fini versus __attribute__((constructor)) - I'm amazed it worked at all.

Zack
That worked. The `ln` lines aren't necessary; `make install` ends up creating the links. I guess I'll have to read up on autoconf and libraries. I love jumping into projects unprepared; I get to learn all this new stuff. Thanks!
Nomexous