1

I'm trying to compile a C program linking two previously created object files but keep getting an 'undefined reference' error.

I'm using Visual Code to write the code and Ubuntu on Windows to compile using a makefile. The two C files, task5.c and reverse.c which have been made into object files both contain #include reverse.h statements which contains the prototypes for the functions in reverse.c.

task5.c

#include <stdio.h>
#include "ctap.h"
#include "reverse.h"

TESTS {
    const char *a = "Family";
    char *b = reverse(a);

    //test 1
    ok(string_length(a) == string_length(b), "Strings are the same size");

    //test 2
    is("ylimaF", b, "Strings match");
}

reverse.c

#include <stdio.h>
#include <stdlib.h>
#include "reverse.h"

char *reverse(const char *str) {
    //code
}

int string_length(const char *str) {
    //code
}

reverse.h

char *reverse(const char *str);
int string_length(const char *str);

makefile

linked:
    gcc -o linked task5.o reverse.o

task5.o
    gcc -c -o task5.o task5.c

reverse.o
    gcc -c -o reverse.o reverse.c

When I run the command make linked I expect it to be made and return nothing.

But when I run that command I get this error:

cc   task5.o   -o linked
task5.o: In function `ctap_tests':
task5.c:(.text+0x1abe): undefined reference to `reverse'
task5.c:(.text+0x1ace): undefined reference to `string_length'
task5.c:(.text+0x1adc): undefined reference to `string_length'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'linked' failed
make: *** [task5] Error 1
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Nathan
  • 21
  • 2
  • 3
    You have a makefile which links both object files. But you don't seem to be using it? Or using an old makefile? Because the output you show doesn't match the makefile you show. – Some programmer dude Apr 10 '19 at 06:28
  • https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix describes the topic (C++ centered, but probably generally also helpful for C). – Yunnosch Apr 10 '19 at 06:31
  • @Someprogrammerdude What part doesn't match? If you're referring to the 'In function `ctap_tests':' ctap_tests is there because the macro TESTS{} expands to 'void ctap_tests(void)' according to VSCode when I hover over TESTS{} in task5.c. – Nathan Apr 10 '19 at 06:42
  • Ah, I've just tried compiling it using 'gcc -o linked task5.o reverse.o' instead of make linked and it worked. I'm not sure why it would be using another make file but thanks for getting me to check it out, it's definitely something wrong with the make file. – Nathan Apr 10 '19 at 06:49
  • Try using the `ls` command to list the files in the current directory. Do you have multiple "makefiles" (and remember that Linux filesystems are case-sensitive)? If there's only one, if you type it (with the `cat` command) is it the one you expect? – Some programmer dude Apr 10 '19 at 06:57
  • The ls command still only shows the one makefile as 'makefile.mk', when i use the cat command it is the exact same makefile as what I see in VSCode so I'm not sure what other makefile would be being referenced and why the output isn't the same. – Nathan Apr 10 '19 at 07:17
  • 1
    Try to rename it `Makefile` – Phantom Apr 10 '19 at 07:19

1 Answers1

1

According to this GNU make documentation, the GNU make program will try to use GNUMakefile, makefile or Makefile.

The make program will not try makefile.mk, which means that e.g. make linked will use no makefile and only the default rules.

You can solve this by either renaming your makefile as Makefile (the most common) or makefile; Or by using the -f option to specify the makefile

$ make -f makefile.mk linked
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thankyou! You were right, it was the way VSCode named the makefile when i saved it, I just rewrote it in notepad++ and saved it as just makefile (VSCode wouldn't let me) and it worked! – Nathan Apr 10 '19 at 07:51