Linker not finding symbols which should be present

123 Views Asked by At

Recently I took it upon myself to see if I could get devd from the FreeBSD project to build and run on OpenBSD. In doing so, I found that the application itself was not fairly large, so it was not too much work to go through and find what I needed to do in order to make up for the missing system calls. All was well and good. However, it did not seem to link. Except for a few things relating to configuration files which I deemed seemingly discardable within this context, the Makefile of the project is exactly that which is present in the directory in the FreeBSD source. I have seen this kind of this happen with yacc before, but I do not have the knowledge necessary to know how to resolve this. This is seemingly the only thing preventing me from testing it at this point.

Well, there was one include in the Makefile which was FreeBSD specific. I commented it out to see what that would do. It appeared to me that the include was necessary for a conditional statement about configuration files to theoretically be used by the daemon after it is already in production. Nothing to do fundamentally with the build process. After that, I did what any person trying to port software would do - I began the compilation process and started looking at all of the errors that the compiler was shooting back at me, and seeing if I could refactor it to work with the system being ported to. That part work fairly well, and I was able to eliminate all compiler errors and warning. I was expecting the Makefile provided would be sufficient to build the application for me.

Here is the error I was left with:

foo$ make devd
c++ -O2 -pipe   -MD -MP   -o devd devd.cc 
ld: error: undefined symbol: yyin
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::parse_one_file(char const*))

ld: error: undefined symbol: lineno
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::parse_one_file(char const*))
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(new_match)

ld: error: undefined symbol: yyparse
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::parse_one_file(char const*))

ld: error: undefined symbol: pidfilefoo$ make devd
c++ -O2 -pipe   -MD -MP   -o devd devd.cc 
ld: error: undefined symbol: yyin
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::parse_one_file(char const*))

ld: error: undefined symbol: lineno
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::parse_one_file(char const*))
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(new_match)

ld: error: undefined symbol: yyparse
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::parse_one_file(char const*))

ld: error: undefined symbol: pidfile
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::open_pidfile())
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(main)
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(main)
c++: error: linker command failed with exit code 1 (use -v to see invocation)
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(config::open_pidfile())
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(main)
>>> referenced by devd.cc
>>>               /tmp/devd-e407ee.o:(main)
c++: error: linker command failed with exit code 1 (use -v to see invocation)

And here is the BSD-style Makefile I was using to attempt to build this

# $FreeBSD$

#.include <src.opts.mk>

WARNS?= 3
PACKAGE=devd
CONFGROUPS= CONFS DEVD
CONFS=  devd.conf
DEVD=   devmatch.conf
DEVDDIR=    /etc/devd
#.if ${MK_ACPI} != "no"
#DEVD+= asus.conf
#.endif

#.if ${MK_HYPERV} != "no"
#CONFGROUPS+=   HYPERV
#HYPERVDIR=${DEVDDIR}
#HYPERV+=   hyperv.conf
#HYPERVPACKAGE= hyperv-tools
#.endif

#.if ${MK_USB} != "no"
#DEVD+= uath.conf ulpt.conf
#.endif

#.if ${MACHINE_ARCH} == "powerpc"
#DEVD+= apple.conf
#.endif

#.if ${MK_ZFS} != "no"
#DEVD+= zfs.conf
#.endif

PROG_CXX=devd
SRCS=   devd.cc token.l parse.y y.tab.h
MAN=    devd.8 devd.conf.5

LIBADD= util

YFLAGS+=-v
CFLAGS+=-I. -I${.CURDIR}
CFLAGS.clang += -Wno-missing-variable-declarations
CFLAGS.gcc = -Wno-redundant-decls
CXXFLAGS.gcc = -Wno-redundant-decls

CLEANFILES= y.output y.tab.i

HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests

.include <bsd.prog.mk>

You can find the project's source on GitHub here

Thank you all very much in advance for your time, attention, effort, and thoughtful answers. Community is important!

1

There are 1 best solutions below

0
On BEST ANSWER

Since I knew that the system binary 'config' in the '/sbin' directory of the OpenBSD source tree also uses YACC, I decided that I would try simple making a very simple replicate Makefile out of the useful information gained from that Makefile. That proved successful in this case...

.include <bsd.own.mk>

PROG= devd

SRCS= devd.cc parse.y token.l

DPADD += ${LIBUTIL}
LDADD += -lutil

MAN= devd.8 devd.conf.5

.include <bsd.prog.mk>

As one can see, it is relatively short, simple, sweet, and straight to the point. It did not require much at all to be successful. However, I think the problem here simply lied in the slight difference in the 'make' systems between FreeBSD and OpenBSD. In any case, this build, and the pidfile handling should be all squared away, in line with the OpenBSD process. All other systems call conflicts have been resolved. Now all that is left to do with is is install and test!