Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Makefile:将对象编译到源文件夹_C_Makefile - Fatal编程技术网

C Makefile:将对象编译到源文件夹

C Makefile:将对象编译到源文件夹,c,makefile,C,Makefile,我有下面的makefile # project name (generate executable with this name) TARGET = tp3 CC = gcc -std=c99 -c # compiling flags here CFLAGS = -Wall -I. -Werror-implicit-function-declaration LINKER = gcc -o # linking flags here LFLAGS = -Wall #

我有下面的makefile

# project name (generate executable with this name)
TARGET   = tp3

CC       = gcc -std=c99 -c
# compiling flags here
CFLAGS   = -Wall -I. -Werror-implicit-function-declaration

LINKER   = gcc -o
# linking flags here
LFLAGS   = -Wall

# debug flags here
DFLAGS   = -g -DDEBUG

SOURCES  := $(shell find . -type f -name '*.c')
INCLUDES  := $(shell find . -type f -name '*.h')
OBJECTS  := $(SOURCES:.c=.o)
rm       = rm -rf

$(TARGET): obj
    @$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

obj: $(SOURCES) $(INCLUDES)
    @$(CC) $(CFLAGS) -DNDEBUG $(SOURCES)
    @echo "Compilation complete!"

#debug:
#   gcc $(DFLAGS) $(SOURCES) -o $(TARGET)   

dobj: $(SOURCES) $(INCLUDES)
    @$(CC) $(CFLAGS) $(DFLAGS) $(SOURCES)
    @echo "dlinking complete!"

debug: dobj
    @$(LINKER) $(TARGET) $(LFLAGS) $(DFLAGS) $(OBJECTS) -o $(TARGET)
    @echo "dcompilation complete!"

run:
    ./tp3

clean:
    @$(rm) $(TARGET) $(OBJECTS) *.dSYM
    @echo "Cleanup complete!"

问题是:我在CMM/CMM文件夹中有文件,对象假定对象也在CMM/CMM文件夹中,但编译器将它们放在根文件夹中。如何让编译器在CMM/CMM中编译.o文件,或者告诉模式替换程序
对象:=$(源代码:.c=.o)
所有内容都在根文件夹中?

您真正的问题是没有使用make提供的工具来简化任务。
此外,您的编译器正在将所有
.o
文件放在根文件夹中,因为您没有告诉他不要这样做,或者让make为您这样做

以下是工作生成文件:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)

# Preprocessor flags here
CPPFLAGS    :=  -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) *.dSYM
    @echo "Cleanup complete!"
Make有一组内置的变量和规则,您应该使用它们来避免浪费时间和遇到简单的错误

请注意,此Makefile不能很好地处理依赖项,仅向Makefile添加
.h
文件列表是不够的。您可以通过让编译器在编译
.o
文件时动态创建依赖项文件来解决此问题,例如:

  • 构建
    .d
    文件名的列表:
    DEP:=$(OBJ:.o=.d)
  • 告诉编译器生成相应的文件,将
    -MMD-MP
    开关添加到
    CPPFLAGS
    内置变量
  • 将它们包含在Makefile中,以便它分析它们的内容:
    -Include$(DEP)
  • 不要忘记清理它们,将
    $(DEP)
    添加到
    清理
    目标中的
    $(RM)
    命令中
结果:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)
DEP :=  $(OBJ:.o=.d)

# Preprocessor flags here
CPPFLAGS    :=  -MMD -MP -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

-include $(DEP)

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) $(DEP) *.dSYM
    @echo "Cleanup complete!"

如果您有任何问题,请继续。

您真正的问题在于您没有使用make提供的工具来简化您的任务。
here are the contents of two makefile items.
 a top level makefile the drives the makefile.bot
the makefile.bot handles files/executables in other directorys
these makefiles also use recursion to produce the dependency lists
so only those header files that are actually include'd in the source
are listed as dependencies for that source.
Note: there are several common .c and .h files in the top level directory
      so they are compiled first, then referenced later
      when performing the link activity in each of the sub directories
Note: the 'AllDirectorys' is a list of the sub directories 
      where source code is to be compiled/linked in individual executables
Note: this is setup to run on Linux, and uses linux shell commands
      and certain utilities, like 'sed'

file: makefile.mak (the top level file)

    SHELL = /bin/sh


#  note: this makefile.mak needs to be run from the ./src directory
# of the GOT4 directory tree


SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp

MV      :=  mv

LDFLAGS :=  -L/usr/local/lib -L/usr/lib -L/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

LIBS    :=  -lssl -ldl -lrt -lz -lc -lm -lcrypto



.PHONY: AllDirectories
# the following statement needs to be edited as
# subdirectories are added/deleted/re-named
AllDirectories := \
    CommandConfiguration \
    Communication \
    MainScheduler \
    RetrieveCDSLog \
    RetrieveEventRecorderLog \
    RetrieveGPS \
    QESRouter



#AllDirectories :=  \
#    MainScheduler \
#    Communication  \
#    RetrieveGPS   \
#    TestCommunicationDev



.PHONY: all
#all: $(OBJ) $(AllDirectories)
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak name=Tsk_$d all ); )

all: $(OBJ) $(AllDirectories)
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d all ); )



#
# create dependancy files
#
%.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
#
%.o: %.c %.d
    #
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I.
    # ========= END $< TO $@ =========
    #



.PHONY: clean
#clean: $(AllDirectories)
#   # ========== start clean activities ==========
#   rm -f *.o
#   rm -f $(name).map
#   rm -f $(name)
#   rm -f *.d
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end clean activities ==========

clean: $(AllDirectories)
    # ========== start clean activities ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    rm -f ../bin/Tsk_*
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d clean ); )
    # ========== end clean activities ==========



.PHONY: install
#install: $(AllDirectories)
#   # ========== start install activities ==========
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end install activities ==========

install: $(AllDirectories)
    # ========== start install activities ==========
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d install ); )
    # ========== end install activities ==========



# include the contents of all the .d files
# note: the .d files contain:
# <filename>.o:<filename>.c plus all the dependancies for that 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


file: makefile.bot  which only occurs once, in the top level directory
along side the above listed makefile.mak

SHELL = /bin/sh


BINDIR  :=  /home/user/bin


.PHONY: all
all : $(BINDIR)/$(name) ../makefile.mak ../makefile.bot


#
# macro of all *.c files 
# (NOTE:
# (the following 'wildcard' will pick up ALL .c files
# (like FileHeader.c and FunctionHeader.c 
# (which should not be part of the build
# (so be sure no unwanted .c files in directory
# (or change the extension
#
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


COMMON_OBJ := $(wildcard ../*.o)
#COMMON_SRC := $(wildcard ../*.c)
#COMMON_OBJ := $(COMMON_SRC:.c=.o)
#COMMON_DEP := $(COMMON_SRC:.c=.d)
#COMMON_INC := $(COMMON_SRC:.c=.h)

MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp -f

MV      := mv

LDFLAGS :=  -L/usr/local/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

#LIBS    :=  -lidn -lssl -ldl -lrt -lz -lc -lm
LIBS    :=   -lssl -ldl -lrt -lz -lc -lm -lcrypto



#
# link the .o files into the executable 
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ) $(COMMON_OBJ) ../makefile.mak ../makefile.bot
    #
    # ======= $(name) Link Start =========
    $(CC) $(LDFLAGS) -o $@ $(OBJ) $(COMMON_OBJ) $(LIBS)
    # ======= $(name) Link Done ==========
    #



# note:
# using MV rather than CP results in all executables being re-made everytime
$(BINDIR)/$(name): $(name)
    #
    # ======= $(name) Copy Start =========
    $(CP) $(name) $(BINDIR)/
    # ======= $(name) Copy Done ==========
    #



#
#create dependancy files -- inference rule
#
%.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 
    # 
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I. 
    # ========= END $< TO $@ =========
    # 



.PHONY: clean
clean: 
    # ========== CLEANING UP ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    # ========== DONE ==========



.PHONY: install
install: all

# 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
此外,您的编译器正在将所有
.o
文件放在根文件夹中,因为您没有告诉他不要这样做,或者让make为您这样做

以下是工作生成文件:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)

# Preprocessor flags here
CPPFLAGS    :=  -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) *.dSYM
    @echo "Cleanup complete!"
Make有一组内置的变量和规则,您应该使用它们来避免浪费时间和遇到简单的错误

请注意,此Makefile不能很好地处理依赖项,仅向Makefile添加
.h
文件列表是不够的。您可以通过让编译器在编译
.o
文件时动态创建依赖项文件来解决此问题,例如:

  • 构建
    .d
    文件名的列表:
    DEP:=$(OBJ:.o=.d)
  • 告诉编译器生成相应的文件,将
    -MMD-MP
    开关添加到
    CPPFLAGS
    内置变量
  • 将它们包含在Makefile中,以便它分析它们的内容:
    -Include$(DEP)
  • 不要忘记清理它们,将
    $(DEP)
    添加到
    清理
    目标中的
    $(RM)
    命令中
结果:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)
DEP :=  $(OBJ:.o=.d)

# Preprocessor flags here
CPPFLAGS    :=  -MMD -MP -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

-include $(DEP)

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) $(DEP) *.dSYM
    @echo "Cleanup complete!"

如果您有任何问题,请继续。

您真正的问题在于您没有使用make提供的工具来简化您的任务。
here are the contents of two makefile items.
 a top level makefile the drives the makefile.bot
the makefile.bot handles files/executables in other directorys
these makefiles also use recursion to produce the dependency lists
so only those header files that are actually include'd in the source
are listed as dependencies for that source.
Note: there are several common .c and .h files in the top level directory
      so they are compiled first, then referenced later
      when performing the link activity in each of the sub directories
Note: the 'AllDirectorys' is a list of the sub directories 
      where source code is to be compiled/linked in individual executables
Note: this is setup to run on Linux, and uses linux shell commands
      and certain utilities, like 'sed'

file: makefile.mak (the top level file)

    SHELL = /bin/sh


#  note: this makefile.mak needs to be run from the ./src directory
# of the GOT4 directory tree


SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp

MV      :=  mv

LDFLAGS :=  -L/usr/local/lib -L/usr/lib -L/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

LIBS    :=  -lssl -ldl -lrt -lz -lc -lm -lcrypto



.PHONY: AllDirectories
# the following statement needs to be edited as
# subdirectories are added/deleted/re-named
AllDirectories := \
    CommandConfiguration \
    Communication \
    MainScheduler \
    RetrieveCDSLog \
    RetrieveEventRecorderLog \
    RetrieveGPS \
    QESRouter



#AllDirectories :=  \
#    MainScheduler \
#    Communication  \
#    RetrieveGPS   \
#    TestCommunicationDev



.PHONY: all
#all: $(OBJ) $(AllDirectories)
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak name=Tsk_$d all ); )

all: $(OBJ) $(AllDirectories)
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d all ); )



#
# create dependancy files
#
%.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
#
%.o: %.c %.d
    #
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I.
    # ========= END $< TO $@ =========
    #



.PHONY: clean
#clean: $(AllDirectories)
#   # ========== start clean activities ==========
#   rm -f *.o
#   rm -f $(name).map
#   rm -f $(name)
#   rm -f *.d
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end clean activities ==========

clean: $(AllDirectories)
    # ========== start clean activities ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    rm -f ../bin/Tsk_*
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d clean ); )
    # ========== end clean activities ==========



.PHONY: install
#install: $(AllDirectories)
#   # ========== start install activities ==========
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end install activities ==========

install: $(AllDirectories)
    # ========== start install activities ==========
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d install ); )
    # ========== end install activities ==========



# include the contents of all the .d files
# note: the .d files contain:
# <filename>.o:<filename>.c plus all the dependancies for that 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


file: makefile.bot  which only occurs once, in the top level directory
along side the above listed makefile.mak

SHELL = /bin/sh


BINDIR  :=  /home/user/bin


.PHONY: all
all : $(BINDIR)/$(name) ../makefile.mak ../makefile.bot


#
# macro of all *.c files 
# (NOTE:
# (the following 'wildcard' will pick up ALL .c files
# (like FileHeader.c and FunctionHeader.c 
# (which should not be part of the build
# (so be sure no unwanted .c files in directory
# (or change the extension
#
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


COMMON_OBJ := $(wildcard ../*.o)
#COMMON_SRC := $(wildcard ../*.c)
#COMMON_OBJ := $(COMMON_SRC:.c=.o)
#COMMON_DEP := $(COMMON_SRC:.c=.d)
#COMMON_INC := $(COMMON_SRC:.c=.h)

MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp -f

MV      := mv

LDFLAGS :=  -L/usr/local/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

#LIBS    :=  -lidn -lssl -ldl -lrt -lz -lc -lm
LIBS    :=   -lssl -ldl -lrt -lz -lc -lm -lcrypto



#
# link the .o files into the executable 
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ) $(COMMON_OBJ) ../makefile.mak ../makefile.bot
    #
    # ======= $(name) Link Start =========
    $(CC) $(LDFLAGS) -o $@ $(OBJ) $(COMMON_OBJ) $(LIBS)
    # ======= $(name) Link Done ==========
    #



# note:
# using MV rather than CP results in all executables being re-made everytime
$(BINDIR)/$(name): $(name)
    #
    # ======= $(name) Copy Start =========
    $(CP) $(name) $(BINDIR)/
    # ======= $(name) Copy Done ==========
    #



#
#create dependancy files -- inference rule
#
%.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 
    # 
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I. 
    # ========= END $< TO $@ =========
    # 



.PHONY: clean
clean: 
    # ========== CLEANING UP ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    # ========== DONE ==========



.PHONY: install
install: all

# 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
此外,您的编译器正在将所有
.o
文件放在根文件夹中,因为您没有告诉他不要这样做,或者让make为您这样做

以下是工作生成文件:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)

# Preprocessor flags here
CPPFLAGS    :=  -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) *.dSYM
    @echo "Cleanup complete!"
Make有一组内置的变量和规则,您应该使用它们来避免浪费时间和遇到简单的错误

请注意,此Makefile不能很好地处理依赖项,仅向Makefile添加
.h
文件列表是不够的。您可以通过让编译器在编译
.o
文件时动态创建依赖项文件来解决此问题,例如:

  • 构建
    .d
    文件名的列表:
    DEP:=$(OBJ:.o=.d)
  • 告诉编译器生成相应的文件,将
    -MMD-MP
    开关添加到
    CPPFLAGS
    内置变量
  • 将它们包含在Makefile中,以便它分析它们的内容:
    -Include$(DEP)
  • 不要忘记清理它们,将
    $(DEP)
    添加到
    清理
    目标中的
    $(RM)
    命令中
结果:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)
DEP :=  $(OBJ:.o=.d)

# Preprocessor flags here
CPPFLAGS    :=  -MMD -MP -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

-include $(DEP)

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) $(DEP) *.dSYM
    @echo "Cleanup complete!"

如果您有任何问题,请继续。

您真正的问题在于您没有使用make提供的工具来简化您的任务。
here are the contents of two makefile items.
 a top level makefile the drives the makefile.bot
the makefile.bot handles files/executables in other directorys
these makefiles also use recursion to produce the dependency lists
so only those header files that are actually include'd in the source
are listed as dependencies for that source.
Note: there are several common .c and .h files in the top level directory
      so they are compiled first, then referenced later
      when performing the link activity in each of the sub directories
Note: the 'AllDirectorys' is a list of the sub directories 
      where source code is to be compiled/linked in individual executables
Note: this is setup to run on Linux, and uses linux shell commands
      and certain utilities, like 'sed'

file: makefile.mak (the top level file)

    SHELL = /bin/sh


#  note: this makefile.mak needs to be run from the ./src directory
# of the GOT4 directory tree


SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp

MV      :=  mv

LDFLAGS :=  -L/usr/local/lib -L/usr/lib -L/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

LIBS    :=  -lssl -ldl -lrt -lz -lc -lm -lcrypto



.PHONY: AllDirectories
# the following statement needs to be edited as
# subdirectories are added/deleted/re-named
AllDirectories := \
    CommandConfiguration \
    Communication \
    MainScheduler \
    RetrieveCDSLog \
    RetrieveEventRecorderLog \
    RetrieveGPS \
    QESRouter



#AllDirectories :=  \
#    MainScheduler \
#    Communication  \
#    RetrieveGPS   \
#    TestCommunicationDev



.PHONY: all
#all: $(OBJ) $(AllDirectories)
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak name=Tsk_$d all ); )

all: $(OBJ) $(AllDirectories)
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d all ); )



#
# create dependancy files
#
%.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
#
%.o: %.c %.d
    #
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I.
    # ========= END $< TO $@ =========
    #



.PHONY: clean
#clean: $(AllDirectories)
#   # ========== start clean activities ==========
#   rm -f *.o
#   rm -f $(name).map
#   rm -f $(name)
#   rm -f *.d
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end clean activities ==========

clean: $(AllDirectories)
    # ========== start clean activities ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    rm -f ../bin/Tsk_*
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d clean ); )
    # ========== end clean activities ==========



.PHONY: install
#install: $(AllDirectories)
#   # ========== start install activities ==========
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end install activities ==========

install: $(AllDirectories)
    # ========== start install activities ==========
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d install ); )
    # ========== end install activities ==========



# include the contents of all the .d files
# note: the .d files contain:
# <filename>.o:<filename>.c plus all the dependancies for that 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


file: makefile.bot  which only occurs once, in the top level directory
along side the above listed makefile.mak

SHELL = /bin/sh


BINDIR  :=  /home/user/bin


.PHONY: all
all : $(BINDIR)/$(name) ../makefile.mak ../makefile.bot


#
# macro of all *.c files 
# (NOTE:
# (the following 'wildcard' will pick up ALL .c files
# (like FileHeader.c and FunctionHeader.c 
# (which should not be part of the build
# (so be sure no unwanted .c files in directory
# (or change the extension
#
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


COMMON_OBJ := $(wildcard ../*.o)
#COMMON_SRC := $(wildcard ../*.c)
#COMMON_OBJ := $(COMMON_SRC:.c=.o)
#COMMON_DEP := $(COMMON_SRC:.c=.d)
#COMMON_INC := $(COMMON_SRC:.c=.h)

MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp -f

MV      := mv

LDFLAGS :=  -L/usr/local/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

#LIBS    :=  -lidn -lssl -ldl -lrt -lz -lc -lm
LIBS    :=   -lssl -ldl -lrt -lz -lc -lm -lcrypto



#
# link the .o files into the executable 
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ) $(COMMON_OBJ) ../makefile.mak ../makefile.bot
    #
    # ======= $(name) Link Start =========
    $(CC) $(LDFLAGS) -o $@ $(OBJ) $(COMMON_OBJ) $(LIBS)
    # ======= $(name) Link Done ==========
    #



# note:
# using MV rather than CP results in all executables being re-made everytime
$(BINDIR)/$(name): $(name)
    #
    # ======= $(name) Copy Start =========
    $(CP) $(name) $(BINDIR)/
    # ======= $(name) Copy Done ==========
    #



#
#create dependancy files -- inference rule
#
%.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 
    # 
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I. 
    # ========= END $< TO $@ =========
    # 



.PHONY: clean
clean: 
    # ========== CLEANING UP ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    # ========== DONE ==========



.PHONY: install
install: all

# 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
此外,您的编译器正在将所有
.o
文件放在根文件夹中,因为您没有告诉他不要这样做,或者让make为您这样做

以下是工作生成文件:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)

# Preprocessor flags here
CPPFLAGS    :=  -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) *.dSYM
    @echo "Cleanup complete!"
Make有一组内置的变量和规则,您应该使用它们来避免浪费时间和遇到简单的错误

请注意,此Makefile不能很好地处理依赖项,仅向Makefile添加
.h
文件列表是不够的。您可以通过让编译器在编译
.o
文件时动态创建依赖项文件来解决此问题,例如:

  • 构建
    .d
    文件名的列表:
    DEP:=$(OBJ:.o=.d)
  • 告诉编译器生成相应的文件,将
    -MMD-MP
    开关添加到
    CPPFLAGS
    内置变量
  • 将它们包含在Makefile中,以便它分析它们的内容:
    -Include$(DEP)
  • 不要忘记清理它们,将
    $(DEP)
    添加到
    清理
    目标中的
    $(RM)
    命令中
结果:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)
DEP :=  $(OBJ:.o=.d)

# Preprocessor flags here
CPPFLAGS    :=  -MMD -MP -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

-include $(DEP)

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) $(DEP) *.dSYM
    @echo "Cleanup complete!"
如果您有任何问题,请继续。

以下是两个makefile项的内容。
here are the contents of two makefile items.
 a top level makefile the drives the makefile.bot
the makefile.bot handles files/executables in other directorys
these makefiles also use recursion to produce the dependency lists
so only those header files that are actually include'd in the source
are listed as dependencies for that source.
Note: there are several common .c and .h files in the top level directory
      so they are compiled first, then referenced later
      when performing the link activity in each of the sub directories
Note: the 'AllDirectorys' is a list of the sub directories 
      where source code is to be compiled/linked in individual executables
Note: this is setup to run on Linux, and uses linux shell commands
      and certain utilities, like 'sed'

file: makefile.mak (the top level file)

    SHELL = /bin/sh


#  note: this makefile.mak needs to be run from the ./src directory
# of the GOT4 directory tree


SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp

MV      :=  mv

LDFLAGS :=  -L/usr/local/lib -L/usr/lib -L/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

LIBS    :=  -lssl -ldl -lrt -lz -lc -lm -lcrypto



.PHONY: AllDirectories
# the following statement needs to be edited as
# subdirectories are added/deleted/re-named
AllDirectories := \
    CommandConfiguration \
    Communication \
    MainScheduler \
    RetrieveCDSLog \
    RetrieveEventRecorderLog \
    RetrieveGPS \
    QESRouter



#AllDirectories :=  \
#    MainScheduler \
#    Communication  \
#    RetrieveGPS   \
#    TestCommunicationDev



.PHONY: all
#all: $(OBJ) $(AllDirectories)
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak name=Tsk_$d all ); )

all: $(OBJ) $(AllDirectories)
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d all ); )



#
# create dependancy files
#
%.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
#
%.o: %.c %.d
    #
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I.
    # ========= END $< TO $@ =========
    #



.PHONY: clean
#clean: $(AllDirectories)
#   # ========== start clean activities ==========
#   rm -f *.o
#   rm -f $(name).map
#   rm -f $(name)
#   rm -f *.d
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end clean activities ==========

clean: $(AllDirectories)
    # ========== start clean activities ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    rm -f ../bin/Tsk_*
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d clean ); )
    # ========== end clean activities ==========



.PHONY: install
#install: $(AllDirectories)
#   # ========== start install activities ==========
#   $(foreach d,$(AllDirectories), \
#    ( cd $d && $(MAKE) -f makefile.mak clean ); )
#   # ========== end install activities ==========

install: $(AllDirectories)
    # ========== start install activities ==========
    $(foreach d,$(AllDirectories), \
    ( cd $d && $(MAKE) -f ../makefile.bot name=Tsk_$d install ); )
    # ========== end install activities ==========



# include the contents of all the .d files
# note: the .d files contain:
# <filename>.o:<filename>.c plus all the dependancies for that 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


file: makefile.bot  which only occurs once, in the top level directory
along side the above listed makefile.mak

SHELL = /bin/sh


BINDIR  :=  /home/user/bin


.PHONY: all
all : $(BINDIR)/$(name) ../makefile.mak ../makefile.bot


#
# macro of all *.c files 
# (NOTE:
# (the following 'wildcard' will pick up ALL .c files
# (like FileHeader.c and FunctionHeader.c 
# (which should not be part of the build
# (so be sure no unwanted .c files in directory
# (or change the extension
#
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)


COMMON_OBJ := $(wildcard ../*.o)
#COMMON_SRC := $(wildcard ../*.c)
#COMMON_OBJ := $(COMMON_SRC:.c=.o)
#COMMON_DEP := $(COMMON_SRC:.c=.d)
#COMMON_INC := $(COMMON_SRC:.c=.h)

MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp -f

MV      := mv

LDFLAGS :=  -L/usr/local/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -W

#CPPFLAGS += =MD

#LIBS    :=  -lidn -lssl -ldl -lrt -lz -lc -lm
LIBS    :=   -lssl -ldl -lrt -lz -lc -lm -lcrypto



#
# link the .o files into the executable 
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ) $(COMMON_OBJ) ../makefile.mak ../makefile.bot
    #
    # ======= $(name) Link Start =========
    $(CC) $(LDFLAGS) -o $@ $(OBJ) $(COMMON_OBJ) $(LIBS)
    # ======= $(name) Link Done ==========
    #



# note:
# using MV rather than CP results in all executables being re-made everytime
$(BINDIR)/$(name): $(name)
    #
    # ======= $(name) Copy Start =========
    $(CP) $(name) $(BINDIR)/
    # ======= $(name) Copy Done ==========
    #



#
#create dependancy files -- inference rule
#
%.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 
    # 
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I. 
    # ========= END $< TO $@ =========
    # 



.PHONY: clean
clean: 
    # ========== CLEANING UP ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    # ========== DONE ==========



.PHONY: install
install: all

# 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
顶级makefile驱动makefile.bot makefile.bot处理其他目录中的文件/可执行文件 这些生成文件还使用递归生成依赖项列表 所以只有那些真正包含在源文件中的头文件 列为该源的依赖项。 注意:顶层目录中有几个常见的.c和.h文件 所以先编译它们,然后再引用它们 什么时候