【Make编译控制 05】Makefile动静态库

目录

一、多文件项目源代码

二、静态库编译链接

三、动态库编译链接


一、多文件项目源代码

// include/add.hpp

#pragma once
int add(int a, int b);
// include/sub.hpp

#pragma once
int sub(int a, int b);
// src/add.cpp

#include "add.hpp"

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

#include "sub.hpp"

int sub(int a, int b) {
    return a - b;
}
// src/main.cpp

#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文件

lib_srcs := $(filter-out src/main.cpp,$(shell find src -name *.cpp))
lib_objs := $(patsubst src/%.cpp,obj/%.o, $(lib_srcs))

include_paths := $(shell pwd)/include/

library_paths := $(shell pwd)/lib/
library_names := mymath

I_options := $(include_paths:%=-I%)
l_options := $(library_names:%=-l%)
L_options := $(library_paths:%=-L%)

compile_flags := $(I_options) -w -O3 -std=c++11
linking_flags := $(l_options) $(L_options)

# ================ 编译静态库 ===============

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

lib/libmymath.a : $(lib_objs)
        @mkdir -p $(dir $@)
        ar -r $@ $^

static_lib : lib/libmymath.a

# ================ 链接静态库 ===============

obj/main.o : src/main.cpp
        @mkdir -p $(dir $@)
        g++ -c $^ -o $@ $(compile_flags)

workspace/math.exe : obj/main.o
        @mkdir -p $(dir $@)
        g++ $^ -o $@ $(linking_flags)

# ================ 运行与测试 ===============

run : workspace/math.exe
        @./$<

test :
        @echo "lib_srcs: " $(lib_srcs)
        @echo "lib_objs: " $(lib_objs)
        @echo "include_paths: " $(include_paths)
        @echo "compile_opts: " $(compile_opts)

