La plupart d'entre vous conviendront probablement que CMake est de loin le système de construction le plus populaire pour les projets C / C ++. Imaginez ma surprise de voir dans le projet au nouveau travail son propre système de construction - Bake .
Dans cet article, je voudrais décrire les principales caractéristiques de ce système, en quoi il diffère des autres systèmes similaires et montrer comment il peut être utilisé pour résoudre divers problèmes qui surviennent lors du développement d'un programme.
Bake est un système de construction multiplateforme pour les projets C / C ++ visant principalement les systèmes embarqués. Bake est écrit en Ruby, open source et toujours supporté (en développement depuis 2012)
Les principaux objectifs des développeurs lors de la création de cette solution:
Utilitaire de ligne de commande (il existe un support pour les plugins pour certains éditeurs, y compris VSCode);
Ce qui ne devrait résoudre qu'un seul problème - la construction du programme;
Fichiers de configuration simples - le développeur doit passer son temps à écrire du code, pas des fichiers d'assemblage;
, ;
( , . .).
. 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. , , .
Mais, si j'écris ma prochaine application en C / C ++ pour la construction, j'utiliserai probablement toujours CMake. Eh bien, parce que c'est CMake :)