【译】Ninja 构建系统

CMake + Ninja 构建程序示例 Ninja是一种专注于速度的小型构建系统,特别适合用于大型项目的增量编译。它最初由 Google 的工程师为加速 Chromium 浏览器的构建过程而开发,并逐渐成为一种广泛使用的替代构建工具,尤其是在配合 CMake 等高级构建配置工具时。 阅读详情

Ninja 是设计目标为速度快而生的构建系统,通过官方的博客,本文来深入了解下 Ninja 为何而快。

内容来源: https://aosabook.org/en/posa/ninja.html
原文标题:Ninja
作者:Evan Martin
译者:流左沙
注:翻译较原文会有一定的精简、重排和添删,主要是为了提取重要内容以达到更好的理解,请以原文为准。

As input you describe the commands necessary to process source files into target files. Ninja uses these commands to bring targets up to date. Unlike many other build systems, Ninja’s main design goal was speed.

输入是描述从源文件到目标文件的所需要的参数,Ninja 用这些命令更新目标文件。与其他构建系统不同的是,Ninja 的主要目标是速度快。

Ninja’s other main design goal followed: Ninja needed to be easily embedded within a larger build system.

另一个目标就是:Ninja 需要很方便地就可以嵌入到大型的构建系统。

Design

At a high level any build system performs three main tasks. It will (1) load and analyze build goals, (2) figure out which steps need to run in order to achieve those goals, and (3) execute those steps.

构建系统主要有三个任务:加载和分析编译目标、理解哪些步骤需要被执行、运行这些步骤。

Ninja’s build file language is therefore simple to the point of being inconvenient for humans to write. There are no conditionals or rules based on file extensions. Instead, the format is just a list of which exact paths produce which exact outputs. These files can be loaded quickly, requiring almost no interpretation.

Ninja 的构建文件所用的语言是如此的简陋,对于人而言是很难编写的。它没有对于文件扩展的状态或者规则。它只有一系列指定的输入和输出。这些文件可以被加载得很快,不需要任何的理解时间。

This minimalist design counterintuitively leads to greater flexibility. Because Ninja lacks higher-level knowledge of common build concepts like an output directory or current configuration, Ninja is simple to plug into larger systems (e.g., CMake, as we later found) that have different opinions about how builds should be organized. For example, Ninja is agnostic as to whether build outputs (e.g., object files) are placed alongside the source files (considered poor hygiene by some) or in a separate build output directory (considered hard to understand by others). Long after releasing Ninja I finally thought of the right metaphor: whereas other build systems are compilers, Ninja is an assembler.

最少量的设计反而带来了更好的灵活性。因为 Ninja 对于基本的编译概念缺乏高层级的知识,所以它很容易就能嵌入到不同操作的大型系统中。例如,Ninja 对于编译输出是否放在源文件那或者单独的一个目录是无感知的。总的来说,其他构建系统是编译器,而 Ninja 是集成者。

Philosophical

Where other build systems are high-level languages, Ninja aims to be an assembler.

其他的构建系统都是高级语言,而 Ninja 目标是当一个集成器。

Build systems get slow when they need to make decisions. When you are in a edit-compile cycle you want it to be as fast as possible — you want the build system to do the minimum work necessary to figure out what needs to be built immediately.

构建系统由于需要去做判断所以会变得慢。如果想加快,那么就要构建系统只做最小的必要的工作来完成构建。

Ninja contains the barest functionality necessary to describe arbitrary dependency graphs. Its lack of syntax makes it impossible to express complex decisions.

Ninja 包含了描述任意依赖关系图的所必需的最基本的功能。它缺乏语法去表达复杂的决策。

Instead, Ninja is intended to be used with a separate program generating its input files. The generator program (like the ./configure found in autotools projects) can analyze system dependencies and make as many decisions as possible up front so that incremental builds stay fast. Going beyond autotools, even build-time decisions like "which compiler flags should I use?" or "should I build a debug or release-mode binary?" belong in the .ninja file generator.

Ninja 用来和一个单独的进程来生成其输入文件。生成器进程可以分析系统依赖关系,提前做好尽可能多的决策来加快增量构建。除了 autotools 之外,应该用什么编译参数、应该用 debug 模式还是 release 模式,都在 .ninja 文件生成器中。

Work

A human needs to debug the files when the build rules are wrong, so .ninja build files are plain text, similar to Makefiles, and they support a few abstractions to make them more readable.

当出错时我们需要调试文件,所以 .ninja 文件是纯文本,和 Makefiles 类似,它还支持一些抽象的概念来提供可读性。

The first abstraction is the “rule”, which represents a single tool’s command-line invocation. A rule is then shared between different build steps. Here is an example of the Ninja syntax for declaring a rule named “compile” that runs the gcc compiler along with two build statements that make use of it for specific files.

第一个抽象概念是规则,代表的是一个工具的参数调用。一个规则在不同的编译步骤中可以共享。如下案例:

rule compile
  command = gcc -Wall -c $in -o $out
build out/foo.o: compile src/foo.c
build out/bar.o: compile src/bar.c

The second abstraction is the variable. In the example above, these are the dollar-sign-prefixed identifiers ($in and $out). Variables can represent both the inputs and outputs of a command and can be used to make short names for long strings. Here is an extended compile definition that makes use of a variable for compiler flags:

第二个抽象概念是变量。在上面的案例中,是有美元符号 $ 的标识符。变量可以代表着参数中的输入和输出,可以用来简短长串。

cflags = -Wall
rule compile
  command = gcc $cflags -c $in -o $out

The build file, once parsed, describes a graph of dependencies: the final output binary depends on linking a number of objects, each of which is the result of compiling sources. Specifically it is a bipartite graph, where “nodes” (input files) point to “edges” (build commands) which point to nodes (output files)6. The build process then traverses this graph.

构建文件一旦被解析,就会有依赖图:最终输出的二进制是由一堆目标文件链接而成的,每一个都是编译源文件的结果。这是二向图,输入文件通过编译参数(边)指向了输出文件。编译过程就是遍历这个图。

Given a target output to build, Ninja first walks up the graph to identify the state of each edge’s input files: that is, whether or not the input files exist and what their modification times are. Ninja then computes a plan. The plan is the set of edges that need to be executed in order to bring the final target up to date, according to the modification times of the intermediate files. Finally, the plan is executed, walking down the graph and checking off edges as they are executed and successfully completed.

给定一个编译目标,Ninja 首先会遍历图的每条边以确认每个输入文件的状态:输入文件是否存在,以及它们的修改时间是什么时候。Ninja 会计算一个计划列表,这个计划列表是一系列需要被执行的边(用以更新输出目标),根据中间文件的修改时间来进行判断。最终,计划列表里的边会被执行,遍历这个图然后检查这些边是否被执行成功。

Optimizing

The initial implementation of Ninja was careful to arrange the data structures in order to allow a fast build, but wasn’t particularly clever in terms of optimizations. Once the program worked, I reasoned, a profiler could reveal which pieces mattered.

Ninja 的初始版本是小心地安排数据结构以达到快速编译,但并非对于优化足够清晰。一旦程序跑起来,profiler 可以知道哪些部分是重要的。

Over the years, profiling pointed at different pieces of the program. Sometimes the worst offender was a single hot function that could be micro-optimized. At other times, it suggested something more broad like being careful not to allocate or copy memory except when necessary. There were also cases where a better representation or data structure had the most impact. What follows is a walk through the Ninja implementation and some of the more interesting stories about its performance.

profile 文件指向程序的不同地方。有时更糟糕的是一个热函数会被小量的优化。其他时候,它会建议只在必要时才分配或复制内存。对于更好的代码结构和数据结构影响更大。之后就是编译 Ninja 的实现,优化它的性能。

Parser

Initially Ninja used a hand-written lexer and a recursive descent parser. The syntax was simple enough, I thought. It turns out that for a large enough project like Chrome8, simply parsing the build files (named with the extension .ninja) can take a surprising amount of time.

早期时 Ninja 使用手写的 lexer 和递归下降的解析器。这个语法是十分地简单,导致大型工程的构建文件 (.ninja) 会占用大量的时间。

A simple fix–at the time saving 200 ms–was to replace the function with a 256-entry lookup table that could be indexed by the input character.

使用表结构来处理输入参数可以加快这个时间。

Canonicalization

Ninja avoids using strings to identify paths. Instead, Ninja maps each path it encounters to a unique Node object and the Node object is used in the rest of the code. Reusing this object ensures that a given path is only ever checked on disk once, and the result of that check (i.e., the modification time) can be reused in other code.

Ninja 不用字符串表示路径。相反,它把每个路径映射成一个节点来使用。重用这个节点可以让它只在磁盘检查一次路径,而且检查结果也能够复用。