clean:
        rm -rf obj/* workspace 

.PHONY: test clean run
# 静态库编译链接过程

(base) [root@localhost 08_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── makefile
├── obj
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 08_test]# make static_lib
g++ -c src/add.cpp -o obj/add.o -I/root/gitee/Test/Make_Learn/08_test/include/ -w -O3 -std=c++11
g++ -c src/sub.cpp -o obj/sub.o -I/root/gitee/Test/Make_Learn/08_test/include/ -w -O3 -std=c++11
ar -r lib/libmymath.a obj/add.o obj/sub.o
ar: 正在创建 lib/libmymath.a
(base) [root@localhost 08_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── lib
│   └── libmymath.a
├── makefile
├── obj
│   ├── add.o
│   └── sub.o
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

4 directories, 9 files
(base) [root@localhost 08_test]# make run
g++ -c src/main.cpp -o obj/main.o -I/root/gitee/Test/Make_Learn/08_test/include/ -w -O3 -std=c++11
g++ obj/main.o -o workspace/math.exe -lmymath -L/root/gitee/Test/Make_Learn/08_test/lib/
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost 08_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── lib
│   └── libmymath.a
├── makefile
├── obj
│   ├── add.o
│   ├── main.o
│   └── sub.o
├── src
│   ├── add.cpp
│   ├── main.cpp
│   └── sub.cpp
└── workspace
    └── math.exe

5 directories, 11 files
(base) [root@localhost 08_test]#

三、动态库编译链接

# Makefile文件

lib_srcs := $(filter-out src/main.cpp,$(shell find src -name *.cpp))
lib_objs := $(patsubst src/%.cpp,obj/%.o, $(lib_srcs))

include_paths := $(shell pwd)/include/

library_paths := $(shell pwd)/lib/
library_names := mymath

I_options := $(include_paths:%=-I%)
l_options := $(library_names:%=-l%)
L_options := $(library_paths:%=-L%)

compile_flags := $(I_options) -w -O3 -std=c++11 -fpic
linking_flags := $(l_options) $(L_options)

# ================ 编译动态库 ===============

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

lib/libmymath.so : $(lib_objs)
        @mkdir -p $(dir $@)
        g++ -shared $^ -o $@

shared_lib : lib/libmymath.so

# ================ 链接动态库 ===============

obj/main.o : src/main.cpp
        @mkdir -p $(dir $@)
        g++ -c $^ -o $@ $(compile_flags)

workspace/math.exe : obj/main.o
        @mkdir -p $(dir $@)
        ln -s $(library_paths)/libmymath.so /lib64/libmymath.so
        g++ $^ -o $@ $(linking_flags)

# ================ 运行与测试 ===============

run : workspace/math.exe
        @./$<

test :
        @echo "lib_srcs: " $(lib_srcs)
        @echo "lib_objs: " $(lib_objs)
        @echo "include_paths: " $(include_paths)
        @echo "compile_opts: " $(compile_opts)

clean:
        rm -rf obj/* workspace lib /lib64/libmymath.so

.PHONY: test clean run
# 动态库编译链接过程

(base) [root@localhost 09_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── makefile
├── obj
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 09_test]# make shared_lib
g++ -c src/add.cpp -o obj/add.o -I/root/gitee/Test/Make_Learn/09_test/include/ -w -O3 -std=c++11 -fpic
g++ -c src/sub.cpp -o obj/sub.o -I/root/gitee/Test/Make_Learn/09_test/include/ -w -O3 -std=c++11 -fpic
g++ -shared obj/add.o obj/sub.o -o lib/libmymath.so
(base) [root@localhost 09_test]# make run
g++ -c src/main.cpp -o obj/main.o -I/root/gitee/Test/Make_Learn/09_test/include/ -w -O3 -std=c++11 -fpic
ln -s /root/gitee/Test/Make_Learn/09_test/lib//libmymath.so /lib64/libmymath.so
g++ obj/main.o -o workspace/math.exe -lmymath -L/root/gitee/Test/Make_Learn/09_test/lib/
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost 09_test]# tree .
.
├── include
│   ├── add.hpp
│   └── sub.hpp
├── lib
│   └── libmymath.so
├── makefile
├── obj
│   ├── add.o
│   ├── main.o
│   └── sub.o
├── src
│   ├── add.cpp
│   ├── main.cpp
│   └── sub.cpp
└── workspace
    └── math.exe

5 directories, 11 files
(base) [root@localhost 09_test]# 

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Makefile中将源代码编译静态库,你需要定义适当的规则来编译源文件并将其打包成静态库文件。以下是一个示例Makefile,演示如何将源代码编译静态库: ```makefile CC = g++ CFLAGS = -Wall -g # 静态库名称 LIBRARY = libmylibrary.a # 源文件 SRCS = file1.cpp file2.cpp # 目标文件 OBJS = $(SRCS:.cpp=.o) all: $(LIBRARY) $(LIBRARY): $(OBJS) ar rcs $@ $^ %.o: %.cpp $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(OBJS) $(LIBRARY) ``` 在上面的示例中,`CC`变量定义了使用的编译器(这里使用`g++`),`CFLAGS`定义了编译选项(例如`-Wall`和`-g`)。 `LIBRARY`变量定义了最终生成的静态库的名称,`SRCS`变量定义了源文件的名称。 `OBJS`变量是由源文件生成的目标文件的列表。 在上述示例中,我们定义了一个名为`all`的目标,它依赖于`$(LIBRARY)`。通过运行`make all`命令,将会编译源文件并生成静态库文件。 在编译步骤中,我们使用了模式规则来生成目标文件(`%.o`)。通过运行`$(CC)`编译器并使用`-c`选项编译源文件,并将结果输出到目标文件中。 在链接步骤中,我们使用了`ar`命令将所有目标文件打包成静态库。`-rcs`选项用于创建库文件,`$@`表示目标文件(`$(LIBRARY)`),`$^`表示所有的依赖文件(目标文件)。 最后,我们定义了一个名为`clean`的目标,用于删除生成的目标文件和静态库文件。 你可以根据实际情况修改Makefile中的路径和名称,以适应你的项目。运行`make`命令将会编译源代码并生成静态库文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AllinTome

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

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

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

打赏作者

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

抵扣说明:

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

余额充值