GNU make使用(一)
[时间:2017-01] [状态:Self]
[关键词:makefile,gcc,编译,动态库,静态库,可执行文件,shell命令]
引言
前段时间在Linux下编写一个可测试的程序发现,我对makefile实践太少各种别扭吧。因此参考网上的一篇文章,自己尝试下常用的可执行文件、静态库、动态库的自动编译,以及调用,作为后续开发的参考。
本文主要包括三部分:
- 可执行文件的Makefile
- 静态库*.a的Makefile
- 动态库*.b的Makefile
这是我对Makefile学习总结的第二篇文章,其他的可参考GNU make简介。
本文主要参考,感谢@竹林听雨的分享。
在Linux下编译时常用的命令有:
- make : 编译整个工程
- make install : 输出编译之后的结果,可能是系统目录,也可能是自定义目录
- make clean : 清除编译过程中的中间文件,比如.o,.s等
- make distclean : 恢复编译前的环境,注意本文中使用make veryclean
1. 可执行文件的Makefile
代码如下:
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
#目标文件名,输入任意你想要的执行文件名
TARGET := exe_check
#编译参数
CC := g++
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
#下面的基本上不需要做任何改动了
.PHONY : everything objs clean veryclean rebuild
everything : $(TARGET)
all : $(TARGET)
objs : $(OBJS)
rebuild: veryclean everything
clean :
rm -fr *.so
rm -fr *.o
veryclean : clean
rm -fr $(TARGET)
#这里是实际完成编译的命令
$(TARGET) : $(OBJS)
$(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
如果你是直接拷贝这个makefile的话,麻烦检查下上面的shell命令前空白必须是Tab键,不能是空格。
2. 静态库的Makefile和调用示例
Makefile文件如下,主要使用ar/ranlib打包命令:
#共享库文件名,lib*.a
TARGET := libtest.a
#编译参数
CC := g++
AR = ar
RANLIB = ranlib
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
#下面的基本上不需要做任何改动了
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
#头文件,自动查找.h文件
HEADER := $(wildcard *.h)
.PHONY : everything objs clean veryclean rebuild install
everything : $(TARGET)
all : $(TARGET)
objs : $(OBJS)
rebuild: veryclean everything
clean :
rm -fr *.o
veryclean : clean
rm -fr $(TARGET)
install :
test -f ./sample/lib && echo ' ' || mkdir ./sample/lib
cp $(TARGET) ./sample/lib/
test -f ./sample/include/ && echo ' ' || mkdir ./sample/include
cp $(HEADER) ./sample/include/
$(TARGET) : $(OBJS)
$(AR) cru $(TARGET) $(OBJS)
$(RANLIB) $(TARGET)
由于一般动态库或者静态库需要安装,这里添见了install标签。
调用静态库的话,需要使用下面makefile,这里仅给出相对可执行文件的makefile差别,如下:
#compile and lib parameter
#编译参数
CC := g++
LIBS := -ltest
LDFLAGS := -L./lib/
DEFINES :=
INCLUDE := -I. -I./include
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
主要加入了静态库所在的目录及-l命令。
3. 动态库的Makefile及调用示例
Makefile如下,直接调用g++编译成动态库:
#共享库文件名,lib*.so
TARGET := libtest.so
#编译参数
CC := g++
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
SHARE := -fpic -shared -o
#下面的基本上不需要做任何改动了
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
#头文件,自动查找.h文件
HEADER := $(wildcard *.h)
.PHONY : everything objs clean veryclean rebuild install
everything : $(TARGET)
all : $(TARGET)
objs : $(OBJS)
$(CC) -c -fPIC $(SOURCE)
rebuild: veryclean everything
clean :
rm -fr *.o
veryclean : clean
rm -fr $(TARGET)
install :
test -d ./sample/lib && echo ' ' || mkdir ./sample/lib
cp $(TARGET) ./sample/lib/
test -d ./sample/include/ && echo ' ' || mkdir ./sample/include
cp $(HEADER) ./sample/include/
$(TARGET) : objs
$(CC) $(CXXFLAGS) $(SHARE) $@ $(OBJS) $(LDFLAGS) $(LIBS)
这里就是需要关注下-fPIC和-fpic的不同使用位置,否则可能会出现编译错误。
调用动态库的示例代码的Makefile跟可执行文件的主要区别如下:
#目标文件名,输入任意你想要的执行文件名
TARGET := shared_check
#编译参数
CC := g++
LIBS := -ltest
LDFLAGS := -L./lib/
DEFINES :=
INCLUDE := -I. -I./include
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
4. 小结
简单整理完了,直接看Makefile确实不是很难,但是其中涉及比较多的shell命令,比如wild、test、patsubst以及gcc编译指令,这方面有待加强。
不做实际验证才不会明白其中有各种坑的。简单过一遍GNU Makefile还是很有帮助的。
本文所有涉及的Makefile及源码可以从我的git下载,url:https://git.oschina.net/Tocy/SampleCode.git。相关文件位于makefile-template文件夹下。
GNU make使用(一)的更多相关文章
- 感悟 GNU C 以及将 Vim 打造成 C/C++ 的半自动化 IDE
C 语言在 Linux 系统中的重要性自然是无与伦比.不可替代,所以我写 Linux 江湖系列不可能不提 C 语言.C 语言是我的启蒙语言,感谢 C 语言带领我进入了程序世界.虽然现在不靠它吃饭,但是 ...
- 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码
不可否认,这次的标题有点长.之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解 GCC 生成 16 位实模式代码方法的朋友带到我的博客.先说一下背景,编写能在 x86 实模式下运行的 ...
- 在 Linux 中使用 Eclipse 和 Gnu Autotools 管理 C/C++ 项目
在我该系列的之前的所有随笔中,都是采用 Linux 发行版自带的包管理工具(如 apt-get.yum 等)进行软件的安装和卸载,从来没有向大家展示使用源代码自行编译安装软件的方法.但是长期混迹于 U ...
- GNU Readline 库及编程简介
用过 Bash 命令行的一定知道,Bash 有几个特性: TAB 键可以用来命令补全 ↑ 或 ↓ 键可以用来快速输入历史命令 还有一些交互式行编辑快捷键: C-A / C-E 将光标移到行首/行尾 C ...
- GNU Radio Radar Toolbox
GNU Radio Radar Toolbox Install guide Change to any folder in your home directory and enter followin ...
- gnu coreutils-8.25 for win32 static - Beta
gnu.win32-coreutils-8.25.7z 2.7 Mb bc-1.06.tar.gz coreutils-8.25.tar.xz diffutils-3.5.tar.xz gawk-4. ...
- window下搭建c开发环境(GNU环境的安装)
一.在windows平台上安装GNU环境 windows操作系统不自带GNU环境,如果需要开发跨平台的C语言程序,那么需要给windows安装GNU环境 windows下的两款GNU环境:MinGW和 ...
- GNU make使用变量⑤变量的引用、定义等
在 Makefile 中,变量是一个名字(像是 C 语言中的宏),代表一个文本字符串(变量的值).在 Makefile 的目标.依赖.命令中引用变量的地方,变量会被它的值所取代(与 C 语言中宏引用的 ...
- (转)完全用GNU/Linux工作 by 王珢
完全用GNU/Linux工作 王珢 (看完这篇博文,非常喜欢王珢的这篇博客,也我坚定了学gnu/linux的决心,并努力去按照国外的计算机思维模式去学习编程提高自己.看完这篇文章令我热血沸腾 ...
- Gnu/Linux的学习探索
1.Gnu/Linux是一个基于POSIX和UNIX的多用户多任务 支持多线程多CPU的类UNIX的操作系统. 继承了UNIX以网络为核心的设计思想 是性能稳定的多用户网络操作系统. 1991年10月 ...
随机推荐
- rdesktop方法(Linux to Windows)
我的配置: rdesktop -g 960x1080 -a 16 -u aura-bd -0 192.168.62.241 1. 准备工作: ubuntu端: sudo apt-get install ...
- Python常用模块--string
该模块提供3个常用的功能: * 提供常用的字符串常量(感觉用途不大) * 提供字符串替换功能,主要用途是上下文的国际化(通过str可以实现,不介绍,感兴趣的自己看官网) * 提供字符串的格式化功能(感 ...
- [洛谷P2258][NOIP2014PJ]子矩阵(dfs)(dp)
NOIP 2014普及组 T4(话说一道PJ组的题就把我卡了一个多小时诶) 这道题在我看第一次的时候是没有意识到这是一道DP题的,然后就摁着DFS敲了好长时间,结果敲了一个TLE 这是DP!!! 下面 ...
- NIO 中的读和写
概述 读和写是I/O的基本过程.从一个通道中读取很简单:只需创建一个缓冲区,然后让通道将数据读到这个缓冲区中.写入也相当简单:创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作. 从文件 ...
- windows7命令行终端获取管理员模式随笔
非常感谢http://wenku.baidu.com/view/d0e8d2d2240c844769eaee8a.html 背景: 安装了windows7系统后发现有很多命令在命令行模式下运行不了说没 ...
- 洛谷.4008.[NOI2003]editor文本编辑器(块状链表)
题目链接 st(n)表示sqrt(n) 为使块状链表不会退化,通常将每块的大小S维持在[st(n)/2,2st(n)]中,这样块数C也一定[st(n)/2,2st(n)]中 在此使用另一种方法(方便) ...
- 潭州课堂25班:Ph201805201 爬虫高级 第三课 sclapy 框架 腾讯 招聘案例 (课堂笔记)
到指定目录下,创建个项目 进到 spiders 目录 创建执行文件,并命名 运行调试 执行代码,: # -*- coding: utf-8 -*- import scrapy from ..items ...
- 通俗讲解 异步,非阻塞和 IO 复用
1. 阅前热身 为了更加形象的说明同步异步.阻塞非阻塞,我们以小明去买奶茶为例. 1.1 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式. 同步: 当一个同 ...
- World final 2017 题解
链接:https://pan.baidu.com/s/1kVQc9d9 Problem A: #include <cstdio> #include <algorithm> #i ...
- 探讨后端选型中不同语言及对应的Web框架
在进行后端选型的时候,实际上我们要选择的是一个框架.后端领域所使用的技术和框架已经趋于稳定,我们只需要按我们的需要选择所需要的框架.当存在多个框架适合时,我们再选择适合的语言.不得不指出的是,当我们喜 ...