A maioria de vocês provavelmente concordará que o CMake é de longe o sistema de construção mais popular para projetos C / C ++. Imagine minha surpresa ao ver no projeto do novo trabalho seu próprio sistema de compilação - Bake .
Neste artigo gostaria de descrever as principais características deste sistema, como ele difere de outros sistemas semelhantes e mostrar como ele pode ser usado para resolver vários problemas que surgem no processo de desenvolvimento de um programa.
Bake é um sistema de construção multiplataforma para projetos C / C ++, voltado principalmente para sistemas embarcados. Bake é escrito em Ruby, de código aberto e ainda com suporte (em desenvolvimento desde 2012)
Os principais objetivos que os desenvolvedores aspiravam ao criar esta solução:
Utilitário de linha de comando (há suporte para plug-ins para alguns editores, incluindo VSCode);
O que deve resolver apenas um problema - construir o programa;
Arquivos de configuração simples - o desenvolvedor deve gastar seu tempo escrevendo código, não arquivos de montagem;
, ;
( , . .).
. 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.cppProject.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
* TaskingHello 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. , , .
Mas, se eu escrever meu próximo aplicativo em C / C ++ para construção, provavelmente ainda usarei o CMake. Bem, porque é CMake :)