To always use the same Node for a single file, Ninja must reliably map every possible name for a file into the same Node object. This requires a canonicalization pass on all paths mentioned in input files, which transforms a path like foo/../bar.h into just bar.h. Initially Ninja simply required all paths to be provided in canonical form but that ends up not working for a few reasons. One is that user-specified paths (e.g., the command-line ninja ./bar.h) are reasonably expected to work correctly. Another is that variables may combine to make non-canonical paths. Finally, the dependency information emitted by gcc may be non-canonical.

为了使同一个节点代表的是同一个文件,Ninja 需要非常可靠地把路径名映射到节点。这需要一个规范化的 pass 去处理输入文件的所有路径。开始时,Ninja 会需要所有的路径都以规范化的格式组织起来,但最终没有用处,一个是用户指定的路径,另一个则是变量可能会被拼接成一个非规范化的路径。最后,gcc 生成的依赖信息就不是规范化的。

Thus most of what Ninja ends up doing is path processing, so canonicalizing paths is another hot point in profiles. The original implementation was written for clarity, not performance, so standard optimization techniques–like removing a double loop or avoiding memory allocation–helped considerably.

因此大多数时候 Ninja 是在解析路径,所以规范化的路径是 profile 文件上的热点。原始的实现是为了写得清晰,但没有好的性能,所以标准优化技术像去除双重循环和避免内存分配都很有作用。

Build Log

One part of the Linux kernel build system tracks the commands used to generate outputs. Consider a motivating example: you compile an input foo.c into an output foo.o, and then change the build file such that it should be rebuilt with different compilation flags. For the build system to know that it needs to rebuild the output, it must either note that foo.o depends on the build files themselves (which, depending on the organization of the project, might mean that a change to the build files would cause the entire project to rebuild), or record the commands used to generate each output and compare them for each build.

一部分的构建系统是根据参数来生成输出文件的。比如我们修改了参数就得重编。构建系统想知道是否需要重编输出文件,它就需要标记输出文件依赖于哪些构建文件(.ninja),否则需要记录用来生成输出文件的参数并进行对比。

While building, Ninja writes out a build log that records the full commands used to generate each output.9 Then for each subsequent build, Ninja loads the previous build log and compares the new build’s commands to the build log’s commands to detect changes. This, like loading build files or path canonicalization, was another hot point in profiles.

编译时,Ninja 生成一个 build log 来记录输出文件的全部参数。然后在之后每次编译时,它会加载之前的 build log 然后对比参数来判断是否改变了。像加载构建文件(.ninja)或者规范化,都是 profile 里的热点。

After making a few smaller optimizations Nico Weber, a prolific contributor to Ninja, implemented a new format for the build log. Rather than recording commands, which are frequently very long and take a lot of time to parse, Ninja instead records a hash of the command. In subsequent builds, Ninja compares the hash of the command that is about to be run to the logged hash. If the two hashes differ, the output is out of date. This approach was very successful. Using hashes reduced the size of the build log dramatically–from 200 MB to less than 2 MB on Mac OS X–and made it over 20 times faster to load.

在进行过一些少量优化之后,实现了一个 build log 的新格式。为了避免记录所有的参数(耗时巨大),Ninja 采用记录参数的哈希值。在之后的编译,直接比较哈希值就可以了。这个优化减少了 build log 的大小和优化了将近 20 倍的速度。

Dependency Files

Some build systems use a “header scanner” to extract these dependencies at build time, but this approach can be slow and is difficult to make exactly correct in the presence of #ifdef directives. Another alternative is to require the build files to correctly report all dependencies, including headers, but this is cumbersome for developers: every time you add or remove an #include statement you need to modify or regenerate the build.

一些构建系统采用头文件扫描的方式在编译时提取依赖信息,但这个方式会很慢,而且很难去正确地提取,尤其是在宏判断之下。另一个选择是需要构建文件(.ninja)去正确地反映这些依赖,包括头文件,但这对于开发者而言很繁琐:需要跟着宏的修改同步操作。

A better approach relies on the fact that at compile time gcc (and Microsoft’s Visual Studio) can output which headers were used to build the output. This information, much like the command used to generate an output, can be recorded and reloaded by the build system so that the dependencies can be tracked exactly. For a first-time build, before there is any output, all files will be compiled so no header dependency is necessary. After the first compilation, modifications to any files used by an output (including modifications that add or remove additional dependencies) will cause a rebuild, keeping the dependency information up-to-date.

一个更好的方式是依赖 gcc 在编译时可以得到输出文件用到哪些头文件。这些信息有点像哪些参数用来生成输出文件,可以被构建系统记录或重复加载,所以依赖信息可以被追踪。在第一次编译时,在存在任何输出之前,所有文件都会被编译,所以没有用到头文件依赖信息的必要。在之后的编译,修改任何输出文件用到的文件都会引起重编,保证依赖信息是最新的。

When compiling, gcc writes header dependencies in the format of a Makefile. Ninja then includes a parser for the (simplified subset) Makefile syntax and loads all of this dependency information at the next build. Loading this data is a major bottleneck. On a recent Chrome build, the dependency information produced by gcc sums to 90 MB of Makefiles, all of which reference paths which must be canonicalized before use.

当编译时,gcc 以 Makefile 的格式写出头文件的依赖信息。Ninja 会包含一个 Makefile 的语法解析器,然后会在下次编译时加载所有的依赖信息。加载这些数据是主要的瓶颈。Makefile 的大小和引用的路径需要被规范化都占用大量的时间。

Once Ninja has started executing build commands, all of the performance-critical work has been completed and Ninja is mostly idle as it waits for the commands it executes to complete. In this new approach for header dependencies, Ninja uses this time to process the Makefiles emitted by gcc as they are written, canonicalizing paths and processing the dependencies into a quickly deserializable binary format. On the next build Ninja only needs to load this file. The impact is dramatic, particularly on Windows. (This is discussed further later in this chapter.)

一旦 Ninja 开始处理编译参数,所有的性能监控都会被完成,Ninja 是几乎空闲的,因为它在等在参数被执行完成。在最新的头文件依赖的记录方法中,Ninja 使用这部分时间来处理 gcc 写出的 Makefile 文件,规范化路径,以及把依赖转成可快速反序列化的二进制格式。在下一次编译时,Ninja 只需要加载这个文件。

The “dependency log” needs to store thousands of paths and dependencies between those paths. Loading this log and adding to it needs to be fast. Appending to this log should be safe, even in the event of an interruption such as a cancelled build.

这个依赖日志需要存储上千的路径和路径间的依赖关系。加载这个日志或者写入这个日志都需要快。日志增加需要是安全的,即使在编译被中断时。

After considering many database-like approaches I finally came up with a trivial implementation: the file is a sequence of records and each record is either a path or a list of dependencies. Each path written to the file is assigned a sequential integer identifier. Dependencies are then lists of integers. To add dependencies to the file, Ninja first writes new records for each path that doesn’t yet have an identifier and then writes the dependency record using those identifiers. When loading the file on a subsequent run Ninja can then use a simple array to map identifiers to their Node pointers.

最终的实现方式是:这个文件是一系列的记录,每个记录要么是路径,要么是一系列的依赖。每个写入这个文件的路径都被赋值一个唯一的整型标识符。依赖就是一系列的整数。为了给这个文件添加依赖,Ninja 首先写入每个路径的新的记录(还没有标识符的),然后使用它们的标识符来写入依赖。当加载这个文件时,Ninja 可以使用简单的数组来映射每个标识符到它的节点。

Executing a Build

Ninja runs build commands in parallel by default, based on the number of available CPUs on the system. Since commands running simultaneously could have their outputs interleave, Ninja buffers all output from a command until that command completes before printing its output. The resulting output appears as if the commands were run serially.11

Ninja 默认会并行编译,基于系统的可用 CPU 的数量。由于同时运行编译会存在输出文件有交集的情况,Ninja 将一个命令的所有输出文件都缓存起来,直到这个命令被执行完成。

This control over command output allows Ninja to carefully control its total output. During the build Ninja displays a single line of status while running; if the build completes successfully the total printed output of Ninja is a single line.12 This doesn’t make Ninja run any quicker but it makes Ninja feel fast, which is almost as important to the original goal as real speed is.

在编译时,Ninja 会用一行文字来显示运行状态,成功后也只会显示一行文字。这会让 Ninja 感觉很快。

Comparison to Make

Ninja is closest in spirit and functionality to Make, relying on simple dependencies between file timestamps.

Ninja 本质上和功能上与 Make 相近,依赖于文件时间戳之间的简单依赖关系。

But fundamentally, make has a lot of features: suffix rules, functions, built-in rules that e.g. search for RCS files when building source. Make’s language was designed to be written by humans. Many projects find make alone adequate for their build problems.

但基本上,Make 还有大量的特性。Make 语言设计成人类可写的形式,许多项目只用 make 就能解决构建的问题。

In contrast, Ninja has almost no features; just those necessary to get builds correct while punting most complexity to generation of the ninja input files. Ninja by itself is unlikely to be useful for most projects.

相反的,Ninja 几乎没有任何特性。只是那些必要的能力:在生成 ninja 输入文件的复杂流程中,保证构建的正确性。

Conclusions

Simplicity is a virtue in software; the question is always how far it can go. Ninja managed to cut much of the complexity from a build system by delegating certain expensive tasks to other tools (GYP or CMake), and because of this it is useful in projects other than the one it was made for. Ninja’s simple code hopefully encouraged contributions– the majority of work for supporting OS X, Windows, CMake, and other features was done by contributors. Ninja’s simple semantics have led to experiments by others to reimplement it in other languages (Scheme and Go, to my knowledge).

Ninja 通过把复杂的操作转交给其他工具,成功降低了构建系统的复杂性。Ninja 简单的代码逻辑吸引了很多开发者的贡献,主要是支持了 OS X、Windows、Cmake 等。同时它简单的语法也催生出很多其他编程语言的版本。

reference

https://aosabook.org/en/posa/ninja.html

https://ninja-build.org/manual.

Android源码编译加速:Ninja工具详解与构建系统解析 随着Android操作系统的不断进化,其版本更迭日益频繁,尤其是Android 10与Android 11的源码编译过程,开发者们面临了一个显著的问题:单模块编译时间的冗长。通常情况下,完成一次单模块的编译需要耗费半个小时甚至更长时间,这主要归因于编译过程中需要重新加载全部mk文件,并经由这一系列复杂的步骤生成ninja编译文件,而这一预处理阶段异常缓慢,相比之下,实际的编译过程则显得相当迅速。为了应对这一挑战,Google引入了ninja这一高效的编译工具,它极大地缩短了编译时间。 阅读详情

相关推荐

WebRTC编译系统之gn和ninja

WebRTC现在使用 gn 来生成构建脚本,使用 ninja 来构建。

安晓辉生涯——聚焦程序员的职业规划与成长 1万+

构建工具: Ninja 学习笔记

Ninja 是一个基于 Ninja Build System 或简称为 Ninja 的构建工具。它旨在提供一种高效的、易于理解的构建系统,适用于各种规模的项目。Ninja 将构建过程分解为相互独立的任务,并使用简洁的文件格式来描述构建规则,从而实现快速和可靠的构建。Ninja 是一个强大而高效的构建工具,适用于各种规模的项目。本篇博客对 Ninja 的使用方法和原理进行了全面的介绍,并提供了相关的学习笔记。希望这些内容能够帮助你更好地理解和应用 Ninja。

m0_72410588的博客 3341

用 Ninja and GN 来加速 C++构建

Ninja Ninja 原意是忍者的意思,它是一个专注于速度的小型构建工具。它是一个构建系统。 它将文件的相互依赖关系(通常是源代码和输出可执行文件)作为输入,并快速编排构建它们。 运行Ninja,默认情况下,它会在当前目录中查找名为 build.ninja 的文件并构建所有过时的目标。 您可以指定要构建的目标(文件)作为命令行参数。 还有一个特殊的语法 target^ 用于将目标指定为某个规则的...

温故而知新 2437

构建系统简介以及分布式Ninja实现原理

cloudbuild基于remoteapi实现了ninja的分布式构建,保留了原有Ninja的优点且能够快速的分布式编译大型项目,相比于单机显著缩短编译时间。

菜鸟能飞多高?~~~ 1919

STM32G474串口调试避坑指南:从CubeMX配置到中断收发,手把手教你搞定USART1

本文详细解析了STM32G474串口调试中的常见问题,从CubeMX配置到中断收发,提供USART1的避坑指南。涵盖时钟树同步、GPIO模式选择、中断接收逻辑、波特率偏差修正等关键点,帮助开发者高效解决串口通讯难题,提升嵌入式开发效率。

weixin_29191081的博客 210

第一章、isaacsim 及 isaaclab 安装教程

本专栏所有内容将根据上述资源地址展开,请结合食用~

m0_47719040的博客 4779

Ninja

