我写了一个C代码,它由以下文件组成:main.C、kernel.Cfunzione.Cunzione.h和struttura.h。以下是文件:
main.c:
#include <math.h>
#include "stdio.h"
#include "struttura.h"
#include "funzione.h"
struttura o;
#include "kernel.c"
int main(void){
pincopallo();
return 0;
}
内核.c
void pincopallo(void){
printf("o.x=%fn",o.x);
printf("o.y=%fn",o.y);
}
funzione.cu
#include "struttura.h"
void funzione(struttura* a){
(*a).x = 450;
(*a).y = 150;
}
funzione.h
#include "struttura.h"
void funzione(struttura* a);
struttura.h
#ifndef STRUTTURA_H
#define STRUTTURA_H
typedef struct{
float x;
float y;
}struttura;
#endif /* STRUTTURA_H */
我的目标是显示funzione.c文件中包含的值(我根本不想像struttura.h那样修改它)。然而,当我用我自己编写的makefile编译它时,我得到了以下结果:
o.x=0.000000
o.y=0.000000
而不是值450和150。
这是制作文件:
enter CC=gcc
CFLAGS=-Wall
OBJS = main.o funzione.o
all: eseguibile
eseguibile: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o eseguibile -lm
main.o: main.c funzione.h struttura.h
$(CC) -c $(CFLAGS) main.c
funzione.o: funzione.c funzione.h struttura.h
$(CC) -c $(CFLAGS) funzione.c
clean:
rm -rf *.o eseguibilecode here
(注意标签)。我确信makefile不是完全正确的:事实上,如果第一次运行它,它会一直编译。但是,如果我修改了kernel.c中的某些内容(例如,我将printf("o.x=%fn",o.x);
更改为printf("o.x=%dn",o.x);
)并尝试再次编译,终端将显示以下消息:make: Nothing to be done for all.
在这种情况下,我需要执行make clean
并再次编译,以获得明显的错误消息:error: ‘struttura’ has no member named ‘z’ printf("o.x=%fn",o.z);
所以基本上我的问题是2:
我如何才能正确地得到结果?
我应该如何修改makefile,以便每次我修改kernel.c中的内容时它都会编译
kernel.c
发生更改,则应重新编译main.c
,因为#include
kernel.c在其中,但make
不知道依赖关系。您也可以将其添加到main.o
中,如下所示:
main.o: main.c funzione.h struttura.h kernel.c
$(CC) -c $(CFLAGS) main.c
您永远不会调用funzione()
函数。您需要调用它,并将一个指向o
的指针传递给它。
此外,您真的不应该在C文件上使用#include
,只应该在头文件上使用。
您需要从某个地方向funzione.c
添加一个依赖项,这样Make
就可以在需要时获取该依赖项并重新构建文件。类似于:
eseguibile: main.o funzione.o
修复错误:
void funzione(struttura* a)
未调用,并且未为o.x分配值。在调用之前调用此函数
pincopallo();
大体上。c这样写:
funzione(&o);
pincopallo();
return 0;
- 包含*.c文件不是很好的做法。*.h文件,用于包含。创建kernel.h文件并添加到main.c和kernel.c中
#include "kernel.h"
写入pincopallo()的kernel.h声明:
void pincopallo(void);
注意:在.c文件中包含.c文件是一种非常糟糕的做法
最好像下面的一样组织make文件
并从主.c文件中删除#include"kernel.c"
除此之外,这将是一件好事,尤其是当项目更大,还可以生成依赖文件请参阅末尾的注释,了解实现此操作的方法。
name = eseguibile
CC=gcc
CFLAGS :=-Wall
LIBS := -lm
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
HDR := $(wildcard *.h)
.PHONY: all clean
all: $(name)
$(name): $(OBJ)
#
# ======= $(name) Link Start =========
$(CC) -o $@ $(OBJ) $(LIBS)
# ======= $(name) Link Done ==========
#
%.o: %.c $(HDR)
#
# ========= START $< TO $@ =========
$(CC) $(CCFLAGS) -c $< -o $@ -I.
# ========= END $< TO $@ =========
#
clean:
rm -rf *.o $(name)
dependency notes: only use the following after understanding it
#
#create dependancy files -- inference rule
# (gcc has parameters that do not require the sed utility)
#
%.d: %.c
#
# ========= START $< TO $@ =========
$(CC) -M $(CPPFLAGS) $< > $@.$$$$;
sed 's,($*).o[ :]*,1.o $@ : ,g' < $@.$$$$ > $@;
rm -f $@.$$$$
# ========= END $< TO $@ =========
#
# compile the .c file into .o files using the compiler flags
# -- inference rule
#
%.o: %.c %.d makefile
#
# ========= START $< TO $@ =========
$(CC) $(CCFLAGS) -c $< -o $@ -I.
# ========= END $< TO $@ =========
#
清洁:rm-rf*.o*.d$(名称)
# include the contents of all the .d files
# note: the .d files contain:
# <filename>.o:<filename>.c plus all the dependancies for that .c file
# I.E. the #include'd header files
# wrap with ifneg... so will not rebuild *.d files when goal is 'clean'
#
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEP)
endif