Node.JS
Node.JS

Reputation: 1570

GCC: link error while linking files from parent directory

I am getting a link error while including C files from a parent directory. I appreciate any help or hint.

hashcons_test.c imports

#include "hashcons.h"   // I have tried "../hashcons.h" but no success 

#include "stdbool.h"
#include "stdio.h"
#include "stdlib.h"

Makefile

CC=gcc 
CFLAGS=-I ..

all: output test clean
output: driver.o
    $(CC) $(CFLAGS) hashcons_test.o driver.o -o output

prime.o: ../prime.h ../prime.c
    $(CC) -c $(CFLAGS) ../prime.c -o ../prime.o

hashcons.o: prime.o ../hashcons.h ../hashcons.c
    $(CC) -c $(CFLAGS) ../hashcons.h -o ../hashcons.o

hashcons_test.o: hashcons.o hashcons_test.c
    $(CC) -c $(CFLAGS) hashcons_test.c

driver.o: hashcons_test.o
    $(CC) -c $(CFLAGS) driver.c -o driver.o

test: output
    @./output

clean:
    @rm -rf *.o output

Directory

.
├── hashcons.c
├── hashcons.h
├── prime.c
├── prime.h
└── tests
    ├── Makefile
    ├── driver.c
    ├── driver.o
    ├── hashcons_test.c
    └── hashcons_test.o

Error:

gcc  -c -I .. ../prime.c -o ../prime.o
gcc  -c -I .. ../hashcons.h -o ../hashcons.o
gcc  -c -I .. hashcons_test.c
gcc  -c -I .. driver.c -o driver.o
gcc  -I .. hashcons_test.o driver.o -o output
Undefined symbols for architecture x86_64:
  "_hash_cons_get", referenced from:
      _new_hash_cons_integer in hashcons_test.o
      _new_hash_cons_integer in driver.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [output] Error 1

hash_cons_get is a function defined in hascons.h

Upvotes: 1

Views: 196

Answers (1)

Zeta
Zeta

Reputation: 105876

You never link hashcons.o into output. As neither hashcons_test.o nor driver.o contain the necessary symbols, you're getting a linker error. You have to adjust your rule for output:

output: driver.o
    $(CC) $(CFLAGS) hashcons_test.o hashcons.o driver.o -o output
#                                   ^^^^^^^^^^

However, you should go a step further and properly list all dependencies and use $^ (for all dependencies) instead:

output: driver.o hashcons_test.o hashcons.o
    $(CC) $(CFLAGS) $^ -o $@

Note that this has nothing to do with your #includes. #includes are completely resolved in the pre-processor phase and not regarded during linking.

Upvotes: 2

Related Questions