Makefile 编译问题解惑

时间:2021-12-08 12:39:35
.
|-- List
|   |-- List.c
|   |-- List.h
|   |-- obj   `
|   `-- Unitest
|       `-- main.c
|        -- Makefile
|-- Macro
|   `-- DataMacroDefine.h
 
1、$(OUTPUT):$(OBJS1) $(OBJS2) $(OBJS3) 写法表示依赖三个OBJS的生成。 即首先生成$(OBJS1) $(OBJS2) $(OBJS3)子目标,再生成$(OUTPUT)
2、$(LIBCC) -c 表示只生成目标文件,不进行目标文件的链接。也就是.c(自动关联同名的.h文件) 或者 .h 单独进行编译生成文件,当然不能执行。
   $(LIBCC) 表示生成目标文件,如果有必要,需要进行子目标文件的链接。
#echo $MAKE=make -w ##提示进入或者离开哪个目录,有利于出错问题的定位
INCLUDE= ../
INCLUDE_MACRO= ../../Macro
OBJ_PATH=./
OBJS1=$(OBJ_PATH)List.o
OBJS2=$(OBJ_PATH)main.o
OBJS3=$(OBJ_PATH)DataMacroDefine.o
OUTPUT=List
CC=gcc
CCFLAGS=$(COMPILE_FLAGS) $(DEF)
LIBCC=gcc 
COMPILE_FLAGS=-w -fPIC -rdynamic  
LIBCOMPILE_FLAGS=-w -fPIC -rdynamic  
DEF = -g 
LINKA=ar  
LDFLAGS= -cr 
#ALL定义段  
all:$(OUTPUT)
$(OUTPUT):$(OBJS1) $(OBJS2) $(OBJS3)
	$(LIBCC) $(CCFLAGS) $(OBJS3) $(OBJS1) $(OBJS2)  -o $(OUTPUT)
$(OBJS1):
	$(LIBCC) -c $(CCFLAGS) $(INCLUDE)/List.c -o $(OBJS1)
$(OBJS2):
	$(LIBCC) -c $(CCFLAGS) main.c -o $(OBJS2)
$(OBJS3):
	$(LIBCC) -c $(CCFLAGS) $(INCLUDE_MACRO)/DataMacroDefine.h -o $(OBJS3)
clean:
	rm -rf *.o $(OUTPUT)
上述编译报错:
gcc  -w -fPIC -rdynamic   -g  ./DataMacroDefine.o ./List.o ./main.o  -o List
./DataMacroDefine.o: file not recognized: File format not recognized
collect2: ld returned 1 exit status
make: *** [List] 错误9C f
使用 file DataMacroDefine.o 命令发现与其他两个目标文件的输出信息不同
file List.o 
List.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
file main.o
main.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
file DataMacroDefine.o 
DataMacroDefine.o: GCC precompiled header (version 013) for C
且如果Makefile改成如下形式编译通过。
#ALL定义段  
all:$(OUTPUT)
$(OUTPUT):$(OBJS1) $(OBJS2) $(OBJS3)
	$(LIBCC) $(CCFLAGS) $(INCLUDE_MACRO)/DataMacroDefine.h $(OBJS1) $(OBJS2)  -o $(OUTPUT)
$(OBJS1):
	$(LIBCC) -c $(CCFLAGS) $(INCLUDE)/List.c -o $(OBJS1)
$(OBJS2):
	$(LIBCC) -c $(CCFLAGS) main.c -o $(OBJS2)
$(OBJS3):
	$(LIBCC) -c $(CCFLAGS) $(INCLUDE_MACRO)/DataMacroDefine.h -o $(OBJS3)
clean:
	rm -rf *.o $(OUTPUT)
==》 进一步修改,使用 -I (指定包含头文件路径)
INCLUDE= ../
INCLUDE_MACRO= -I ../../Macro/
OBJ_PATH=./
OBJS1=$(OBJ_PATH)List.o
OBJS2=$(OBJ_PATH)main.o
OUTPUT=List
CC=gcc
CCFLAGS=$(COMPILE_FLAGS) $(DEF)
LIBCC=gcc 
COMPILE_FLAGS=-w -fPIC -rdynamic  
LIBCOMPILE_FLAGS=-w -fPIC -rdynamic  
DEF = -g 
LINKA=ar  
LDFLAGS= -cr 
#ALL定义段  
all:$(OUTPUT)
$(OUTPUT):$(OBJS1) $(OBJS2)
	$(LIBCC) $(CCFLAGS) $(INCLUDE_MACRO) $(OBJS1) $(OBJS2)  -o $(OUTPUT)
