3 .c / .h文件和主文件之间的链接/ Makefile故障

时间:2018-10-13 02:53:02

标签: c makefile c99

我有2个.h文件包含功能定义,还有2个.c文件与.h文件相关。第三个.c文件(不是主要文件)具有头文件,并且希望使用其他2个.c文件中的功能。使用makefile:

CC=gcc
CFLAGS=-Wall -std=c99 -I headers

main: main.o carFunctions.o
        $(CC) $(CFLAGS) build/main.o build/carFunctions.o -o main
carFunctions.o: source/carFunctions.c
        $(CC) $(CFLAGS) -c  source/carFunctions.c -o build/carFunctions.o
linkedList.o: source/linkedList.c
        $(CC) $(CFLAGS) -c source/linkedList.c -o build/linkedList.o
fileManage.o: source/fileManage.c
        $(CC) $(CFLAGS) -c source/fileManage.c -o build/fileManage.o
main.o: source/main.c
        $(CC) $(CFLAGS) -c source/main.c -o build/main.o
clean:
        rm -i build/*.o

导致错误:

gcc -Wall -std=c99 -I headers -c source/main.c -o build/main.o
gcc -Wall -std=c99 -I headers -c  source/carFunctions.c -o build/carFunctions.o
source/carFunctions.c: In function ‘test’:
source/carFunctions.c:9:9: warning: ‘tes3t’ is used uninitialized in this function [-Wuninitialized]
   tes3t = push(tes3t,"TEST");
         ^
gcc -Wall -std=c99 -I headers build/main.o build/carFunctions.o -o main
build/carFunctions.o: In function `test':
carFunctions.c:(.text+0x15): undefined reference to `push'
collect2: error: ld returned 1 exit status
makefile:5: recipe for target 'main' failed
make: *** [main] Error 1

函数的三个.c文件如下:

carFunctions.c:

#include <stdio.h>
#include "carFunctions.h"
#include "linkedList.h"
#include "fileManage.h"

void test()
{
  LL* tes3t;
  tes3t = push(tes3t,"TEST");
  printf("it works?");
}

fileManage.c:

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

void test2()
{
  printf("fileman");
}

和linkedList.c:

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

struct LLStruct
{
  char* plateNum;
  struct LLStruct* next;
};

LL* push(LL* myList, char* data)
{
  LL* newNode = malloc(sizeof(LL));
  if(newNode != NULL)
  {
    newNode->plateNum = data;
    newNode->next = myList;
    return newNode;
  }
  else
  {
    return myList;
  }
}

头文件: carFunctions.h:

#ifndef CARFUN
#define CARFUN

void test();

#endif

fileManage.h:

#ifndef FILEMAN
#define FILEMAN

void test2();

#endif

linkedList.h:

#ifndef LINKLIST
#define LINKLIST

typedef struct LLStruct LL; // Defines a structure for linked lists as "LL"
LL* push(LL* myList, char* data); // Adds an item to the linked list
#endif

最后是main.c:

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

int main()
{
  test();
  return 0;
}

我不太清楚错误的出处,因为我认为没有遗漏的括号。可能是文件链接/ makefile,但是我对文件链接的检查还不够。

2 个答案:

答案 0 :(得分:2)

这里实际上发生了两件事:

  • 第一个:

    source/carFunctions.c: In function ‘test’:
    source/carFunctions.c:9:9: warning: ‘tes3t’ is used uninitialized in this function [-Wuninitialized]
       tes3t = push(tes3t,"TEST");
    

    这说明向您传递了一个未初始化的指针作为函数push的第一个参数。由于指针是未初始化的,因此它可以包含任何内容,可以指向内存中的任意位置,并且程序在运行时的行为可能会发生变化,具体取决于该内存地址处的内容。

    但是,这是一个警告,表示它最终不对构建过程的失败负责。 (警告通常会显示出以后会出现更多令人困惑的错误的根本原因,因此,请务必注意它们。)

  • 第二个:

    build/carFunctions.o: In function `test':
    carFunctions.c:(.text+0x15): undefined reference to `push'
    collect2: error: ld returned 1 exit status
    

    这向您显示链接器无法找到功能push的编译后的机器代码。在这种情况下,这是因为您只是没有在链接器命令行中包含包含该机器代码(linkedList.o)的目标文件。在不同情况下,这种错误有时可能意味着您在函数的定义中犯了一个错误,而忘记了包含适当的头文件以使编译器能够捕获该错误。

答案 1 :(得分:1)

首先,您应该纠正有关未初始化变量print()的警告。

鉴于您拥有/ home / me / src(例如):

将所有tes3t.c文件放入/ home / me / src / source

创建/ home / me / src / build

.h放在/ home / me / src

鉴于此,这是一个固定的Makefile:

Makefile

更好的是,这是一个使用通配符的简单版本:

CC=gcc
CFLAGS=-Wall -std=c99 -I headers

OBJS += build/main.o
OBJS += build/carFunctions.o
OBJS += build/linkedList.o
OBJS += build/fileManage.o

build/main: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) -o main

build/carFunctions.o: source/carFunctions.c
    $(CC) $(CFLAGS) -c  source/carFunctions.c -o build/carFunctions.o

build/linkedList.o: source/linkedList.c
    $(CC) $(CFLAGS) -c source/linkedList.c -o build/linkedList.o

build/fileManage.o: source/fileManage.c
    $(CC) $(CFLAGS) -c source/fileManage.c -o build/fileManage.o

build/main.o: source/main.c
    $(CC) $(CFLAGS) -c source/main.c -o build/main.o

clean:
    rm -f build/*.o build/main