Ninja是类似make的编译工具,make工具比较复杂,Ninja相比make更关注编译速度,小巧高效,LLVM、CMake、chrome使用Ninja编译。 安装 下载官网二进制 https://github.com/ninja-build/ninja/releases 源码编译 生成ninja可执行文件 git clone git://github.com/ninja-build/ninja.git && cd ninja ./configure.py --bootstrap

哈哈哈博客 845

SGM5860x高精度ADC驱动开发与SPI接口实战指南

本文详细介绍了SGM5860x高精度ADC芯片的驱动开发与SPI接口配置实战。内容涵盖芯片特性、SPI通信设置、寄存器映射、驱动初始化、数据采集处理、校准优化及调试技巧,帮助开发者快速掌握国产24位ADC的应用,提升工业测量项目的精度与稳定性。

vvv99的博客 717

Ninja Build System

Ninja是一种轻量级的构建系统,它的设计目的是加速编译过程。与传统的Makefile相比,Ninja能够更快速地生成可执行文件和其他目标文件。 ## 什么是Ninja? Ninja是一个构建工具,它将构建过程分解为一系列简单的任务,并以并行的方式运行这些任务以提高构建速度。Ninja的主要目标是提供一个高效的、易于使用的构建系统,适用于各种不同的编程语言和平台。 ## Ninja可以用来做...

gitblog_00069的博客 568

Claude Desktop新功能:让非技术人士也能自主编程

摘要: Anthropic近日在Claude桌面应用中集成了Claude Code功能,显著降低了非技术用户的使用门槛。Claude Code作为代理式编程工具,支持多任务并行处理、Git隔离和可视化会话管理,无需命令行操作即可实现代码调试、重构等复杂任务。新增的“计划模式”通过先分析后执行的流程,确保安全性,使产品经理、数据分析师等非开发者也能参与技术工作。这一更新标志着AI技术正打破专业壁垒,让领域专家无需编码背景即可利用高级工具,推动技术民主化。

独立开发,substack顶级编辑 1540

手把手教你学simulink实例--Simulink在电动汽车故障诊断与预测中的应用仿真

通过上述步骤,我们成功实现了基于Simulink的电动汽车故障诊断与预测仿真。该系统能够全面评估故障诊断与预测算法的性能,验证其在不同故障场景下的有效性,并通过优化设计提高系统的可靠性和安全性。引入智能算法:结合人工智能技术,实现更智能的故障诊断与预测。扩展功能:增加对多种车型和故障类型的支持,提升系统通用性。实验验证:将仿真模型应用于实际硬件,进行实验验证,评估其在实际工况下的表现。

MHD0815的博客 256

Ninja——小而快的构建系统

介绍 Ninja 是Google的一名程序员推出的注重速度的构建工具,一般在Unix/Linux上的程序通过make/makefile来构建编译,而Ninja通过将编译任务并行组织,大大提高了构建速度。 安装 目前最新版本是17年9月11日推出的v1.8.2,可以直接在github上下载其二进制文件,链接。 或者通过你所使用的系统的包管理器,比如apt、p...

若梦的博客 2万+

本地部署 OpenClaw:让 AI 真正“干活”的开源智能体,从核心概念到实战全流程

在大模型遍地开花的今天,我们早已习惯与 AI 聊天,但真正能**接管本地任务、自动化工作流**的“数字员工”却寥寥无几。OpenClaw 正是这样一款开源利器——它不仅是可本地运行的 AI 私人助理,更像一个“AI 操作系统内核”,能读写文件、执行终端命令、控制浏览器,所有数据本地存储,兼顾隐私与效率。而 Skills 作为它的标准化插件系统,更是让这份能力无限扩展。 本文将从核心概念拆解入手,再分系统给出**保姆级本地部署步骤**,包含环境准备、安装配置、技能安装与验证,甚至覆盖新手最易踩的坑,让你一次

ZhangJiqun&191cm&85kg 2500

Ninja 构建系统

Ninja 构建系统概述Ninja 是一个构建系统,与 Make 类似。作为输入,你需要描述将源文件处理为目标文件这一过程所需的命令。 Ninja 使用这些命令保持目标处于最新状态。与其它一些构建系统不同,Ninja 的主要设计目标是速度。 我在参与 Google Chrome 项目时编写了 Ninja。一开始,我将 Ninja 视作一个实验——看看能不能让 Chrome 构建的更快。为了成功地构

yujiawang的专栏 3万+

43、FMCW雷达高度计仿真

