您的位置:首页 > 运维架构 > Shell

c++构建工具之shell,configure,make,cmake,scons,xmake简析总结

2017-11-03 17:35 1856 查看
前言

说到编译工具,在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: