"undefined reference to" form cmake (translate a C project to C++)

Hi Everyone.
I try to translate a small C project to a C++ one. With modifing the .c to .cc and little modifing in the Makefile using g++.
But I have a following error with the structure of the translated c++ project

File Structure:
.
├── build
│   ├── assignment3.o
│   └── traceroute.o
├── compile_commands.json
├── libraw
│   ├── include
│   │   ├── checksums.h
│   │   ├── hexdump.h
│   │   └── raw.h
│   ├── libraw.a
│   ├── Makefile
│   └── src
│   ├── checksum.c
│   ├── checksum.o
│   ├── crc.c
│   ├── crc.o
│   ├── hexdump.c
│   ├── hexdump.o
│   ├── raw.c
│   ├── raw.o
│   └── timespec.h
├── Makefile
└── src
├── assignment3.cc
├── traceroute.cc
└── traceroute.h

5 directories, 21 files

Makefile for src/:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
TARGET=trace6
CC=g++ -std=c++17
LIBRAWDIR=libraw/
LIBRAW=$(LIBRAWDIR)libraw.a
LDFLAGS=$(LIBRAW)
CFLAGS+=-Wall -Wextra -g -fdiagnostics-color=auto -I$(LIBRAWDIR)include -fno-strict-aliasing
BUILDDIR=build

OBJECTS=build/traceroute.o build/assignment3.o

.PHONY: all clean fresh

all: $(TARGET)

$(TARGET): $(OBJECTS) $(LIBRAW)
	$(CC) $(OBJECTS) $(LDFLAGS) -o $(TARGET)

$(LIBRAW):
	$(MAKE) -C $(LIBRAWDIR)

$(BUILDDIR)/%.o: src/%.cc $(BUILDDIR)/.empty
	$(CC) $(CFLAGS) $< -c -o $@

.PRECIOUS: $(BUILDDIR)/.empty

$(BUILDDIR)/.empty:
	@mkdir -p $(BUILDDIR)
	@touch $@

clean:
	-rm -rf $(OBJECTS)
	-rm -rf $(BUILDDIR)
	-rm -f $(TARGET)
	-$(MAKE) -C $(LIBRAWDIR) clean

fresh: clean
	$(MAKE) all


1
2
3
4
5
6
7
8
9
10
11
make
g++ -std=c++17 build/traceroute.o build/assignment3.o libraw/libraw.a -o trace6
build/assignment3.o: In function `main':
Makefile:16: recipe for target 'trace6' failed
/home/jigao/Workspace/Netz_VM/u1824/assignment3/src/assignment3.cc:139: undefined reference to `parse_args(arguments*, int, char**)'
/home/jigao/Workspace/Netz_VM/u1824/assignment3/src/assignment3.cc:145: undefined reference to `grnvs_open(char const*, int)'
/home/jigao/Workspace/Netz_VM/u1824/assignment3/src/assignment3.cc:154: undefined reference to `grnvs_close(int)'
collect2: error: ld returned 1 exit status
make: *** [trace6] Error 1

Process finished with exit code 2


For example function parse_args(arguments*, int, char**) is already defined in the src/traceroute.cc
Last edited on
I think the problem is at in the makefile, maybe it lacks something?
Hoping you get what I mean.
Hello CakeByTheOcean,

This one is shout. Given the error message:
/home/jigao/Workspace/Netz_VM/u1824/assignment3/src/assignment3.cc:154: undefined reference to `grnvs_close(int)' . The "154" refers to line 154 of the source code and without the source code it is impossible to tell what is happening.

I believe the problems is not in the make file as most error messages tend to refer to something in the source code.

It sounds like you may be trying to call a function before it has been seen by the compiler and the compiler has nothing to reference to.

Here is an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

void foo()
{
	bar();

        // <--- Other code code.

}

void bar()
{
	// <--- Your code.
}

int main()
{
	foo();

	return 0;
}

When the compiler runs it compiles the function foo first and when foo calls bar it does not know about bar because it is not compiled yet.

Two ways to fix this problem:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

void bar()  // <--- Put bar first.
{
	// <--- Code.
}

void foo()
{
	bar();
}

int main()
{
	foo();

	return 0;
}


Or
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

// <--- Prototypes for the functions.
void foo();
void bar();

void foo()
{
	bar();
}

void bar()
{
	// <--- Code.
}

int main()
{
	foo();

	return 0;
}

A thought for now without seeing your code.

Hope that helps,

Andy
@Handy Andy: http://www.cplusplus.com/forum/general/113904/
«Undefined reference is a linker error not a compile error.»
your example will produce a compilation error

@CakeByTheOcean: do a clean build
> For example function parse_args(arguments*, int, char**) is already defined in the src/traceroute.cc
¿are you sure?
my guess is that you keep the old traceroute.o that was compiled with gcc (not g++) so the name mangling is different.

if you can't upload your project, try to reproduce the error in a minimal example
1
2
3
4
//traceroute.cc
void parse_args(arguments*, int, char**){}
void grnvs_open(char const*, int){}
void grnvs_close(int){}

1
2
3
4
5
6
//assignment3.cc
int main(int argc, char **argv){
	parse_args(NULL, argc, argv);
	grnvs_open("", 0);
	grnvs_close(42);
}

@ne555,

Thank you. Duly noted.

My experience has been as a linker error it usually starts in the code.

Andy
Topic archived. No new replies allowed.