简体   繁体   中英

“undefined reference to” with makefile and multiple .c source files

I am trying to compile and link a project of 4.c files and ah files using a makefile. I am having some issues with the linking stage, and i can't seem to figure out what the issue is. I have included the main structure of the programs below without the actual code (since i don't have any issues with the code itself).

The files are epsilon.c (the main project file), funcs.h which has the function declarations, and diffClock.c, equal.c and nameDigit.c which has function implementations. This is homework.

Everything seems to work all right if i run make clean first, but not if i update source code and then simply run make, or make -f makefile from the terminal. For what it's worth i can compile and link everything manually from the terminal without the makefile, so i think the issue might be with the makefile, or the way i have constructed the files. Any help is greatly appreciated.

The makefile looks like this:

CFLAGS   =  -fwrapv # This is a macro definition
LDFLAGS  =  -lm

OBJECTS =  epsilon.o diffClock.o equal.o nameDigit.o funcs.h

default : out.txt
    cat out.txt

out.txt : epsilon                 
    ./$< > $@      

epsilon : $(OBJECTS) # epsilon depends on epsilon.o
    $(CC) $? -o $@ $(LDFLAGS)                   

.PHONEY: clean
clean:                         
    rm -f out.txt epsilon $(OBJECTS) 

diffClock.c:

#include <time.h>
#include "funcs.h"

double diffClock(clock_t clock1, clock_t clock2)
{
    // some code...
}

equal.c:

#include "funcs.h"
#include <math.h>

int equal(double a, double b, double tau, double epsilon){
// some code...
}

nameDigit.c:

#include <stdio.h>
#include "funcs.h"

void name_digit( int dig ){
// some code...
}

funcs.h:

#ifndef EPSILON_FUNCS_H
#define EPSILON_FUNCS_H
#include <time.h>

extern double diffClock(clock_t clock1, clock_t clock2);

extern int equal(double a, double b, double tau, double epsilon);

extern void name_digit( int dig );

#endif //EPSILON_FUNCS_H

lastly epsilon.c is simply consisting of the main function:

#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <float.h>
#include "funcs.h"

int main(){
  // some code...
  return 0;
}

and the terminal output:

make
gcc -fwrapv    -c -o epsilon.o epsilon.c
gcc epsilon.o -o epsilon -lm                    # Now we link the object file to an output program ('-o') called epsilon.
/usr/bin/ld: epsilon.o: in function `main':
epsilon.c:(.text+0x90): undefined reference to `diffClock'
/usr/bin/ld: epsilon.c:(.text+0xd8): undefined reference to `diffClock'
/usr/bin/ld: epsilon.c:(.text+0x11e): undefined reference to `diffClock'
/usr/bin/ld: epsilon.c:(.text+0x1dd): undefined reference to `diffClock'
/usr/bin/ld: epsilon.c:(.text+0x225): undefined reference to `diffClock'
/usr/bin/ld: epsilon.o:epsilon.c:(.text+0x26b): more undefined references to `diffClock' follow
/usr/bin/ld: epsilon.o: in function `main':
epsilon.c:(.text+0x8b7): undefined reference to `name_digit'
collect2: error: ld returned 1 exit status
make: *** [makefile:37: epsilon] Error 1

You should not use $? in your link line.

That variable expands to the object files that were rebuilt by this invocation of make. So if you only need to rebuild one object file, then you'll only link one object file, which is clearly wrong.

You want to use $^ instead, which expands to all the object files listed as prerequisites regardless of whether they were rebuilt or not.

In GNU make $? means all modified prerequisites. You want $^ for all prerequisites.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM