前言
说到编译工具,在windows下必言vs,在linux下必言make。
0.shell
如果编译一个库的命令太复杂或者为了方便,我们更愿意将编译命令写成一个shell脚本来执行,比如build.sh编译ffmpeg:
#!/bin/sh
./configure --prefix=$(pwd)/../../seemideo/thirdparty/lib/ffmpeg-3.2.3 \
--enable-gpl --enable-libx264 --enable-shared --disable-static --enable-vaapi \
--enable-cuda --enable-cuvid --enable-nonfree --enable-pic --enable-libfreetype --enable-postproc --extra-libs="$(pkg-config --libs libva-drm libva-x11 libva)" \
--extra-cflags="$(pkg-config --cflags libva-drm libva-x11 libva) -pg" \
--extra-cflags=-I/usr/local/cuda-8.0/include --extra-libs=-L/usr/local/cuda-8.0/lib64 \
--enable-sse42 && make -j8 && make install
实际上shell称不上一个构建工具,只是脚本的一个功能,之所以要把shell放在这里,是因为下面那些工具都是类似shell脚本的语法,如果你熟练使用shell,使用其他几种工具构建工程将不是问题。
1.make
makefile会根据文件的时间修改编译那些修改过的文件,而不是编译全部工程文件。
执行一个make命令,将在目录下搜索名称为makefile或者Makefile的文件执行命令。
生成动态库就加编译选项 -shared -fPIC 将生成.so
生成静态库是使用 ar 命令将编译成的.o打包成.a
Makefile的规则
在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
一个目标 : 生成目标的多个依赖
生成目标的命令
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
makefile在编译的时候就是从第一个目标寻找依赖,不断的寻找下一个依赖的目标,生成下一个目标,不断的嵌套生成的目标。
make是我们在linux下用的最多最熟悉的构建工具,不管实在x86架构的pc上,还是arm架构的嵌入式板子上,还是在andrio系统的手机上,都可以使用,
现在的c,c++开源工具很多,在linux下大部分都提供源码安装,我们常用的就是三步:
第一步 ./configure
根据系统配置设置编译工具链,根据各种宏开关编译启用模块,根指定编译完成后make install安装的路径,生成makefile,
第二步 make
根据上步生成的makefile,执行make中工具链编译代码
第三步 make install
将生成的include,lib,share,bin拷贝到configure时指定的目录
2.cmake
由于复杂的工程编写makefile太繁琐,所以一般都是根据配置生成makefile,所以就出现了cmake,根据一个CMakeList.txt的脚本生成makefile。
cmake在windows下支持命令行,也支持很多人喜欢的gui工具,并可以生成vs的工程,cmake本质上来说就是make,只不过大型工程的makefile太困难,所以一般是使用cmake的CMakeList.txt规则生成makefile,然后编译。
cmake在windows的gui界面:
在configue的时候选择编译工具,然后可以在上面的列表中修改一些路径和宏定义开关,gernerate就可以生成vs的工程了,可以后面的打开工程项目了
3.scons
scons将在当前目录以下次序 SConstruct,Sconstruct,sconstruct 来搜索配置文件。
SCons 是一个开放源代码、以 Python 语言编写的下一代的程序建造工具。它最初的名字是 ScCons, 基于由 perl 语言编写的 Cons 软件开发而成,它在 2000 年 8 月获得了由 Software Carpentry 举办的 SC 建造比赛的大奖。现在 ScCons 已经被改名为 SCons,目的是为了表示不再与 Software Carpentry 有联系,当然,还有一个目的,就是为了更方便的输入。可以在linux和windows下使用,由于是基于python语言完成,所以在安装使用scons之前要安装python。
SCons 具有以下优点:
- 使用 Python 脚本做为配置文件
- 对于 C,C++ 和 Fortran, 内建支持可靠自动依赖分析 . 不用像 make 工具那样需要执行"make depends"和"make clean"就可以获得所有的依赖关系。
- 内建支持 C, C++, D, Java, Fortran, Yacc, Lex, Qt,SWIG 以及 Tex/Latex。用户还可以根据自己的需要进行扩展以获得对需要编程语言的支持。
- 支持 make -j 风格的并行建造。相比 make -j, SCons 可以同时运行 N 个工作,而不用担心代码的层次结构。
- 使用 Autoconf 风格查找头文件,函数库,函数和类型定义。
- 良好的夸平台性。SCons 可以运行在 Linux, AIX, BSD, HP/UX, IRIX, Solaris, Windows, Mac OS X 和 OS/2 上。
scons生成动态库,静态库,执行程序的接口如下:
Program('hello',['hello.c']) 生成可执行文件
SharedLibrary('hello', ['f1.c', 'f2.c', 'f3.c']) 生成动态库
StaticLibrary('test', ['f4.c', 'f5.c', 'f6.c']) 生成静态库
下面是一个示例脚本:
import os
import commands
import copy
import glob
import string
env = Environment(ENV=os.environ)
release =int(ARGUMENTS.get('r',0))
optimize=int(ARGUMENTS.get('o',0))
if release:
cppflags='-DNDEBUG'
else:
cppflags='-D_DEBUG'
cpp_defines = ['__LINUX__']
env=Environment(CCFLAGS=['-gstabs+','-O2','-std=c++11','-Wall','-fPIC','-shared','-Wl,-rpath=./lib',cppflags])
#env.SharedLibrary('test',Glob('./demo/src/*.cpp'),
#StaticLibrary('test',Glob('*.cpp'),
#CPPPATH=['/usr/include','/usr/local/include','./thirdparty/resiprocate-1.10.2/'],
#LIBS=['libdum.a','libresip.a','libresipares.a','librutil.a','libpthread.so'],
#LIBPATH=['/usr/lib','usr/local/lib','./lib/lib/'])
env.Program('bin/test',Glob('src/*.cpp'),
CPPPATH=['/usr/include','/usr/local/include',
'../log4cxx-0.10.0/build/include',
'../apr-1.6.2/build/include',
'../apr-util-1.6.0/build/include',
'../boost_1_64_0',
'../zookeeper-3.4.6/src/c/include',
'../jsoncpp-1.8.0/include',
'/usr/include/mysql',
'../glog/include',
'../gflags-install/include',
'../mysql++-3.2.3/lib',
'../sdks-gpu-new/include'],
LIBS=['libpthread.so',
'libsimilar_match.so',
'libmysqlpp.so',
'libmysqlclient.so',
#'protobuf',
#'glog',
#'gflags',
'jsoncpp',
'zookeeper_mt',
'log4cxx','apr-1','aprutil-1','expat',
'libboost_system.a','libboost_thread.a','libboost_exception.a','libboost_filesystem.a',
'tcmalloc'],
LIBPATH=['.',
'./lib','../zookeeper-3.4.6/src/c/.libs',
'usr/lib','usr/local/lib','../boost_1_64_0/stage/lib',
'../log4cxx-0.10.0/build/lib','../apr-1.6.2/build/lib','../apr-util-1.6.0/build/lib',
'/tmp/lib/linux',
'/usr/lib64/mysql',
'../mysql++-3.2.3/'])
4.xmake
XMake 是一个基于 Lua 的轻量级跨平台自动构建工具,支持在各种主流平台上构建项目,使用模板生成工程。
xmake 的目标是开发者更加关注于项目本身开发,简化项目的描述和构建,并且提供平台无关性,使得一次编写,随处构建。
它跟 cmake 、 automake 、 premake 有点类似,但是机制不同,它默认不会去生成 IDE 相关的工程文件,采用直接编译,并且更加的方便易用采用 lua 的工程描述语法更简洁直观,支持在大部分常用平台上进行构建,以及交叉编译。
并且 xmake 提供了创建、配置、编译、打包、安装、卸载、运行等一些 actions ,使得开发和构建更加的方便和流程化。
不仅如此,它还提供了许多更加高级的特性,例如插件扩展、脚本宏记录、批量打包、自动文档生成等等。
这里只是作为一个总结,对于makefile的语法这里叫不在讲解了,不过各种各种的出现都是为了解决现阶段的问题而诞生的。
另外有premake,autotools的构建工具。
支持特性
- 支持 windows 、 mac 、 linux 、 ios 、 android 等平台,自动检测不同平台上的编译工具链(也可手动配置)编译 windows 项目采用原生 vs 的工具链,不需要使用 cygwin 、 mingw (当然这些也支持)
- 支持自定义平台编译配置,可以很方便的扩展第三方平台支持
- 采用 lua 脚本语法描述项目,描述规则简单高效,逻辑规则可灵活修改,并且不会生成相关平台的工程文件,是工程更加简单明了
- 支持创建模板工程、配置项目、编译项目、运行、打包、安装和卸载等常用功能(后续还会增加:自动生成文档、调试等模块)
- 支持编译 c/c++/objc/swift 成静态库、动态库、命令行可执行程序
- 提供丰富的工程描述 api ,使用简单灵活,例如添加编译文件只需(还支持过滤排除):
add_files("src/*.c", "src/asm/**.S", "src/*.m")
- 支持头文件、接口、链接库依赖、类型的自动检测,并可自动生成配置头文件 config.h
- 支持自定义编译配置开关,例如如果在工程描述文件中增加了
enable_xxx
的开关,那么配置编译的时候就可以手动进行配置来启用它:
xmake config --enable_xxx=y
- 提供一键打包功能,不管在哪个平台上进行打包,都只需要执行一条相同的命令,非常的方便
- 支持全局配置,一些常用的项目配置,例如工具链、规则描述等等,都可以进行全局配置,这样就不需要每次编译不同工程,都去配置一遍
- 除了可以自动检测依赖模块,也支持手动强制配置模块,还有各种编译 flags 。
- 支持插件扩展、平台扩展、模板扩展、选项自定义等高级功能
- 提供一些内置的常用插件(例如:自动生成 doxygen 文档插件,宏脚本记录和运行插件)
- 宏记录插件里面提供了一些内置的宏脚本(例如:批量打包一个平台的所有 archs 等),也可以在命令行中手动记录宏并回放执行
- 提供强大的 task 任务机制
- 不依赖 makefile 和 make ,实现直接编译,内置自动多任务加速编译, xmake 是一个真正的构架工具,而不仅仅是一个工程文件生成器
- 自动检测 ccache ,进行自动缓存提升构建速度
使用xmake模板创建一个c++ console项目:
xmake create -l c++ -t 1 console
或者
xmake create --language=c++ --template=1 console
工程描述文件:xmake.lua
target("console")
set_kind("binary")
add_files("src/*.c")
xmake提供了一些常用工程模板,可以很方便的创建一些空工程。
创建一个c++ console项目:
xmake create -l c++ -t 1 demo
or xmake create --language=c++ --template=1 demo
创建一个c静态库项目:
xmake create -l c -t 5 demo
or xmake create --language=c --template=5 demo
创建一个c动态库项目:
xmake create -t 3 demo
or xmake create --template=3 demo
默认语言是c, 后面的-t和--template参数指定的是需要创建的模板类型,目前只支持console、静态库、动态库三种模板,后续还会支持:application等app应用程序模板。
下面是一些模板选项定义:
-l LANGUAGE, --language=LANGUAGE The project language (default: c)
- c
- c++
- objc
- objc++
- swift
-t TEMPLATE, --template=TEMPLATE Select the project template id of the given language. (default: 1)
- language: c
1. The Console Program
2. The Console Program (tbox)
3. The Shared Library
4. The Shared Library (tbox)
5. The Static Library
6. The Static Library (tbox)
- language: c++
1. The Console Program
2. The Console Program (tbox)
3. The Shared Library
4. The Shared Library (tbox)
5. The Static Library
6. The Static Library (tbox)
- language: objc
1. The Console Program
- language: objc++
1. The Console Program
- language: swift
1. The Console Program
5.参考资料
make
http://blog.csdn.net/haoel/article/details/2886
http://www.cnblogs.com/wang_yb/p/3990952.html
http://www.cnblogs.com/sky1991/archive/2012/11/15/2771348.html
scons
http://blog.csdn.net/sealyao/article/details/6402257
http://www.linuxidc.com/Linux/2013-02/79467.htm
https://www.ibm.com/developerworks/cn/linux/l-cn-scons/
cmake
http://blog.csdn.net/xuguangsoft/article/details/8162757
http://blog.csdn.net/dbzhang800/article/details/6314073
http://blog.csdn.net/dbzhang800/article/details/6329068
xmake
https://segmentfault.com/a/1190000004235989
http://blog.csdn.net/earbao/article/details/52238568
标签:shell,cmake,lib,..,--,make,编译,简析,xmake From: https://blog.51cto.com/u_4296776/5928618