Makefile 编译c++ 调试模板 VScode

源码:如果你不想自己创建可以试一下👇qcj/MakefileTemplatehttps://gitee.com/chaojie-qin/MakefileTemplate

文件结构

按照下述结构创建文件:

Makefile文件

make run  运行(如果未编译,先编译后运行)

make clean  删除编译文件

make compile 编译

# 生成静态库或者动态库

make get_a lib_name="静态库名字"

make get_so lib_name="动态态库名字"

# 生成的文件在buid文件夹内

# 这可以实现c++ 和 cu 的混合编译,你只需要更改这里 linux
# DEBUG: 						是否开启debug 1, 0
# SHOW_WARNING:					是否显示warning 1, 0
# stdcpp: 						设置编译标准 c++11, c++14, c++17
# cc、nvcc: 					设置编译器 c++ 和 cuda
# exec_name:				   可执行文件名
# include_paths、library_paths、ld_librarys_names 头文件路径、库路径、库名字、多个路径和名字使用空格分割
# build_dir : 					编译生成的内容都会放到这个文件夹里
# lib_name						库名字
DEBUG                   := 1
SHOW_WARNING            := 0
stdcpp    				:= c++17
cc        				:= g++
nvcc 					:= nvcc
exec_name 	 			:= exec
include_paths 			:= include  /usr/include /usr/local/cuda/include
library_paths 			:= /usr/local/cuda/lib64
ld_librarys_names 		:= cudart cublas cuda
build_dir			    := build
lib_name				:= your_lib_name

# 1. 查找文件
cpp_src_path := $(shell find src -name '*.cpp')  # 后缀名.cpp文件路径
cpp_objs_path := $(patsubst src/%.cpp, $(build_dir)/objs/%.o, $(cpp_src_path))  # .cpp文件路径替换成后缀名.o文件路径
 
cu_src_path := $(shell find src -name '*.cu')  # 后缀名.cpp文件路径
cu_objs_path := $(patsubst src/%.cu, $(build_dir)/objs/%.o, $(cu_src_path))  # .cpp文件路径替换成后缀名.o文件路径

all_objs_path := $(cpp_objs_path) $(cu_objs_path)  # 所有的objs 路径
all_objs_path := $(filter-out $(build_dir)/objs/main.o, $(all_objs_path))

# 2. 定义编译选项
include_paths := $(include_paths)        # 头文件路径
library_paths := $(library_paths)                   # 库路径
ld_librarys_names := $(ld_librarys_names)                # 库的名字
 
 
# 把每一个头文件路径前面增加-I,库文件路径前面增加-L,链接选项前面加-l
I_options := $(include_paths:%=-I%) # 头文件 编译选项
l_options := $(ld_librarys_names:%=-l%) # 库名 链接选项
L_options := $(library_paths:%=-L%) # 库路径 链接选项
r_options := $(library_paths:%=-Wl,-rpath=%) 	 # 动态库 链接选项
 
# 编译设置
linking_options 	:= $(l_options) $(L_options) $(r_options)            # 链接选项
cpp_compile_options      :=  -std=$(stdcpp) -pthread -fPIC $(I_options)  # cpp 编译选项
cu_compile_options 	     :=  --shared -Xcompiler -fPIC $(I_options)                 # cuda 编译选项,
 
ifeq ($(DEBUG),1)
cu_compile_options     +=  -g -O0 -G
cpp_compile_options      +=  -g -O0
else
cu_compile_options     +=  -O3
cpp_compile_options      +=  -O3
endif
 
ifeq ($(SHOW_WARNING),1)
cu_compile_options     +=  -Wall -Wunused-function -Wunused-variable -Wfatal-errors
cpp_compile_options      +=  -Wall -Wunused-function -Wunused-variable -Wfatal-errors
else
cu_compile_options     +=  -w
cpp_compile_options      +=  -w
endif
 
 
# 3. 编译
#定义objs下的o文件,依赖src下对应的cpp文件
# $@ = 左边的生成项
# $< = 右边的依赖项第一个
# $^ = 右边的所有依赖项
$(build_dir)/objs/%.o : src/%.cpp
	@echo "[INFO] Compiling $< to $@"
	@mkdir -p $(dir $@)
	@cc -c $^ -o $@ $(cpp_compile_options)  	# 编译
 