$(OBJS1):
	$(LIBCC) -c $(CCFLAGS) $(INCLUDE)/List.c -o $(OBJS1)
$(OBJS2):
	$(LIBCC) -c $(CCFLAGS) main.c -o $(OBJS2)
clean:
rm -rf *.o $(OUTPUT)
==》 进一步修改,规范文件路径
MY_PATH= ../
INCLUDE= -I ../../Macro/
OBJ_PATH=./obj/
OBJS1=$(OBJ_PATH)List.o
OBJS2=$(OBJ_PATH)main.o
OUTPUT=$(OBJ_PATH)List
CC=gcc
CCFLAGS=$(COMPILE_FLAGS) $(DEF)
LIBCC=gcc 
COMPILE_FLAGS=-w -fPIC -rdynamic  
LIBCOMPILE_FLAGS=-w -fPIC -rdynamic  
DEF = -g 
LINKA=ar  
LDFLAGS= -cr 
#ALL定义段  
all:$(OUTPUT)
$(OUTPUT):$(OBJS1) $(OBJS2)
	$(LIBCC) $(CCFLAGS) $(INCLUDE) $(OBJS1) $(OBJS2)  -o $(OUTPUT)
$(OBJS1):
	$(LIBCC) -c $(CCFLAGS) $(MY_PATH)List.c -o $(OBJS1)
$(OBJS2):
	$(LIBCC) -c $(CCFLAGS) main.c -o $(OBJS2)
clean:
	rm -rf $(OBJS1) $(OBJS2) $(OUTPUT)
==》 进一步修改,使用$<(自动匹配目标文件名,进行编译输出)
MY_PATH= ../
INCLUDE=-I ../ \
        -I ../../Macro/
OBJ_PATH=./obj/
OBJS=$(MY_PATH)List.o 
UNIT_OBJS=main.o
OUTPUT=$(OBJ_PATH)List
CC=gcc
CCFLAGS=$(COMPILE_FLAGS) $(DEF)
LIBCC=gcc 
COMPILE_FLAGS=-w -fPIC -rdynamic  
LIBCOMPILE_FLAGS=-w -fPIC -rdynamic  
DEF = -g 
LINKA=ar  
LDFLAGS= -cr 
#ALL定义段  
all:$(OUTPUT)
$(OUTPUT):$(OBJS) $(UNIT_OBJS)
	$(LIBCC) $(CCFLAGS) $(INCLUDE) $(OBJS) $(UNIT_OBJS) -o $(OUTPUT)
$(OBJS):%o:%c
	$(LIBCC) -c $(CCFLAGS) $< -o $(OBJS)
$(UNIT_OBJS):%o:%c
	$(LIBCC) -c $(CCFLAGS) $< -o $(UNIT_OBJS)
clean:
	rm -rf $(OBJS) $(UNIT_OBJS) $(OUTPUT)
==》 进一步修改,使用$@(依次取出目标文件名,进行编译输出)
MY_PATH= ../
INCLUDE=-I ../ \
        -I ../../Macro/
OBJ_PATH=./obj/
OBJS=$(MY_PATH)List.o 
UNIT_OBJS=main.o
OUTPUT=$(OBJ_PATH)List
CC=gcc
CCFLAGS=$(COMPILE_FLAGS) $(DEF)
LIBCC=gcc 
COMPILE_FLAGS=-w -fPIC -rdynamic  
LIBCOMPILE_FLAGS=-w -fPIC -rdynamic  
DEF = -g 
LINKA=ar  
LDFLAGS= -cr 
#ALL定义段  
all:$(OUTPUT)
$(OUTPUT):$(OBJS) $(UNIT_OBJS)
	$(LIBCC) $(CCFLAGS) $(INCLUDE) $(OBJS) $(UNIT_OBJS) -o $@
$(OBJS):%o:%c
	$(LIBCC) -c $(CCFLAGS) $< -o $@
$(UNIT_OBJS):%o:%c
	$(LIBCC) -c $(CCFLAGS) $< -o $@
