错误:使用 makefile 在 C 中未定义对“proccess_External”的引用

error: undefined reference to `proccess_External' in C using makefile

提问人:Roy Shiff 提问时间:3/28/2021 更新时间:3/28/2021 访问量:98

问:

我有我写的这两个文件:

external_handling.c

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ library description. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of library description. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ #includes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "general_helper.h"
#include "label_handling.h"
#include "label.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of #includes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ #defines. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#define EXTERNALVALUE 0

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of #defines. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ prototypes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

/* proccess a file of external type */
void proccess_External(list* list, char* line,char* type);

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of prototypes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ functions. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

/* proccess a file of external type */
void proccess_External(list* list, char* line,char* type)
{

/* gets the global variable line_num */
    extern int line_num;
/* cuts the line in peices by tabs and spaces to check if its has ant syntax error */
    char* label = strtok(line," \t");
    char* string = strtok(NULL," \t");
/* calls a function to check if the label name is legal*/
    if(check_Label_Name(label) != True)
    {
        printf("Error, line %d: expected operand of type label_name, but found ilegal operand type(%s)\n", line_num, label);
    }
    else
    {
    /* if label has a legal name adds it to the labels list*/
        add_Node(list, label, EXTERNALVALUE, type);
    }
/* continue checking the string for errors */
    while (string != NULL)
    {
        printf("Error, line %d: expected no more operand, instead foun the operand - %s ",line_num,string);
        string=strtok(NULL," \t");
    }
    free(label);
}

/* proccess a file of entry type */
void proccess_Entry(list* list, char* line,char* type)
{
/* gets the global variable line_num */
    extern int line_num;

/* cuts the line in peices by tabs and spaces to check if its has ant syntax error */
    char* label = strtok(line," \t");
    char* string = strtok(NULL," \t");

/* calls a function to check if the label name is legal*/
    if(check_Label_Name(label) != True)
    {
        printf("Error, line %d: expected operand of type label_name, but found ilegal operand type(%s)\n",line_num,label);
    }
    else
    {
    /* if label has a legal name adds it to the labels list*/
        add_Node(list,label,line_num,type);
    }

/* continue checking the string for errors */
    while (string != NULL)
    {
        printf("Error, line %d: expected no more operand, instead foun the operand - %s ",line_num,string);
        string=strtok(NULL," \t");
    }

    free(label);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of functions. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

external_handling.h

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ library description. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of library description. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#ifndef EXTERNAL_HANDLING
#define EXTERNAL_HANDLING



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ #includes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */




#include "label.h"

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of #includes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ #defines. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#define EXTERNALVALUE 0

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of #defines. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */



/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ prototypes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

/* proccess a file of external type */
void proccess_External(list* list, char* line,char* type);

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ end of prototypes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */


#endif

我写了一个main只是为了测试文件是否有效

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "data_handling.h"
#include "general_helper.h"
#include "label.h"
#include "external_handling.h"
#include "entry_handling.h"
#define AS ".as"
#define OB ".ob"
#define ENT ".ent"
#define EXT ".ext"
#define DATA "data"
#define CODE "code"
#define LINE_LENGTH 81
#define ICS 100
#define DCS 0
int IC = ICS;
int DC = DCS;
int line_num=0;
flag errors=False;
int main(int argc, char* argv[])
{
    list* list=malloc(sizeof(list));
    char* a;
    char* type="entry";
    int i;
    FILE* source;
    FILE* code;
    FILE* data;
    char* fp="stam.txt";
    char* line="BBB";
    char* label_name;

    a = (char*)malloc(sizeof(char)*50);

    strcpy(a," 1a ,,-2  3a ,    , 3 ,, 6     \n");
    /*data=fopen("doc1.txt","r");*/
    
    if(data == NULL)
    {
            printf("Error!");   
            exit(1);             
    }
    proccess_External(list, line,type); --------> function i get the error
    /*proccess_Data_Line(a,data);*/
    free(a);
    return 1;
}

我写了一个 makefile f来连接每个文件

生成文件

run: main *.o
    gcc -g -ansi -std=c90 -Wall -pedantic *.o -o main
    
main.o: main.c data_handling.h general_helper.h label_handling.h label.h external_handling.h entry_handling.h
    gcc -c -g -Wall -pedantic -ansi -std=c90 main.c

data_handling.o: data_handling.c general_helper.h label.h
    gcc -c -g -Wall -pedantic -ansi -std=c90 data_handling.c

label.o: label.c general_helper.h
    gcc -c -g -Wall -pedantic -ansi -std=c90 label.c

general_helper.o: general_helper.c 
    gcc -c -g -Wall -pedantic -ansi -std=c90 general_helper.c

label_handling.o: label_handling.c general_helper.h
    gcc -c -g -Wall -pedantic -ansi -std=c90 label_handling.c

external_handling.o: external_handling.c general_helper.h label_handling.h label.h
    gcc -c -g -Wall -pedantic -ansi -std=c90 external_handling.c

entry_handling.o: entry_handling.c general_helper.h label_handling.h label.h
    gcc -c -g -Wall -pedantic -ansi -std=c90 entry_handling.c

all : run

当我尝试在终端中构建时,出现此错误

cc   main.o   -o main
main.o: In function `main':
/home/user/Desktop/testing/main.c:45: undefined reference to `proccess_External'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'main' failed
make: *** [main] Error 1

我找了几个小时,都搞不清问题出在哪里。 我该如何解决这个问题?

c makefile 未定义引用

评论

0赞 Roy Shiff 3/28/2021
那么我该放什么呢?只是主要的?
0赞 kaylum 3/28/2021
一个主要问题:你没有目标。也就是说,您没有告诉 make 如何构建,因此它使用的是默认规则,当然不会链接到您的所有对象。mainmain
0赞 Roy Shiff 3/28/2021
那么我应该在那里写什么来修复它?
0赞 William Pursell 3/28/2021
显式列出对象文件,而不是使用 ,并更改为*.orunmain
0赞 Roy Shiff 3/28/2021
好吧,我现在更改了它,我收到此错误:valgrind:./main:权限被拒绝

答:

0赞 Orielno 3/28/2021 #1

当你写的时候,你告诉makefile使用你目录中所有以结尾的现有文件,但是如果这些目标文件还没有创建呢?*.o.o

相反,您应该告诉 makefile 采用所有以 结尾的文件名,将 替换为 ,这就是您想要的目标文件列表。喜欢这个:.cco

OBJ = $(patsubst %.c,%.o,$(wildcard *.c))
main: $(OBJ)
    gcc -g -ansi -std=c90 -Wall -pedantic $^ -o main

评论

0赞 Roy Shiff 3/28/2021
对不起,我不确定我是否了解我应该在哪里编写所有 .o 文件
0赞 MadScientist 3/28/2021 #2

问题在于这条规则:

run: main *.o

它有两个问题。第一个问题,即您看到的问题,是您列为目标的先决条件,但您实际上并没有在 makefile 中的任何位置创建规则来构建。mainrunmain

因为没有要构建的规则,所以查看其内置规则目录,并发现它有一个规则可以从同名文件构建任何可执行文件。这就是它的作用,但这当然是错误的,因为为了构建一个可执行文件,你也需要所有其他目标文件,你没有告诉你需要这些文件。main.omain

第二个问题是如上@Orielno所讨论的。*.o

如果你用他们答案中提供的目标替换你的目标,那么它就会起作用。run