我正在尝试编写我的第一个makefile。在我的项目中,我有这些文件:
它们中的任何一个都没有函数定义或声明,只有简单的include "list.h"
和clean main来测试编译过程。当我使用命令在控制台中编译这些文件时:
gcc -std=c99 -Wall -Wextra main.c list.c
一切都很好,但是当我使用我的Makefile(在Qt Creator和Gome终端中)时,我遇到了很多错误:
:-1: error: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
。
这是我的Makefile:
CC=gcc
CFLAGS=-std=c99 -Wall -Wextra
LDFLAGS=
all: listtest
listtest: main.o list.o
$(CC) main.o list.o -o listtest
main.o: main.c
$(CC) $(CFLAGS) main.c
list.o: list.c
$(CC) $(CFLAGS) list.c
clean:
rm -rf *o listtest
这是我用来创建它的makefile教程。这个makefile有什么问题,如何解决?
答案 0 :(得分:5)
您在-c
规则中错过了.o
:
main.o: main.c
$(CC) -c -o main.o $(CFLAGS) main.c
list.o: list.c
$(CC) -c -o list.o $(CFLAGS) list.c
更好的规则是:
%.o : %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
此模式规则基本上是用于从.o
构建.c
的内置规则,请参阅make's Catalogue of Implicit Rules。换句话说,您不需要编写上述任何规则。
更好的规则是:
%.o : %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ -MD -MP -MF ${@:.o=.d} $<
这会自动为您生成依赖项。这些依赖项需要包含在makefile中(在后续运行中):
-include $(wildcard *.d)
答案 1 :(得分:0)
here are two reallife, working make files
SHELL = /bin/sh
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
.PHONY: AllDirectories
# the following statement needs to be edited as
# subdirectories are added/deleted/re-named
AllDirectories := \
Main_Scheduler \
Communication \
Retrieve_GPS \
Test_Communication_Dev
.PHONY: 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
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.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
the above file, in the top level directory,
has the following companion make file in each sub directory
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)
MAKE := /usr/bin/make
CC := /usr/bin/gcc
CP := cp
MV := mv
LDFLAGS := -L/usr/local/lib
DEBUG := -ggdb3
CCFLAGS := $(DEBUG) -Wall -W
#CPPFLAGS += =MD
LIBS := -lssl -ldl -lrt -lz -lc -lm
#
# 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 =========
sudo $(CP) $(name) $(BINDIR)/.
# ======= $(name) Copy Done ==========
#
#
#create dependancy files -- inference rule
# list makefile.mak as dependancy so changing makefile forces rebuild
#
%.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
The above two make files
(the main make file,
when executed, executes each of the subdirectory makefiles.)
is from a real/working project.
It creates several executables,
one in each sub directory, except the 'common' sub directory.
It creates all the dependancy information (the *.d files), etc etc
Your will notice the 'install' target only invokes the 'all' target
as no special install operations were needed.
These two files are for a linux system/GCC/make,
but should work with minimal changes elsewhere.
There two files include almost everything
you will need to know about makefiles.
答案 2 :(得分:0)
你可能错过了目标名称。 在我的情况下,这没有错误:
g ++ -o oclb oclb.o -L / usr / local / lib -locilib
这里是错误“重定位0具有无效的符号索引......”:
g ++ -o oclb.cpp -L / usr / local / lib -locilib