如何在这个C程序中正确设置makefile并获得正确的结果

如何在这个C程序中正确设置makefile并获得正确的结果,c,makefile,C,Makefile,我编写了一个C代码,由以下文件组成:main.C、kernel.C、funzione.C、funzione.h和struttura.h。以下是文件: 主要条款c: funzione.cu funzione.h 斯特鲁图拉 我的目标是显示funzione.c文件中包含的值(我根本不想像struttura.h一样修改它)。但是,当我使用自己编写的makefile编译它时,我得到了以下结果: o.x=0.000000 o.y=0.000000 而不是值450和150 以下是make文件: enter

我编写了一个C代码,由以下文件组成:main.C、kernel.C、funzione.C、funzione.h和struttura.h。以下是文件:

主要条款c:

funzione.cu

funzione.h

斯特鲁图拉

我的目标是显示funzione.c文件中包含的值(我根本不想像struttura.h一样修改它)。但是,当我使用自己编写的makefile编译它时,我得到了以下结果:

o.x=0.000000
o.y=0.000000
而不是值450和150

以下是make文件:

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:无需为所有人执行任何操作。
在这种情况下,我需要执行
make clean
并再次编译以获得明显的错误消息:
错误:“struttura”没有名为“z”printf的成员(“o.x=%f\n”,o.z)

所以基本上我的问题是2:

  • 如何才能正确获得结果

  • 我应该如何修改makefile,以便每次修改kernel.c中的内容时它都能编译


您从未调用
funzione()
函数。您需要调用它并将指针传递给它,指向某个地方的
o

另外,您真的不应该在C文件上使用
#include
,而应该只在标题上使用

您需要从某处向
funzione.c
添加一个依赖项,这样
Make
就可以在需要时提取该依赖项并重新构建文件。比如:

eseguibile: main.o funzione.o

如果
kernel.c
发生更改,则应重新编译
main.c
,因为您将
kernel.c包含在其中,但
make
不知道依赖关系。您也可以将其添加到
main.o
,如下所示:

main.o: main.c funzione.h struttura.h kernel.c
    $(CC) -c $(CFLAGS) main.c
funzione(&o);
pincopallo();
return 0;
  • 修复错误:

    void funzione(struttura*a)

  • 未调用,也未指定o.x的值。在调用之前调用此函数

    pincopallo();
    
    总而言之 这样写:

    main.o: main.c funzione.h struttura.h kernel.c
        $(CC) -c $(CFLAGS) main.c
    
    funzione(&o);
    pincopallo();
    return 0;
    
  • 包含*.c文件不是很好的做法。 *.h文件用于包含。 创建kernel.h文件并添加到main.c和kernel.c中
  • #包括“kernel.h”

    写入pincopallo()的kernel.h声明:


    注意:在.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 $@ =========
        #
    
    name=eseguibile
    CC=gcc
    CFLAGS:=-Wall
    LIBS:=-lm
    SRC:=$(通配符*.c)
    对象:=$(SRC:.c=.o)
    HDR:=$(通配符*.h)
    .骗子:都是干净的
    全部:$(名称)
    $(名称):$(OBJ)
    #
    #=======$(名称)链接开始=========
    $(CC)-o$@$(OBJ)$(LIBS)
    #=======$(名称)链接完成==========
    #
    %.o:%.c$(HDR)
    #
    #=========开始$<到$@=========
    $(CC)$(CCFLAGS)-c$<-o$@-I。
    #=======结束$<到$@=========
    #
    清洁:
    rm-rf*.o$(名称)
    依赖项注释:仅在理解后使用以下内容
    #
    #创建依赖性文件--推理规则
    #(gcc具有不需要sed实用程序的参数)
    #
    %d.d:%
    #
    #=========开始$<到$@=========
    $(CC)-M$(CPPFLAGS)$<>$@.$$$\
    sed's,\($*\)\.o[:]*,\1.o$@:,g'<$@.$$>$@\
    rm-f$@$$$$
    #=======结束$<到$@=========
    #
    #使用编译器标志将.c文件编译成.o文件
    #--推理规则
    #
    %.o:%.c%.d生成文件
    #
    #=========开始$<到$@=========
    $(CC)$(CCFLAGS)-c$<-o$@-I。
    #=======结束$<到$@=========
    #
    
    清洁: rm-rf*.o*.d$(名称)

    #包括所有.d文件的内容
    #注意:.d文件包含:
    #.o:.c加上该.c文件的所有依赖项
    #即#include'd头文件
    #用ifneg包装。。。因此,当目标为“干净”时,不会重建*.d文件
    #
    ifneq“$(MAKECMDGOALS)”“干净”
    -包括美元(DEP)
    恩迪夫
    
    每个头文件都需要一个保护包装器,因此它不能在任何一个编译单元(源文件)中包含多次
    pincopallo();
    
    funzione(&o);
    pincopallo();
    return 0;
    
    void pincopallo(void);
    
    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 $@ =========
        #
    
    # 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