【Make编译控制 04】Makefile项目编译

本文详细介绍了C++编程中的编译选项(如指定标准、调试信息和优化级别)、链接选项(如库名和路径设置)以及如何通过Makefile进行工程项目的编译和管理。以一个简单的项目为例,展示了Makefile的使用和不同编译目标的生成过程。
摘要由CSDN通过智能技术生成

目录

一、编译选项

二、链接选项

三、项目编译


一、编译选项

  • -std=: 指定编译标准,例如:-std=c++11、-std=c++14
  • -g: 包含调试信息
  • -w: 不显示警告
  • -O: 优化等级,通常使用:-O3
  • -I: 加在头文件路径前
  • -m64: 指定编译为 64 位应用程序
  • fPIC: (Position-Independent Code), 产生的没有绝对地址,全部使用相对地址,代码可以被加载到内存的任意位置,且可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的

二、链接选项

  • -l: 加在库名前面
  • -L: 加在库路径前面
  • -Wl,<选项>: 将逗号分隔的 <选项> 传递给链接器
  • -rpath=: "运行" 的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找

三、项目编译

在一个工程项目中,通常包含有多个头文件、源文件,有时候为了打包成库,也需要管理多个目标文件,所以我们需要通过 Makefile 进行工程项目的编译和管理。

项目示例概述:

  1. 项目包含两个头文件:add.hpp、sub.hpp
  2. 每个头文件对应一个源文件:add.cpp、sub.cpp
  3. 有一个主函数源文件:main.cpp
// add.hpp头文件

#pragma once
int add(int a, int b);
// sub.hpp头文件

#pragma once
int sub(int a, int b);
// add.cpp源文件

#include "add.hpp"

int add(int a, int b) {
    return a + b;
}
// sub.cpp源文件

#include "sub.hpp"

int sub(int a, int b) {
    return a - b;
}
#include <iostream>
#include "add.hpp"
#include "sub.hpp"

int main() {
    std::cout << "10 + 5 = " << add(10, 5) << std::endl;
    std::cout << "10 - 5 = " << sub(10, 5) << std::endl;
    return 0;
}
# makefile文件

cpp_srcs := $(shell find src/ -name *.cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o, $(cpp_srcs))

# 头文件绝对路径
include_paths := /root/gitee/Test/Make_Learn/07_test/include/

I_flags := $(include_paths:%=-I%)
# 也可以用 foreach 函数

compile_opts = -w -O3 -m64 $(I_flags)

objs/%.o : src/%.cpp
        @g++ -c $^ -o $@ $(compile_opts)

execs/math : $(cpp_objs)
        @mkdir -p execs
        @g++ $^ -o $@

run : execs/math
        @./$<

gdbs/math_g : $(cpp_objs)
        @mkdir -p gdbs
        @g++ $^ -o $@ -g

gdb : gdbs/math_g
        @gdb $<

test :
        @echo $(cpp_srcs)
        @echo $(cpp_objs)
        @echo $(I_flags)

clean:
        @rm -rf objs/*.o execs gdbs

.PHONY: run gdb test clean
(base) [root@localhost 07_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── makefile
├── objs
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 07_test]# make run
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost 07_test]# tree .
.
├── execs
│   └── math
├── include
│   ├── add.hpp
│   └── sub.hpp
├── makefile
├── objs
│   ├── add.o
│   ├── main.o
│   └── sub.o
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

4 directories, 10 files
(base) [root@localhost 07_test]# make clean
(base) [root@localhost 07_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── makefile
├── objs
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 07_test]# make gdb
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/gitee/Test/Make_Learn/07_test/gdbs/math_g...(no debugging symbols found)...done.
(gdb) r
Starting program: /root/gitee/Test/Make_Learn/07_test/gdbs/math_g 
10 + 5 = 15
10 - 5 = 5
[Inferior 1 (process 30835) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64
(gdb) quit
(base) [root@localhost 07_test]# tree .
.
├── gdbs
│   └── math_g
├── include
│   ├── add.hpp
│   └── sub.hpp
├── makefile
├── objs
│   ├── add.o
│   ├── main.o
│   └── sub.o
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

4 directories, 10 files
(base) [root@localhost 07_test]#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllinTome

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值