简体   繁体   English

makefile 和多个.c 源文件的“未定义引用”

[英]“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.我正在尝试使用 makefile 编译和链接 4.c 文件和 ah 文件的项目。 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. 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.如果我先运行 make clean,一切似乎都正常,但如果我更新源代码然后简单地运行 make,或者从终端运行 -f makefile,则一切正常。 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.对于它的价值,我可以在没有 makefile 的情况下从终端手动编译和链接所有内容,所以我认为问题可能与 makefile 或我构建文件的方式有关。 Any help is greatly appreciated.任何帮助是极大的赞赏。

The makefile looks like this: makefile 看起来像这样:

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: diffClock.c:

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

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

equal.c:等于.c:

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

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

nameDigit.c:名称Digit.c:

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

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

funcs.h:函数.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:最后 epsilon.c 仅由主要的 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:和终端 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.该变量扩展为通过调用 make 重建的 object 文件。 So if you only need to rebuild one object file, then you'll only link one object file, which is clearly wrong.所以如果你只需要重建一个 object 文件,那么你只会链接一个 object 文件,这显然是错误的。

You want to use $^ instead, which expands to all the object files listed as prerequisites regardless of whether they were rebuilt or not.您想改用$^ ,它会扩展到所有列为先决条件的 object 文件,无论它们是否被重建。

In GNU make $?在 GNU 中制作$? means all modified prerequisites.表示所有修改的先决条件。 You want $^ for all prerequisites.您需要$^来满足所有先决条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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