-2

UPDATE: Found the problem. It was a bug on my end and had nothing to do with make. I had edited the file to remove the preprocessor conditional and botched it.

I am attempting to compile a testing program using a makefile to handle the creation of a library of files that include functions which are used by the test. When trying to make the final executable, I receive an 'undefined reference' error. Below is my makefile and the resulting output. I have tried switching up the ordering of files and operations within my makefile, but they all resulted in failure. That leads me to believe I am missing some key component to making it work instead of needing to reorder my operations.

I am running RHEL 4 if that matters.

CC=gcc
CFLAGS=-Wall
LDFLAGS=-lm
AR=ar

OBJ = \
    test.o \
    disk_alloc.o \
    stringtools.o \
    path.o \
    xxmalloc.o

LIB = libtest.a
PROG = test
TAR = $(LIB) $(PROG)

all: $(TAR)

libtest.a: $(OBJ)
    $(AR) -rv $(LIB) $(OBJ)
    ranlib $(LIB)

$(PROG):
    $(CC) $(CFLAGS) $(LIB) -o $@

clean:
    rm -f $(OBJ) $(TAR)

.PHONY: all clean

# vim: set noexpandtab tabstop=4:

Output after executing make:

gcc -Wall   -c -o test.o test.c
gcc -Wall   -c -o disk_alloc.o disk_alloc.c
gcc -Wall   -c -o stringtools.o stringtools.c
gcc -Wall   -c -o path.o path.c
gcc -Wall   -c -o xxmalloc.o xxmalloc.c
ar -rv libtest.a test.o disk_alloc.o stringtools.o path.o xxmalloc.o
ar: creating libtest.a
a - test.o
a - disk_alloc.o
a - stringtools.o
a - path.o
a - xxmalloc.o
ranlib libtest.a
gcc -Wall libtest.a -o test
libtest.a(test.o): In function `disk_alloc_test_empty':
test.c:(.text+0x5f): undefined reference to `disk_alloc_create'
test.c:(.text+0x81): undefined reference to `disk_alloc_delete'
libtest.a(test.o): In function `disk_alloc_test_read_write':
test.c:(.text+0x17b): undefined reference to `disk_alloc_create'
test.c:(.text+0x1e0): undefined reference to `disk_alloc_delete'
libtest.a(test.o): In function `disk_alloc_test_nested':
test.c:(.text+0x30a): undefined reference to `disk_alloc_create'
test.c:(.text+0x372): undefined reference to `disk_alloc_create'
test.c:(.text+0x410): undefined reference to `disk_alloc_delete'
test.c:(.text+0x426): undefined reference to `disk_alloc_delete'
collect2: ld returned 1 exit status
make: *** [test] Error 1
Duder
  • 1
  • 3
  • 2
    Are `disk_alloc_create` and `disk_alloc_delete` in `disk_alloc.c`? Can you see those symbols in the `disk_alloc.o` file and the `libtest.a` library? Also you realize RHEL 4 is **very** old and full of **gaping** security holes, right? (As well as being entirely unmaintained at this point.) – Etan Reisner Sep 30 '15 at 15:48
  • Disregarding talk of gaping holes, yes those two functions are in disk_alloc.c and are present in the library. – Duder Sep 30 '15 at 15:51
  • @etan-reisner Looking at the disk_alloc.o file, I actually found that the symbols for disk_alloc_create and disk_alloc_delete are not found, but they are in the library. What causes this discrepancy and how can I resolve it? – Duder Sep 30 '15 at 15:58
  • When you say "they are in the library" you mean you can find them in the `libtest.a` file? Or in the source? If they are in the library then things should be working I think. If they are only in the source then they either aren't marked for export or gcc is choosing not to include them in the object file for some reason I can't imagine. – Etan Reisner Sep 30 '15 at 15:59
  • They are found in the libtest.a file, but not in disk_alloc.o. – Duder Sep 30 '15 at 16:01
  • That is certainly odd and I can't explain that. (I don't see how that's possible actually unless they are coming from some other object in the `.a` library.) And actually, have you tried simply putting `test.o` *after* `disk_alloc.o` in the library? (Hm... actually that's probably the wrong order now that I think about it.) – Etan Reisner Sep 30 '15 at 16:02
  • Rearranging the order of the object files did not seem to have an impact either way. – Duder Sep 30 '15 at 16:23
  • Can you show the definitions of the functions in the `disk_alloc.c` file? If you clean up all the `.a` and `.o` files and start building from scratch does this problem repeat (exactly)? – Etan Reisner Sep 30 '15 at 16:28
  • Check the source posted in my question for the definitions. If I clean up and rebuild, the problem still persists. – Duder Sep 30 '15 at 16:36
  • I can check out that exact repository, dump that exact Makefile in the `dttools/src` directory and run it (with a shim `test.c` that just lists the functions for symbol purposes) and I get an error about `cctools_debug` being a missing symbol but nothing about `disk_alloc_(create|delete)`. On CentOS 5 that is. Could this be a tooling issue of the ancient RHEL 4 toolsets? – Etan Reisner Sep 30 '15 at 16:50
  • Found the problem. It was a bug on my end and had nothing to do with make. I had edited the file to remove the preprocessor conditional and botched it. – Duder Sep 30 '15 at 17:04

1 Answers1

2

You forgot to link your object files $(OBJ) and you might not need any $(LIB), so replace

$(PROG):
    $(CC) $(CFLAGS) $(LIB) -o $@

with

$(PROG): $(OBJ)
    $(CC) $(CFLAGS) $^ -o $@

If you absolutely want to have your library, you'll need to link an object file providing main outside of it. Probably keep $(LIB) but remove test.o from definition of OBJ, and do

$(PROG): test.o $(LIB)
     $(CC) $(CFLAGS) $^ -o $@

Read more about automatic variables in make

And indeed, you should upgrade your Linux distribution (using RHEL4 is not reasonable these days). If possible, in 2015, use one with GCC 5 & make 4.... Consider also using remake to debug your Makefile-s. See also the links in this answer (including examples of short Makefile-s)

BTW, static libraries are generally obsolete, and in your case it might not worth having a library (even a shared one). If you really want one, make it shared, and read Program-Library-HowTo & Drepper's paper: How to Write a Shared Library

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks for the speedy reply. Unfortunately, this produces a heap of 'multiple definition' errors for all the functions found in the library and still leaves the 'undefined reference' errors at the end of the command. Any other info I can give you? – Duder Sep 30 '15 at 15:57
  • The OP is linking the `libtest.a` library and so doesn't need the individual object files. – Etan Reisner Sep 30 '15 at 15:58
  • This answer still does not resolve the 'undefined reference' errors stemming from disk_alloc_create and disk_alloc_delete. I have removed reference to the library and just used the object files as well as removing only test.o and compiling that separately using your above suggestion. Both yield the same result. Seeing as neither disk_alloc_create nor disk_alloc_delete are found in the disk_alloc.o file, that leads me to believe something has gone wrong there, but I am not sure what. – Duder Sep 30 '15 at 16:14
  • We can't help more without the entire source code that your are compiling. – Basile Starynkevitch Sep 30 '15 at 16:16
  • You should have mentioned that in your question, certainly not in a comment – Basile Starynkevitch Sep 30 '15 at 16:23