Makefile使用小结

 Makefile-gcc 使用小结

# gcc
## gcc编译器的可选参数。
-c表示只编译(compile)源文件但不链接,会把.c或.cc的c源程序编译成目标文件,一般是.o文件。
-o用于指定输出(out)文件名。不用-o的话,一般会在当前文件夹下生成默认的a.out文件作为可执行程序。

例如:
gcc -c test.c将生成test.o的目标文件
gcc -o app test.c将生成可执行程序app
gcc -c a.c -o a.o表示把源文件a.c编译成指定文件名a.o的中间目标文件(其实在这里,把-o a.o省掉,效果是一样的,因为中间文件默认与源文件同名,只是后缀变化)。

1、如果GCC不带-C参数,编译一个源代码文件(test.c)。那么会自动将编译和链接一步完成,并生成可执行文件。可执行文件可以有-o参数指定(test.o)

2、如果是多个文件,则需要先编译成中间目标文件(一般是.o文件),在链接成可执行文件,一般习惯目标文件都是以.o后缀,也没有硬性规定可执行文件不能用.o文件

加个-g 是为了gdb 用,不然gdb用不到

-W: 关闭编译警告
-Wall: 打开编译警告
-lpthread:l指link,链接pthread库

# makefile
- makefile老是报“recipe for target xxx”错误,不妨先看看makefile文件的编码是否正确
如果你的makefile是直接从网上复制来的,先在window下,用写字板看看是否有乱码,“空格”的乱码很有可能就是你错误的罪魁祸首。

- 在函数‘_start’中:对‘main’未定义的引用
这是因为,编译的文件中,找不到main()这个函数.
确认一下,是不是注释了,或者ifdef没了.或者包含main的.cpp文件未被包含生成.o文件

## 相关教程、示例资料
《跟我一起写Makefile》
链接:https://pan.baidu.com/s/1OT-Hk3bzo070hjuWo39ASg
提取码:sjfy

一个Makefile示例; 采用了很多高级功能,大大简化了makefile文件的编写
https://www.jianshu.com/p/3c13d915dcb0 

完整的示例工程和 makefile 文件可以到如下路径取:
https://github.com/Lingminzou/code/tree/master/makefile/example

make的使用和Makefile的编写
https://blog.youkuaiyun.com/u012510204/article/details/53926399

跟我一起写Makefile
https://seisman.github.io/how-to-write-makefile/overview.html

自动生成项目的Makefile文件(待研究)
https://www.cnblogs.com/yejinru/p/4983209.html

vs code 配置.json文件引入makefile文件实现多文件编译
https://blog.youkuaiyun.com/m0_37433067/article/details/80145679

# *************** 一般工程makefile模板 ******************

# 输出标目名称
BINNAME = UnderdriveHand

# 设置 .o 文件输出路径
OBJDIR = ./obj

# 配置工具链 CC
CC = g++

# 配置编译选项
CC_OPTS :=  -std=c++11 # -Wall -Werror  编译过程中输出控制

# 配置链接选项
LD_OPTS := -lpthread

# 指定编译时依赖的头文件目录,然后放进编译选项
INC_DIR := ./EigenArduino_Eigen30 # ./serial ./driver ./kinematic ./control 如何连续包含??

CC_OPTS += -I$(INC_DIR)
CC_OPTS += -I ./drive
CC_OPTS += -I ./kinematic 
CC_OPTS += -I ./control 
CC_OPTS += -I ./main

# 指出源文件存放路径
SRC_DIR := ./EigenArduino_Eigen30 
SRC_DIR += ./drive ./kinematic ./control ./main

# 指定依赖文件搜索路径,即我们的源文件路径
VPATH = $(SRC_DIR)

# 找出所有需要编译的 cpp 类型文件,注意 find 默认是会循环找子目录的,
# 由于我们子目录的路径也需要写进 VPATH 所以这里把 find 的查找深度设置为了 1
SRC = $(shell find $(SRC_DIR) -maxdepth 1 -name '*.cpp') # -maxdepth 1

# 生成需要输出的 .o 文件名
OBJ_0  = $(notdir $(patsubst %.cpp, %.o, $(SRC)))

# 加上 .o 文件存放路径前缀
OBJ    = $(foreach file, $(OBJ_0), $(OBJDIR)/$(file))

.PHONY: all setup bin clean
all: setup bin
setup:
	@echo $(SRC)
	@echo $(OBJ_0)
	@echo $(OBJ)
	mkdir -p $(OBJDIR)
bin: $(OBJ)
	$(CC) $(OBJ) $(LD_OPTS) -o $(BINNAME)
$(OBJ): $(OBJDIR)/%.o : %.cpp
	$(CC) $(CC_OPTS) -o $@ -c $<

clean:
	rm -rf $(OBJDIR)
	rm -rf $(BINNAME)

