Die meisten von Ihnen werden wahrscheinlich zustimmen, dass CMake das mit Abstand beliebteste Build-System für C / C ++ - Projekte ist. Stellen Sie sich meine Überraschung vor, im Projekt bei der neuen Arbeit ein eigenes Build-System zu sehen - Bake .
In diesem Artikel möchte ich die Hauptmerkmale dieses Systems beschreiben, wie es sich von anderen ähnlichen Systemen unterscheidet, und zeigen, wie es zur Lösung verschiedener Probleme verwendet werden kann, die bei der Entwicklung eines Programms auftreten.
Bake ist ein plattformübergreifendes Build-System für C / C ++ - Projekte, das hauptsächlich auf eingebettete Systeme abzielt. Bake ist in Ruby geschrieben, Open Source und wird weiterhin unterstützt (in Entwicklung seit 2012).
Die Hauptziele, die die Entwickler bei der Erstellung dieser Lösung anstrebten:
Befehlszeilenprogramm (für einige Editoren, einschließlich VSCode, werden Plugins unterstützt);
Was nur ein Problem lösen sollte - das Erstellen des Programms;
Einfache Konfigurationsdateien - Der Entwickler sollte seine Zeit damit verbringen, Code zu schreiben, keine Assembly-Dateien.
, ;
( , . .).
. 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. , , .
Wenn ich jedoch meine nächste Anwendung in C / C ++ zum Erstellen schreibe, werde ich wahrscheinlich weiterhin CMake verwenden. Nun, weil es CMake ist :)