【问题标题】:Makefile for beginners适合初学者的 Makefile
【发布时间】:2015-02-11 17:26:20
【问题描述】:

我刚开始学习makefile:我自己创建了一个简单的教程,但似乎我在某个地方弄错了,我不知道在哪里;我的迷你教程由一个 main.c 脚本组成,该脚本调用了一个名为 kernel.c 的函数;在最后一个函数中,调用了另外 2 个函数:add.c(将 2 个数字相加)和 mul.c(将前一个总和的结果相乘);然后我创建了头文件 kernel.hfunctions.h ,其中包含上面定义的函数的原型;这两个标头包含在同一 main.c 脚本之一中创建的文件夹中:common/inc

这里是文件:

//main
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"

int main(){
int a = 5, b = 4, c = 0;
int *pa, *pb, *pc;
pa = &a; pb = &b; pc = &c;

kernel(pa, pb, pc);

printf("c = %d\n", c);

return 0;
}

这里是 kernel.c

#include "kernel.h"
#include "functions.h"

void kernel(int* a, int*b, int* c){
 int x = add(*a,*b);
 *c = mul(x);
}

这里是 add.c

#include "functions.h"

int add(int a, int b){
return a + b;
}

这里是 mul.c

#include "functions.h"

int mul(int a){
return a*2;
}

这里是 kernel.h

void kernel(int* a, int*b, int* c);

这里是函数.h

int add(int a, int b);
int mul(int a);

我写的make文件是这样的:

#===========================Makefile================================#

CC=gcc
IDIR = common/inc
CFLAGS=-c -Wall -I$(IDIR)

all: eseguibile

eseguibile: main.o  
    $(CC) $(CFLAGS) main.o -o eseguibile

main.o: main.c kernel.o
    $(CC) $(CFLAGS) main.c kernel.o

kernel.o: kernel.c add.o mul.o
    $(CC) $(CFLAGS) kernel.c add.o mul.o

add.o: add.c 
    $(CC) $(CFLAGS) add.c

mul.o: mul.c 
    $(CC) $(CFLAGS) mul.c

clean:
    rm -rf *o eseguibile

我知道程序可以正常工作,因为如果我在终端中输入gcc main.c kernel.c add.c mul.c -I common/inc/,一切正常。

谁能告诉我我做错了什么?`

我得到的错误是这样的:

gcc -c -Wall -Icommon/inc add.c
gcc -c -Wall -Icommon/inc mul.c
gcc -c -Wall -Icommon/inc kernel.c add.o mul.o
gcc: warning: add.o: linker input file unused because linking not done
gcc: warning: mul.o: linker input file unused because linking not done
gcc -c -Wall -Icommon/inc main.c kernel.o
gcc: warning: kernel.o: linker input file unused because linking not done
gcc -c -Wall -Icommon/inc main.o -o eseguibile
gcc: warning: main.o: linker input file unused because linking not done

【问题讨论】:

  • 你遇到了什么错误?
  • 您是否使用制表符或空格来缩进$(CC) $(CFLAGS) ...?因为make 需要标签。
  • 是的!我只是无法在 stackoverflow 中复制标签,但我原来的 makefile 中的标签已正确完成
  • 我认为问题在于您在最终的可执行文件中包含了 -c 标志。
  • 这将有助于未来的智慧寻求者使问题标题尽可能具体。例如。 为什么gcclinker input file unused because linking not done

标签: c makefile dependencies


【解决方案1】:

我更喜欢单独构建对象,然后在最后将它们全部组合起来。我认为问题在于您在最终可执行文件中包含-c 标志。试试这个:

#===========================Makefile================================#

CC=gcc
IDIR = common/inc
CFLAGS=-Wall -I$(IDIR)
OBJS = main.o kernel.o add.o mul.o

all: eseguibile

eseguibile: $(OBJS)
    $(CC) $(CFLAGS) $^ -o eseguibile

main.o: main.c kernel.h
    $(CC) -c $(CFLAGS) main.c

kernel.o: kernel.c kernel.h functions.h
    $(CC) -c $(CFLAGS) kernel.c

add.o: add.c functions.h
    $(CC) -c $(CFLAGS) add.c

mul.o: mul.c functions.h
    $(CC) -c $(CFLAGS) mul.c

clean:
    rm -rf *.o eseguibile

【讨论】:

  • 成功了!!!我不得不通过删除包含在 common/inc 文件夹中的 kernel.h 来稍微修改它;除此之外它还有效......非常感谢!
  • 请记住,现在目标(main.okernel.o 等)仅依赖于一个文件,因此如果您修改 kernel.h,例如,makefile 将获胜不知道哪些目标需要重建。因此,您可能希望将 .h 文件作为依赖项添加到使用它们的目标中。否则你会发现自己在make clean; make 做很多事情。
  • 我更新了我发布的 makefile 以包含您上面列出的 .h 依赖项,只是为了让您了解它的外观。基本上,依赖项所做的只是告诉 make“如果此文件上的时间戳发生更改,则重建目标”
  • 我正要问你为什么要添加kernel.h,因为我不知道,事实上我总是不得不做很多make clean 来编译我的代码我做了一些改变,很好。
  • make clean 是一个很好的健全性检查,但如果你经常这样做,这可能意味着你的一些目标缺少依赖项。如果您的项目开始变大,编译器也可以为您自动生成依赖项 - scottmcpeak.com/autodepend/autodepend.htmlstackoverflow.com/questions/2394609/…
猜你喜欢
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-17
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多