Project Icon

bake

轻量级C/C++项目构建与管理工具

bake是一款轻量级C/C++项目构建工具,致力于简化开发流程。它具有平台无关的最小化配置、一键创建项目、内置WebAssembly支持等特性。bake直接调用编译器,无需额外依赖,支持逻辑名称引用依赖项和自动包含头文件。其他功能包括符号导出宏、自动项目发现与构建、单一源文件生成等。bake兼容Linux、MacOS和Windows平台,并已在多个主流编译器上验证。

.github/workflows/main.yml

bake

The Dutch IRS has a catchy slogan, which goes like this: "Leuker kunnen we 't niet maken, wel makkelijker". Roughly translated this means: "We can't make it more fun, but we can make it easier". Bake adopts a similar philosophy. Building C/C++ code will never be fun, but with bake you'll probably spend a little less time worrying about it.

Here's how bake tries to alleviate some of the pain:

  • Minimal, platform independent project configuration (as in 2 lines of JSON minimal)
  • Create new projects with a single command
  • Builtin emscripten (webasm) support
  • Zero-dependencies, calls msvc, gcc, clang and emcc compilers directly
  • Refer to dependencies by logical names, no OS/environment dependent paths
  • Automatically include headers from dependencies
  • Out of the box macro's for exporting symbols
  • Automatically discover, order and build projects in directories without additional config
  • Recursively build projects & their dependencies for the right config with a single command
  • Generate single source/header files from any project
  • A test framework
  • Clone, build and run projects with their dependencies with a single command
  • Make projects warning free on all compilers/compiler versions with strict compilation mode
  • Out of the box support for running projects with address sanitizers
  • Manage projects & their git repositories with bake bundles

Bake is verified on the following platforms:

  • Linux
  • MacOS
  • Windows

Bake is verified on the following compilers

  • gcc (7, 8, 9, 10)
  • clang (8, 9, 10)
  • msvc

Bake is used as the primary build system for Flecs.

Contents

Installation

Install bake using the following commands:

On Linux/MacOS:

git clone https://github.com/SanderMertens/bake
bake/setup.sh

On Windows:

Requires Visual Studio Build Tools or the full Visual Studio Community IDE installed with the C++ CMake tools for Windows and Windows SDK individual components included in the Desktop development with C++ workload:

git clone https://github.com/SanderMertens/bake
cd bake
setup

On MacOS/Linux bake will install a single script in /usr/local/bin which calls the bake binary in ~/bake, which may prompt for your password during installation. This script allows you to call bake from any location without having to make changes to your environment.

If you'd rather not install this script, you can install bake in local mode:

git clone https://github.com/SanderMertens/bake
cd bake
make -C build-$(uname) clean all
./bake setup --local

After the setup has finished, the bake executable will be stored in ~/bake. Make sure to add this directory to your PATH variable before using bake.

Upgrade bake

You can upgrade bake to the latest version by running this command:

bake upgrade

Getting started

The following commands are useful for getting started with bake. Also, check out the bake --help command, which lists all the options and commands available in the bake tool.

Create and run new project

To create and run a new bake application project called my_app, run the following commands:

bake new my_app
bake run my_app

You can also run projects in interactive mode. This will automatically rebuild and restart an application when a project file changes. To run in interactive mode, simply add --interactive to the bake command:

bake run my_app --interactive

Basic configuration with dependency and configuration for C driver

This example shows a simple configuration with a dependency on the foo.bar package and links with pthread.

{
    "id": "my_app",
    "type": "application",
    "value": {
        "use": ["foo.bar"]
    },
    "lang.c": {
        "lib": ["pthread"]
    }
}

Build, rebuild and clean a project

bake
bake rebuild
bake clean

Specify a build configuration:

bake --cfg release

Clone & build a project from git

Build a project and its dependencies directly from a git repository using this command:

bake clone https://github.com/SanderMertens/example

Export an environment variable to the bake environment

Bake can manage environment variables that must be set during the build. To export an environment variable to the bake environment, use this command:

bake export VAR=value

Alternatively, if you want to add a path to an environment variable like PATH or LD_LIBRARY_PATH, use this:

bake export PATH+=/my/path

These variables are stored in a configuration file called bake.json in the root of the bake environment, which by default is $HOME/bake.

To export the bake environment to a terminal, use:

export `bake env`

FAQ

Bake is built under the GPL3.0 license. Does this mean I cannot use it for commercial projects?

No. As long as you do not distribute bake (either as source or binary) as part of your (closed source) deliverable, you can use bake for building your projects. This is no different than when you would use make for your projects, which is also GPL licensed.

I want my customers to use bake. Does the license allow for this?

Yes. As long as your customers use the open source version of bake, and you do not distribute bake binaries or source files with your product, your customers can use bake.

I noticed a premake file in the bake repository. Does bake need premake to be installed?

No. Bake uses premake to generate its makefiles (we would've used bake to build bake- but chicken & egg etc). The generated makefiles are included in the bake repository, so you won't need premake to use bake.

Why yet another build tool?

To put it bluntly, existing tools for C/C++ aren't great.

Is bake a package manager?

No. Bake has package-management like features, like resolving projects by logical name, automatic project discovery & associate projects with git repositories, but it does not pretend to be a full-fledged package manager. The only reason bake has these features is because it makes the build process easier.

Why are bake project configurations so simple?

All C/C++ project build configurations basically boil down to the same set of rules to translate source files into objects, and objects into shared objects or application binaries. Yet with most build systems you'll find yourself copy-pasting the same rules every time you create a new project.

Bake doesn't need to be told how to build C/C++ code. It just needs three pieces of information:

  • The project name
  • Whether it's an application or a package
  • A src and include directory

Why doesn't bake generate makefiles or visual studio files?

Makefiles and Visual Studio files are just elaborate front-ends for how to call compilers. Bake calls the compiler directly. It has builtin drivers for gcc, clang, msvc and emcc, and it automatically detects for which compiler it's building.

How does bake compare to make?

GNU make is a low-level tool that requires you to explicitly list all the rules required to translate code to binaries. Bake is a high-level tool that already knows how to build the code, and can do this with minimal configuration.

How does bake compare to CMake?

CMake is a tool that generates other build configurations. When you use CMake you still need to use another tool like Make or Visual Studio to actually build your project. Bake builds your code directly.

Another big difference is that CMake requires you to specify project configuration in a custom language, whereas Bake configuration is specified in JSON. Here is a CMake configuration and a Bake configuration for the same project:

CMake:

cmake_minimum_required (VERSION 2.6)

include_directories ("bar")
add_subdirectory (bar)
set (EXTRA_LIBS ${EXTRA_LIBS} bar)

project (foo)
add_executable(foo foo.c)

target_link_libraries (foo ${EXTRA_LIBS})

Bake:

{
    "id": "foo",
    "type": "application",
    "value": {
        "use": ["bar"]
    }
}

A difference that jumps out from the examples is that the bake configuration is agnostic to its environment. It knows where to find project bar, whereas in CMake this needs to be explicitly specified.

How does bake compare to premake?

Premake is a lot like CMake, but with a Lua-based project configuration that's slightly less verbose. Premake also generates build configurations, and requires additional tools to actually build your code.

How does bake compare to Bazel?

Out of all build systems, bake and bazel come closest in the way they approach building code. The biggest differences are:

  • Bake is a much, much smaller project
  • Bake is less controlling when it comes to your environment. If you want absolute control over which version of Python, make, gcc etc. you're using while building, Bazel can do a better job.
  • Bake only builds C/C++ code.
  • Bazel project identifiers are relative to a workspace. Bake project identifiers are universal.
  • Bazel has a custom language for project configuration

Can I link with non-bake libraries?

Yes. This example shows how to link with libm:

{
    "id": "my_app",
    "type": "application",
    "lang.c": {
        "lib": ["m"]
    }
}

This can be improved by ensuring that libm is only added on Linux (MacOS/Windows don't have libm):

{
    "id": "my_app",
    "type": "application",
    "${os linux}": {
        "lang.c": {
            "lib": ["m"]
        }
    }
}

I want to wrap a C library so I can use it as a bake dependency. How do I do this?

It would be nice if we could wrap libm.so from the previous example in a bake math package, so we don't have to repeat this configuration for every project. Bake lets us do this with the "dependee" attribute:

{
    "id": "math",
    "type": "package",
    "value": {
        "language": "none"
    },
    "dependee": {
        "${os linux}": {
            "lang.c": {
                "lib": ["m"]
            }
        }
    }
}

This creates a new "math" package that you can now specify as regular bake dependency. The "language": "none" attribute lets bake know that there is no code to build, and this is a configuration-only project. The dependee attribute tells bake to not apply the settings inside the JSON object to the math project, but to the projects that depend on math.

We can now use the math package like this:

{
    "id": "my_app",
    "type": "application",
    "value": {
        "use": ["math"]
    }
}

Where can I find the configuration options for C and C++ projects?

You can find language-specific configuration options in the README of the language driver projects:

For C: https://github.com/SanderMertens/bake/tree/master/drivers/lang/c

For C++: https://github.com/SanderMertens/bake/tree/master/drivers/lang/cpp

What is a driver?

All of the rules and instructions in bake that actually builds code is organized in bake "drivers". Drivers are shared libraries that bake loads when a project needs them. The most common used drivers are "language drivers", which contain all the build instructions for a specific language, like C or C++. Bake automatically loads the language drivers based on the "language" attribute in your project.json, as is specified here:

{
    "id": "my_app",
    "type": "application",
    "value": {
        "language": "c"
    }
}

By default the language is set to "c", so if you do not specify a language, your project will build as a C project.

What does "lang.c" mean? When do I need to specify it?

In some cases you will want to provide configuration options that are specific to a language, like linking with C libraries on your system, or provide additional compiler flags. In that case, you have to tell bake that the configuration you are about to specify is for a specific driver. This is where "lang.c" comes in:

{
    "id": "my_app",
    "type": "application",
    "value": {
        "language": "c"
    },
    "lang.c": {
        "lib": ["m"]
    }
}

The "lang.c" member uniquely identifies the bake driver responsible for building C code, and bake will make all of the attributes inside the object ("lib") available to the driver.

If you want to build a C++ project, instead of using the "lang.c" attribute, you have to use the "lang.cpp" attribute, which identifies the C++ driver:

{
    "id": "my_app",
    "type": "application",
    "value": {
        "language": "c++"
    },
    "lang.cpp": {
        "lib": ["m"]
    }
}

For C++ projects, should I specify cpp or c++ for the language attribute?

You can use either, but for specifying driver-specific configuration you always have to use lang.cpp.

How can I see a list of the available drivers?

The following command will show you a list of the available drivers:

bake list bake.*

Everything except for bake.util is a driver. If you just built bake for the first time, this will only show the "lang.c" and "lang.cpp" drivers.

Can I load more than one driver?

Yes! You can load as many drivers as you want. If you want to add a driver, simply add it to your configuration like this:

{
    "id": "my_app",
    "type": "application",
    "my_custom_driver": { }
}

Are there any example drivers I can use as a template?

Driver documentation is a bit lacking at the moment, but we will eventually address that. In the meantime, you can take a look at the C driver to see what a fully fledged driver looks like:

https://github.com/SanderMertens/bake/tree/master/drivers/lang/c

How do I install bake packages?

Bake relies on git to store packages. To install a package, use the bake clone command with a GitHub repository identifier:

bake clone SanderMertens/example

If your git repository is not hosted on GitHub, simply provide the full git URL:

bake clone https://my_git_server.com/example

Any URL that is accepted by git is accepted by bake.

How does bake find dependencies of cloned projects?

When bake clones a package with dependencies, it will try to also install those dependencies. It does this by taking the git URL specified to bake clone, and replacing the package name with the dependency name. For example, if the https://github.com/SanderMertens/example git repository depends on project foobar, bake would also look for https://github.com/SanderMertens/foobar.

Future versions of bake may provide more intelligent ways to locate packages.

Why use JSON for project configuration?

A number of people have asked me why I used JSON for project configuration. There are two reasons:

  • It is a ubiquitous language that everyone understands,
  • It has a C parser that can be easily embedded into bake without adding dependencies

A disadvantage of JSON is that while it is fine for trivial configurations, it can get a bit unwieldy once project configurations get more complex. In bake however, you can encapsulate complexity into a configuration-only project, and then include that project as a dependency in your project configuration (example).

Additionally, bake is not like traditional build tools where you specify rules with inputs and outputs in your project configuration. If you want to, for example, add a code generation step to your build, you write a driver for it, and then include the driver in your project configuration.

How can I specify a custom compiler?

The drivers for C & C++ projects by default use gcc/g++ (on Linux) and clang/clang++ (on MacOS). If you want to change the default compiler, you can set the CC (for C) and CXX (for C++) environment variables, as long as the command line options are compatible with gcc. Instead of setting the environment variables manually, you can make them part of a bake environment like this:

bake export CC=clang --env clang_env

To use the environment, and build with clang, you can then invoke bake like

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号