# 一个基础示例 makefile_test

main.cpp

#include "print.h"

int main()
{
    printhello();
    return 0;
}

print.h

#include<stdio.h>
void printhello();

print.cpp

#include"print.h"

void printhello()
{
    printf("Hello, world\n");

}

Makefile

# #*********基础版
# helloworld:main.o print.o
# 	gcc -o helloworld main.o print.o

# mian.o:mian.c print.h
# 	gcc -c main.c 

# print.o:print.c print.h
# 	gcc -c print.c

# clean:
# 	rm helloworld main.o print.o


# #*********简化版
obj := main.o print.o # 变量;宏定义
helloworld:$(obj)
	gcc -o helloworld $(obj)
$(obj):print.h # 都依赖print.h
mian.o:mian.c #去掉了gcc -c main.c 让gcc make自动推导
print.o:print.c
clean:
	rm helloworld $(obj)

# 报错、异常处理

- makefile老是报“recipe for target xxx”错误,不妨先看看makefile文件的编码是否正确

如果你的makefile是直接从网上复制来的,先在window下,用写字板看看是否有乱码,“空格”的乱码很有可能就是你错误的罪魁祸首。




- 在函数‘_start’中:对‘main’未定义的引用

这是因为,编译的文件中,找不到main()这个函数.

确认一下,是不是注释了,或者ifdef没了.或者包含main的.cpp文件未被包含生成.o文件

# 相关教程、示例资料

《跟我一起写Makefile》
链接:https://pan.baidu.com/s/1OT-Hk3bzo070hjuWo39ASg
提取码:sjfy


一个Makefile示例; 采用了很多高级功能,大大简化了makefile文件的编写
https://www.jianshu.com/p/3c13d915dcb0 
完整的示例工程和 makefile 文件可以到如下路径取:
https://github.com/Lingminzou/code/tree/master/makefile/example


make的使用和Makefile的编写
https://blog.youkuaiyun.com/u012510204/article/details/53926399


跟我一起写Makefile
https://seisman.github.io/how-to-write-makefile/overview.html

自动生成项目的Makefile文件(待研究)
https://www.cnblogs.com/yejinru/p/4983209.html


vs code 配置.json文件引入makefile文件实现多文件编译
https://blog.youkuaiyun.com/m0_37433067/article/details/80145679

# 一个较通用模板

Makefile

# //*** 根据具体工程需要,更改BINNAME、LD_OPTS、SRC_DIR 、CC_OPTS等宏变量即可 ***//

# 输出标目名称
BINNAME = UnderdriveHand

# 设置 .o 文件输出路径
OBJDIR = ./obj

# 配置工具链 CC
CC = g++

# 配置编译选项
CC_OPTS :=  -std=c++11 # -Wall -Werror  编译过程中输出控制

# 配置链接选项
LD_OPTS := -lpthread

# 指定编译时依赖的头文件目录,然后放进编译选项
INC_DIR := ./EigenArduino_Eigen30 # ./serial ./driver ./kinematic ./control 如何连续包含??

CC_OPTS += -I$(INC_DIR)
CC_OPTS += -I ./drive
CC_OPTS += -I ./kinematic 
CC_OPTS += -I ./control 
CC_OPTS += -I ./main

# 指出源文件存放路径
SRC_DIR := ./EigenArduino_Eigen30 
SRC_DIR += ./drive ./kinematic ./control ./main

# 指定依赖文件搜索路径,即我们的源文件路径
VPATH = $(SRC_DIR)

# 找出所有需要编译的 cpp 类型文件,注意 find 默认是会循环找子目录的,
# 由于我们子目录的路径也需要写进 VPATH 所以这里把 find 的查找深度设置为了 1
SRC = $(shell find $(SRC_DIR) -maxdepth 1 -name '*.cpp') # -maxdepth 1

# 生成需要输出的 .o 文件名
OBJ_0  = $(notdir $(patsubst %.cpp, %.o, $(SRC)))

# 加上 .o 文件存放路径前缀
OBJ    = $(foreach file, $(OBJ_0), $(OBJDIR)/$(file))

.PHONY: all setup bin clean

all: setup bin

setup:
	@echo $(SRC)
	@echo $(OBJ_0)
	@echo $(OBJ)
	mkdir -p $(OBJDIR)

bin: $(OBJ)
	$(CC) $(OBJ) $(LD_OPTS) -o $(BINNAME)

$(OBJ): $(OBJDIR)/%.o : %.cpp
	$(CC) $(CC_OPTS) -o $@ -c $<

clean:
	rm -rf $(OBJDIR)
	rm -rf $(BINNAME)

根据具体工程需要,更改BINNAME、LD_OPTS、SRC_DIR 、CC_OPTS等宏变量即可.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值