La mayoría de ustedes probablemente estarán de acuerdo en que CMake es, con mucho, el sistema de compilación más popular para proyectos C / C ++. Imagínese mi sorpresa al ver en el proyecto del nuevo trabajo su propio sistema de construcción: Bake .
En este artículo me gustaría describir las principales características de este sistema, en qué se diferencia de otros sistemas similares y mostrar cómo se puede utilizar para resolver diversos problemas que surgen en el proceso de desarrollo de un programa.
Bake es un sistema de construcción multiplataforma para proyectos C / C ++, dirigido principalmente a sistemas integrados. Bake está escrito en Ruby, de código abierto y aún es compatible (en desarrollo desde 2012)
Los principales objetivos a los que aspiraban los desarrolladores al crear esta solución:
Utilidad de línea de comandos (hay soporte para complementos para algunos editores, incluido VSCode);
Lo que debería resolver solo un problema: la construcción del programa;
Archivos de configuración simples: el desarrollador debe dedicar su tiempo a escribir código, no archivos de ensamblaje;
, ;
( , . .).
. Bake Ruby gem. Ruby ( 2.0). gem bake-toolkit rubygems.org:
gem install bake-toolkit
, :
mkdir myapp && cd myapp bake --create exe
,
bake -a black
**** Building 1 of 1: bake (Main) ****
Compiling bake (Main): src/main.cpp
Linking bake (Main): build/Main/bake
Building done.
-a
, bake ( , ANSI).
. , Bake , , . , .
, ( , bake --rebuild
):
bake -c
Cleaning done.
bake -v2 -a black
**** Applying 1 of 2: bake (IncludeOnly) ****
**** Building 2 of 2: bake (Main) ****
g++ -c -MD -MF build/Main/src/main.d -Iinclude -o build/Main/src/main.o src/main.cpp
g++ -o build/Main/bake build/Main/src/main.o
Building done.
-v(0-3)
output, , 2, .
, :
my_app
|
|-- .bake
`-- .gitignore
|-- Default.Project.meta.cache
|-- Project.meta.cache
|-- build
`-- Main
`-- src
| `-- main.cmdline
| |-- main.d
| |-- main.d.bake
| |-- main.o
|-- .gitignore
|-- my_app
|-- my_app.cmdline
|-- Project.meta
|-- include
`-- src
`-- main.cpp
Project.meta , CMakeLists.txt CMake, . Bake, , . Project.meta .
.bake -, , Bake . . , Bake .gitignore Git.
build . main.o my_app, .cmdline , /. .d.bake header . build , Project.meta, Main , .
Project default: Main {
RequiredBakeVersion minimum: "2.66.0"
Responsible {
Person "mdanilov"
}
CustomConfig IncludeOnly {
IncludeDir include, inherit: true
}
ExecutableConfig Main {
Files "src/*/.cpp"
Dependency config: IncludeOnly
DefaultToolchain GCC
}
}
Bake , . , - RText. Bake .
, VSCode extension . IDE .
, Project , . ( Config) - (, bake ). - Config’, 3 - LibraryConfig , ExecutableConfig , ELF , , CustomConfig . , IncludeOnly CustomConfig Main ExecutableConfig, default.
Bake Config include ( CMake include_directories target_include_directories), CustomConfig IncludeOnly, Bake Config.
, IncludeDir include , header . API, , include . inherit , Dependency.
ExecutableConfig , , Files. C Dependency Config, CustomConfig IncludeOnly. , include (. inherit: true ).
DefaultToolchain, Bake - . gcc.
toolchain :
bake --toolchain-names
Available toolchains:
* Diab
* GCC
* CLANG
* CLANG_ANALYZE
* CLANG_BITCODE
* TI
* GreenHills
* Keil
* IAR
* MSVC
* GCC_ENV
* Tasking
Hello world ,
workspace.
, my_app, libA, libB, libC. libB libC, libC . unit libB.
Bake. Project.meta toolchain , Project.meta ( Project.meta , ).
Project.meta Flags. C++, (Linker), C (Compiler C), (Compiler ASM) (Archiver). - GCC toolchain bake --toolchain-info GCC
.
Bake Config. ( , . .) CommandLine ( ). , release MakeDir Copy PostSteps.
, ArtifactName , Main .
Bake 3 : , .
Project.meta :
libA/Project.meta
Project default: Lib {
CustomConfig IncludeOnly {
IncludeDir include, inherit: true
}
LibraryConfig Lib {
Files "src/*/.cpp"
Dependency config: IncludeOnly
Toolchain {
Compiler CPP {
Flags remove: "-O2 -march=native"
}
}
}
}
Bake toolchain Config. libA , DefaultToolchain, .
libB/Project.meta
Project default: Lib {
CustomConfig IncludeOnly {
IncludeDir include, inherit: true
}
LibraryConfig Lib {
Files "src//.cpp"
Dependency config: IncludeOnly
Dependency libC, config: IncludeOnly
}
ExecutableConfig UnitTest {
Files "test/src//.cpp"
Dependency config: Lib
DefaultToolchain GCC
}
}
libB , UnitTest. Config , DefaultToolchain ( , UnitTest).
libC/Project.meta
Project default: Lib {
CustomConfig IncludeOnly {
IncludeDir include, inherit: true
}
LibraryConfig Lib {
ExternalLibrary "libC.a", search: false
Dependency config: IncludeOnly
}
}
libC , , ExternalLibrary.
, bake -p <dir>
, dir (libA, libB, ..).
1) Bake, , -j . , . 1 : bake -j 1
2) compile_commands.json. bake --compile-db compile_commands.json
3) . bake --prebuild
, Config, , Config . Project.meta :
Prebuild {
Except <project>, config: <config>
...
}
, SDK, , , .
SDK, , , API, Except . SDK bake --prebuild
.
4) bakery. UnitTest bakery -b AllUnitTests
, Collection.meta, bakery Config :
Collection AllUnitTests {
Project "*", config: UnitTest
}
5) . bake --dot DependencyGraph.dot
:
6) JSON incudes defines bake --incs-and-defs=json
:
"myapp": {
"includes": [
"libA/include",
"libB/include",
"libC/include"
],
"cppdefines": [],
"c_defines": [],
"asm_defines": [],
"dir": "/Users/mdanilov/Work/my_app"
}
Adaptions Bake
Adaptions Bake. , , , .
Project.meta, Adapt.meta ( ). . , --adapt
.
. , gcc ( DefaultToolchain GCC) Clang , Project.meta. Bake, Adapt.meta:
Adapt {
ExecutableConfig __MAIN__, project: __MAIN__, type: replace {
DefaultToolchain CLANG
}
}
, (replace) DefaultToolchain Config , __MAIN__ .
: Adapt.meta , Bake ( Project.meta).
clang, bake --adapt clang
, Clang.
__ALL__, . . , replace, remove, extend push_front. , , .
, --adapt
.
:
Adapt toolchain: GCC, os: Windows {
…
}
GCC Windows. Adapt If ( Unless, ) .
, , C/C++.
, Bake , . , Bake. , , .
Pero, si escribo mi próxima aplicación en C / C ++ para compilar, probablemente seguiré usando CMake. Bueno, porque es CMake :)