Makefile和“重定位具有无效的符号索引”错误

时间:2021-09-20 15:28:59

I was trying to write my first makefile. In my project I have these files:

我在写我的第一个makefile。在我的项目中,我有这些文件:

  • main.c
  • c
  • list.c
  • list.c
  • list.h
  • list.h
  • Makefile
  • Makefile

There is even no function definition or declaration in any of them, just simple include "list.h" and clean main to test the compilation process. When I compile these files in console with command:

其中甚至没有函数定义或声明,只有简单的include“列表”。h和clean main测试编译过程。当我用命令在控制台编译这些文件时:

gcc -std=c99 -Wall -Wextra main.c list.c

c -std=c99 -Wall -Wextra main。c list.c

everything is fine, but when I use my Makefile (in Qt Creator and Gome terminal) I'm getting a lot of errors like:

一切都很好,但是当我使用我的Makefile(在Qt Creator和国美终端)时,我得到了很多错误,比如:

:-1: error: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11.

:-1:错误:/usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info):重定位0具有无效的符号索引11。

This is my Makefile:

这是我的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

This is a makefile tutorial I was using to create it. What's wrong with this makefile and how can I fix it?

这是我用来创建它的makefile教程。这个makefile有什么问题,我如何修复它?

http://mrbook.org/tutorials/make/

http://mrbook.org/tutorials/make/

3 个解决方案

#1


5  

You missed -c in your .o rules:

你错过了。o规则中的-c:

main.o: main.c
    $(CC) -c -o main.o $(CFLAGS) main.c

list.o: list.c
    $(CC) -c -o list.o $(CFLAGS) list.c

A better rule is:

一个更好的规则是:

%.o : %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<

This pattern rule is essentially the built-in rule for building .o from .c, see make's Catalogue of Implicit Rules. In other words, you don't need to write any of the above rules.

这个模式规则本质上是构建.o的内置规则,参见make的隐式规则目录。换句话说,您不需要编写上面的任何规则。


A much better rule is:

更好的规则是:

%.o : %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ -MD -MP -MF ${@:.o=.d} $<

This automatically generates dependencies for you. These dependencies need to be included into makefile (on subsequent runs):

这将自动为您生成依赖项。这些依赖项需要包含在makefile中(在后续运行中):

-include $(wildcard *.d)

#2


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.

#3


0  

Might be You'd missed target name. In my case this works without errors:

可能是你漏掉了目标名称。在我的例子中,这是没有错误的:

g++ -o oclb oclb.o -L/usr/local/lib -locilib

g++ - o oclb oclb。o - l / usr /地方/ lib -locilib

and here are errors "relocation 0 has invalid symbol index...":

这里有错误“重新安置0有无效的符号索引…”

g++ -o oclb.cpp -L/usr/local/lib -locilib

g++ - o oclb。cpp - l / usr /地方/ lib -locilib

#1


5  

You missed -c in your .o rules:

你错过了。o规则中的-c:

main.o: main.c
    $(CC) -c -o main.o $(CFLAGS) main.c

list.o: list.c
    $(CC) -c -o list.o $(CFLAGS) list.c

A better rule is:

一个更好的规则是:

%.o : %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<

This pattern rule is essentially the built-in rule for building .o from .c, see make's Catalogue of Implicit Rules. In other words, you don't need to write any of the above rules.

这个模式规则本质上是构建.o的内置规则,参见make的隐式规则目录。换句话说,您不需要编写上面的任何规则。


A much better rule is:

更好的规则是:

%.o : %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ -MD -MP -MF ${@:.o=.d} $<

This automatically generates dependencies for you. These dependencies need to be included into makefile (on subsequent runs):

这将自动为您生成依赖项。这些依赖项需要包含在makefile中(在后续运行中):

-include $(wildcard *.d)

#2


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.

#3


0  

Might be You'd missed target name. In my case this works without errors:

可能是你漏掉了目标名称。在我的例子中,这是没有错误的:

g++ -o oclb oclb.o -L/usr/local/lib -locilib

g++ - o oclb oclb。o - l / usr /地方/ lib -locilib

and here are errors "relocation 0 has invalid symbol index...":

这里有错误“重新安置0有无效的符号索引…”

g++ -o oclb.cpp -L/usr/local/lib -locilib

g++ - o oclb。cpp - l / usr /地方/ lib -locilib