本文介绍了FMCW雷达高度计的波形级建模与仿真过程,重点模拟了着陆和倾斜两种飞行场景以评估其性能。通过结合高程数据和飞行轨迹构建雷达场景,使用自定义信号处理器分析IQ样本并估计高度。结果表明,该高度计在多数情况下满足性能要求,但也存在误差较大的点,提出了地面检测算法优化的潜在方向。

neovim7hacker的博客 135

MFC属性网格控件(CMFCPropertyGridCtrl)完全指南:构建专业属性编辑界面

本文详细介绍了MFC中的CMFCPropertyGridCtrl控件的使用方法。主要内容包括:控件基础用法(初始化、添加属性、事件处理)、高级设置(自定义外观、创建属性类型、动态更新)、派生类实现(自定义绘制、搜索过滤功能)、界面集成技巧(对话框布局、属性编辑器)以及实际应用示例。文章重点讲解了如何通过继承和自定义实现复杂功能,并提供了性能优化、多语言支持等最佳实践方案。该控件适用于需要大量参数配置的应用程序,能够创建类似Visual Studio属性窗口的专业界面。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 154

Android build子系统(01)Ninja构建系统解读

说明:本文将解读Ninja构建系统,这是当前Android Framework中广泛使用的构建工具。我们将从Ninja的起源和背景信息开始,逐步解读Ninja的优势和核心原理,并探讨其一般使用场景。然后介绍其在Android Framework中的应用及相关工具:kati、soong、gn等,最后介绍下如何自行构建一个Ninja编译系统,以便于对Ninja有一个完整的了解。

wangdsh的博客 2900

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

系统运维:Ninja 构建工具详解

尽管 Ninja 本身只关注执行部分的构建任务,但它也允许通过build语句来定义自定义的构建规则。这个规则会指定如何将编译为my_target。Ninja 是一个高效、快速的构建工具,特别适用于大规模项目和需要高度并行化的构建任务。它通过简单的构建描述文件和高效的增量构建机制,显著提高了构建速度,尤其在处理复杂的、依赖关系密集的项目时,具有明显的优势。尽管 Ninja 本身并不提供构建规则的编写能力,但它与 CMake 等工具的配合使用,使得它成为现代软件开发中不可或缺的构建工具之一。

十年运维开发经验的王义杰在此分享自己的知识和经验 2416

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【构建】Ninja构建系统初步认知

ninja

YZJincsdn的博客 1326

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Ninja 构建系统及其在 LLVM 中的应用分析

本报告深入分析了 Ninja 构建系统的设计理念、核心功能及其与传统构建系统(如 Make)的对比,并详细探讨了其在 LLVM 项目中的具体应用、优势、最佳实践以及可能遇到的挑战。

weixin_39145568的博客 1302

【cmake】关于cmake构建系统Ninja

p 选项表示“parents”,即递归地创建目录。如果上级目录不存在,mkdir -p 会自动创建所有必要的上级目录。如果 path 或 to 目录不存在,mkdir -p 会自动创建它们。

Michael 2292

Ninja构建系统初探

Ninja构建系统概述Ninja是一个专注于速度的小型构建系统。它与其他构建系统在两个主要方面有所不同:一是它被设计为由更高级别的构建系统生成.ninja文件作为其输入;二是它被设计为尽可...

码农孟宁的博客 1132

ninja介绍及使用

ninja介绍以及相关使用

MAX__YF的博客 1万+

【亲测免费】 Ninja 构建系统安装和配置指南

### 项目基础介绍 Ninja 是一个专注于速度的小型构建系统。它旨在替代传统的构建工具(如 Make),提供更快的构建速度和更简洁的构建脚本。Ninja 的设计目标是尽可能快地完成构建任务,适用于需要频繁构建的大型项目。 ### 主要编程语言 Ninja 主要使用 C++ 编写,同时也包含一些 Python 脚本用于配置和生成构建文件。 ## 2. 项目使用的关键技术和框架 ### 关键...

gitblog_09339的博客 1960

Ninja构建文件语法与规则系统详解

Ninja构建文件语法与规则系统详解 【免费下载链接】ninja 项目地址: https://gitcode.com/gh_mirrors/nin/ninja 本文深入解析...

gitblog_00687的博客 1142
上一篇: 【译】编译构建的确定性分析
下一篇: 【译】CMake 构建工具
流左沙
博客等级 码龄11年 46粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值