# CUDA 编译
$(build_dir)/objs/%.o : src/%.cu
	@echo "[INFO] Compiling $< to $@"
	@mkdir -p $(dir $@)
	@$(nvcc) -c $^ -o $@ $(cu_compile_options)
 
 
# 链接文件  to exec
$(build_dir)/workspace/$(exec_name) : $(cpp_objs_path) $(cu_objs_path)
	@echo "[INFO] Linking $@...."
	@mkdir -p $(dir $@)
	@$(cc) $^ -o $@ $(linking_options)
	@echo "[INFO] Compiling $@ Done!"
 
 
# ---------------------------------------------------------------------------------
 
# 编译成可执行文件exec,编译,不运行
compile : $(build_dir)/workspace/$(exec_name)
 
 
# 运行 依赖 编译完成
run : $(build_dir)/workspace/$(exec_name)
	@echo "[RUN] $< 👇"
	@cd $(build_dir)/workspace && ./$(exec_name) # 进入目录,执行


# ---------------------------------------------------------------------------------
# 静态库
$(build_dir)/bin/lib$(lib_name).a : $(all_objs_path)
	@echo "[INFO] Creating static library $@..."
	@mkdir -p $(dir $@)
	@ar rcs $@ $^
	@echo "[INFO] Static library created!"

# 动态库
$(build_dir)/bin/lib$(lib_name).so : $(all_objs_path)
	@echo "[INFO] Creating shared library $@..."
	@mkdir -p $(dir $@)
	@$(cc) -shared -o $@ $^ $(linking_options)
	@echo "[INFO] Shared library created!"

# 静态库目标
generate_static_lib : $(build_dir)/bin/lib$(lib_name).a
get_a : generate_static_lib
# 动态库目标
generate_shared_lib : $(build_dir)/bin/lib$(lib_name).so
get_so : generate_shared_lib
# ---------------------------------------------------------------------------------

 
debug :
	@echo $(linking_options)

clean :
	@rm -rf workspace build


 
.PHONY : debug clean run compile generate_static_lib generate_shared_lib get_a get_so

调试

调试时,需要把DEBUG设置为1

 创建launch.json和task.json文件

 task.json文件

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "make compile -j6"   // 这里compile是 Makefile中定义的编译命令
        }
    ]
}

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",  // 配置名称,用于在启动调试时选择
            "type": "cppdbg",      // 调试类型,这里使用 C++ 调试器
            "request": "launch",   // 请求类型,"launch" 表示启动程序进行调试
            "program": "${workspaceFolder}/workspace/exec",     // makefile生成的可执行文件路径
            "args": [],            // 程序启动参数,目前为空
            "stopAtEntry": false,  // 是否在程序入口处停止,默认为 false
            "cwd": "${workspaceFolder}/workspace",  // 工作目录,即当前工作区的 workspace/build 目录
            "environment": [],     // 环境变量设置,目前为空
            "externalConsole": false,  // 是否使用外部控制台,默认为 false
            "MIMode": "gdb",       // 使用的调试器模式,这里是 gdb
            "setupCommands": [     // 设置调试器命令
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build",  // 在启动调试前执行的任务,这里是 task.json中label的值,现在是 build
            // "miDebuggerArgs": "-q -ex quit; wait() { fg >/dev/null; }; /bin/gdb -q --interpreter=mi"  // 添加此行
        }
    ]
}

 F5启动调试界面,或者右上角三角形启动。

posted @ 2025-04-29 09:56  qinchaojie  阅读(132)  评论(0)    收藏  举报  来源