如何正确设置 makefile 并在此 C 程序中获得正确的结果
How to set up correctly makefile and get the right results in this C program
我写了一个由这些文件组成的 C 代码:main.c, kernel.c, funzione.c、funzione.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;
}
kernel.c
void pincopallo(void){
printf("o.x=%f\n",o.x);
printf("o.y=%f\n",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=%f\n",o.x);
更改为 printf("o.x=%d\n",o.x);
)并尝试再次编译,终端将显示以下消息:make: Nothing to be done for all.
在这种情况下,我需要执行 make clean
并再次编译以获得明显的错误消息:
error: ‘struttura’ has no member named ‘z’ printf("o.x=%f\n",o.z);
所以基本上我的问题是 2:
怎样才能得到正确的结果?
我应该如何修改 makefile 以便每次我修改 kernel.c[ 时它都能编译=22=]
您永远不会调用 funzione()
函数。您需要调用它并向其传递指向 o
某处的指针。
另外,你真的不应该在 C 文件上使用 #include
,只能在头文件上使用。
您需要从某处向 funzione.c
添加依赖项,以便 Make
可以选择它并在需要时重新构建文件。类似于:
eseguibile: main.o funzione.o
如果 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
修复错误:
void funzione(struttura* a)
未被调用并且 o.x 的值未被分配。在调用
之前调用这个函数
pincopallo();
在main.c
像这样写:
funzione(&o);
pincopallo();
return 0;
- include *.c 文件不是很好的做法。
*.h 文件用于包含。
创建 kernel.h 文件并添加到 main.c 和 kernel.c
#include "kernel.h"
写入 pincopallo() 的 kernel.h 声明:
void pincopallo(void);
注意:在 .c 文件中包含 .c 文件是一种非常糟糕的做法
像下面这样组织make文件会好很多
并从 main.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[ :]*,.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
我写了一个由这些文件组成的 C 代码:main.c, kernel.c, funzione.c、funzione.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;
}
kernel.c
void pincopallo(void){
printf("o.x=%f\n",o.x);
printf("o.y=%f\n",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=%f\n",o.x);
更改为 printf("o.x=%d\n",o.x);
)并尝试再次编译,终端将显示以下消息:make: Nothing to be done for all.
在这种情况下,我需要执行 make clean
并再次编译以获得明显的错误消息:
error: ‘struttura’ has no member named ‘z’ printf("o.x=%f\n",o.z);
所以基本上我的问题是 2:
怎样才能得到正确的结果?
我应该如何修改 makefile 以便每次我修改 kernel.c[ 时它都能编译=22=]
您永远不会调用 funzione()
函数。您需要调用它并向其传递指向 o
某处的指针。
另外,你真的不应该在 C 文件上使用 #include
,只能在头文件上使用。
您需要从某处向 funzione.c
添加依赖项,以便 Make
可以选择它并在需要时重新构建文件。类似于:
eseguibile: main.o funzione.o
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
修复错误:
void funzione(struttura* a)
未被调用并且 o.x 的值未被分配。在调用
之前调用这个函数pincopallo();
在main.c 像这样写:
funzione(&o);
pincopallo();
return 0;
- include *.c 文件不是很好的做法。 *.h 文件用于包含。 创建 kernel.h 文件并添加到 main.c 和 kernel.c
#include "kernel.h"
写入 pincopallo() 的 kernel.h 声明:
void pincopallo(void);
注意:在 .c 文件中包含 .c 文件是一种非常糟糕的做法
像下面这样组织make文件会好很多
并从 main.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[ :]*,.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