clean:
	rm -rf $(OBJS) $(UNIT_OBJS) $(OUTPUT)
</pre><pre code_snippet_id="461598" snippet_file_name="blog_20140831_1_4410746" name="code" class="cpp">.
|-- List
|   |-- Hello.c
|   |-- Hello.h
|   |-- List.c
|   |-- List.h
|   |-- obj   `
|   `-- Unitest
|       `-- main.c
|        -- Makefile
|-- Macro
|   `-- DataMacroDefine.h

 
 
 
 

==》 进一步修改,合并$(OBJS) $(UNIT_OBJS) 为$(OBJS)

MY_PATH= ../INCLUDE=-I ../ \ -I ../../Macro/OBJ_PATH=./obj/OBJS1=$(MY_PATH)List.o $(MY_PATH)Hello.oOBJS=$(OBJS1) main.oOUTPUT=$(OBJ_PATH)ListCC=gccCCFLAGS=$(COMPILE_FLAGS) $(DEF)LIBCC=gcc COMPILE_FLAGS=-w -fPIC -rdynamic LIBCOMPILE_FLAGS=-w -fPIC -rdynamic DEF = -g LINKA=ar LDFLAGS= -cr #ALL定义段 all:$(OUTPUT)$(OUTPUT):$(OBJS)$(LIBCC) $(CCFLAGS) $(INCLUDE) $(OBJS) -o $@$(OBJS):%o:%c$(LIBCC) -c $(CCFLAGS) $< -o $@clean:rm -rf $(OBJS) $(OUTPUT)

==》 进一步修改, 对变量使用“+=” 进行赋值,不会覆盖

MY_PATH= ../INCLUDE +=-I ../ \ -I ../../Macro/OBJ_PATH=./obj/OBJS=$(MY_PATH)List.o $(MY_PATH)Hello.oOBJS += main.oOUTPUT=$(OBJ_PATH)ListCC=gccCCFLAGS +=$(COMPILE_FLAGS) $(DEF)LIBCC=gcc COMPILE_FLAGS=-w -fPIC -rdynamic LIBCOMPILE_FLAGS=-w -fPIC -rdynamic DEF = -g LINKA=ar LDFLAGS= -cr .SUFFIXES: .cpp .c .h .cpp.o: $(CC) $(CCFLAGS) $(INCLUDE) -c $< -o $@ .c.o: $(CC) $(CCFLAGS) $(INCLUDE) -c $< -o $@#ALL定义段 all:$(OUTPUT)$(OUTPUT):$(OBJS) $(LIBCC) $(CCFLAGS) $(INCLUDE) $(OBJS) -o $@clean: rm -rf $(OBJS) $(OUTPUT)

.

|-- List

 |   |-- Hello.c|   |-- Hello.h|   |-- List.c|   |-- List.h|   |-- obj|   |   `-- Makefile|   `-- Unitest|       `-- main.c|-- Macro|   `-- DataMacroDefine.h 
 

 
 
==》 进一步修改,调整路径并使用VPATH 解决多路径问题,路径变量可用冒号“:” 隔开
MY_PATH= ../
UNIT_PATH= ../Unitest
INCLUDE +=-I ../ \
          -I ../Macro/
OBJS=List.o Hello.o
OBJS += main.o
VPATH = $(MY_PATH):$(UNIT_PATH)
OUTPUT=List
CC=gcc
CCFLAGS +=$(COMPILE_FLAGS) $(DEF)
LIBCC=gcc 
COMPILE_FLAGS=-w -fPIC -rdynamic  
LIBCOMPILE_FLAGS=-w -fPIC -rdynamic  
DEF = -g 
LINKA=ar  
LDFLAGS= -cr 
.SUFFIXES: .cpp .c .h  
.cpp.o:  	
<span style="white-space:pre">	</span>$(CC) $(CCFLAGS) $(INCLUDE) -c $< -o $@   
.c.o:
	$(CC) $(CCFLAGS) $(INCLUDE) -c $< -o $@

#ALL定义段  

all:$(OUTPUT)$(OUTPUT):$(OBJS)

	$(LIBCC) $(CCFLAGS) $(INCLUDE) $(OBJS)  -o $@
clean:
	rm -rf $(OBJS) $(OUTPUT)