初识FASTBuild 一个大幅提升C/C++项目编译速度的分布式编译工具
FASTBuild 是一款高性能、开源的构建系统,支持高度可扩展的编译,缓存和网络分发。
以上是FASTBuild官网对其产品的一句话介绍。
FASTBuild 的开源地址:https://github.com/fastbuild/fastbuild
众所周知C/C++语言的一大特色就是需要人为地描述编译过程,然后编译器才会按照这个编译过程一步一步生成你所需要的目标文件。Linux下有make命令和Makefile来完成这一任务,Windows下有各种界面化的IDE帮助开发人员完成这些琐碎的工作,包括后来的CMake可以支持跨平台的编译过程描述,其原理都是一样的。
FASTBuild和上面列举的这些工具作用很相似,就是通过解析输入的编译过程描述文件,调用编译工具,按照步骤生成目标文件。但是如果仅限于此,FASTBuild和其他工具就没什么区别了,它的优势在于它可以通过缓存和网络分发来加快构建的过程。
想要使用FASTBuild,首先得学会 fbuild.bff 文件的编写,fbuild.bff本质上也是一个编译过程描述文件,无非是指定编译器路径、链接器路径、包含目录、库目录、源代码目录、编译参数等等一些编译必要的信息,具体的语法可以在官网查到。
下面是一个多文件、多目标的 fbuild.bff 文件的示例。
完整工程路径:https://gitee.com/tiger_git/FASTBuild_SimpleExample
// Windows Platform (VS 2015 Compiler, Windows 7.1A SDK) // 指定开发环境 //------------------------------------------------------------------------------ .VSBasePath = 'C:\Program Files (x86)\Microsoft Visual Studio 14.0' //------------------------------------------------------------------------------ Settings { .Environment = { "PATH=$VSBasePath$\Common7\IDE\;$VSBasePath$\VC\bin\x86_amd64\", "TMP=C:\Windows\Temp", "SystemRoot=C:\Windows" } } // X64 ToolChain // 指定具体的工具路径 //------------------------------------------------------------------------------ // 编译器 .Compiler = '$VSBasePath$\VC\bin\x86_amd64\cl.exe' // 编译选项 .CompilerOptions = '"%1"' // Input + ' /Fo"%2"' // Output + ' /Z7' // Debug format (in .obj) + ' /c' // Compile only + ' /nologo' // No compiler spam + ' /EHsc' + ' /MTd' // 链接器 .Linker = '$VSBasePath$\VC\bin\x86_amd64\link.exe' // 链接选项 .LinkerOptions = ' /OUT:"%2"' // Output + ' "%1"' // Input + ' /nologo' // No linker spam + ' /DEBUG' // Keep debug info when linking + ' /NODEFAULTLIB:libcmt.lib' + ' /MACHINE:X64' // 库生成器 .Librarian = '$VSBasePath$\VC\bin\x86_amd64\lib.exe' // 库生成器选项 .LibrarianOptions = '"%1"' + ' /OUT:"%2"' + ' /nologo' + ' /MACHINE:X64' // 包含目录 ----------------------------------------------------------------------- .BaseIncludePaths = ' /I"./"' + ' /I"$VSBasePath$\VC\include\"' + ' /I"$VSBasePath$\VC\atlmfc\include\"' + ' /I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt"' + ' /I"C:\Program Files (x86)\Windows Kits\8.1\Include\um"' + ' /I"C:\Program Files (x86)\Windows Kits\8.1\Include\shared"' + ' /I"C:\Program Files (x86)\Windows Kits\8.1\Include\winrt"' .CompilerOptions + .BaseIncludePaths // 库目录 //------------------------------------------------------------------------------ .LibPaths = ' /LIBPATH:"$VSBasePath$\VC\lib\amd64"' + ' /LIBPATH:"$VSBasePath$\VC\atlmfc\lib\amd64"' + ' /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64"' + ' /LIBPATH:"C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64"' + ' /LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\Lib\um\x64"' .LinkerOptions + .LibPaths // 常见的系统库 // .CommonLibs = ' libcmt.lib' // + ' kernel32.lib' // + ' user32.lib' // + ' gdi32.lib' // + ' winspool.lib' // + ' comdlg32.lib' // + ' advapi32.lib' // + ' shell32.lib' // + ' ole32.lib' // + ' oleaut32.lib' // + ' uuid.lib' // + ' odbc32.lib' // + ' odbccp32.lib' // 生成utils.lib // utils------------------------------------------------------------------------------ Library('utils') { .CompilerInputPath = 'utils' // 源文件所在目录,就是把该目录下所有的.cxx\.c文件编译成库文件 .CompilerOutputPath = 'objs\utils' // .obj文件 输出目录 .LibrarianOutput = 'lib\utils.lib' // 库文件 输出目录 } // 生成net.lib // net------------------------------------------------------------------------------ Library('net') { .CompilerInputPath = 'net' // 源文件所在目录,就是把该目录下所有的.cxx\.c文件编译成库文件 .CompilerOutputPath = 'objs\net' // .obj文件 输出目录 .LibrarianOutput = 'lib\net.lib' // 库文件 输出目录 } // 生成frame.lib // frame------------------------------------------------------------------------------ Library('frame') { .CompilerInputPath = 'frame' // 源文件所在目录,就是把该目录下所有的.cxx\.c文件编译成库文件 .LibrarianOutput = 'lib\frame.lib' // .obj文件 输出目录 .CompilerOutputPath = 'objs\frame' // 库文件 输出目录 } // 生成gate.exe // gate------------------------------------------------------------------------------ ObjectList('gate_objs') // 生成gate所需的objs文件 { .CompilerInputPath = 'gate' // 源文件所在目录,就是把该目录下所有的.cxx\.c文件编译.obj(s)文件 .CompilerOutputPath = 'objs\gate' // .obj文件 输出目录 } Executable('gate') { .Libraries = { 'gate_objs', 'net', 'utils' } // 把gate.exe所需的.obj(s)文件和.lib(s)文件链接成.exe文件 .LinkerOutput = 'bin\gate.exe' // .exe文件输出目录 } // game------------------------------------------------------------------------------ ObjectList('game_objs') // 生成game所需的objs文件 { .CompilerInputPath = 'game' // 源文件所在目录,就是把该目录下所有的.cxx\.c文件编译.obj(s)文件 .CompilerOutputPath = 'objs\game' // .obj文件 输出目录 } Executable('game') { .Libraries = { 'game_objs', 'net', 'utils', 'frame' } // 把game.exe所需的.obj(s)文件和.lib(s)文件链接成.exe文件 .LinkerOutput = 'bin\game.exe' // .exe文件输出目录 } // 设置all包含的所有目标,执行fbuild.exe的时候,会默认把all下所有的目标都生成一遍,目标之间的依赖关系会被自动推导 // All //------------------------------------------------------------------------------ Alias( 'all' ) { .Targets = { 'gate', 'game'} }
点击 fbuild.bat