<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Build-System on</title><link>/tags/build-system/</link><description>Recent content in Build-System on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 18 Aug 2025 15:25:00 +0000</lastBuildDate><atom:link href="/tags/build-system/index.xml" rel="self" type="application/rss+xml"/><item><title>Lesson 8: Reproducible Builds — Same source, same binary</title><link>/post/rust/rust-build-reproducible/</link><pubDate>Mon, 18 Aug 2025 15:25:00 +0000</pubDate><guid>/post/rust/rust-build-reproducible/</guid><description>&lt;p&gt;A security auditor once asked me to prove that the binary running in production was actually built from the source code we claimed. I confidently ran &lt;code&gt;cargo build --release&lt;/code&gt;, compared the hash of the output with the deployed binary, and&amp;hellip; they were different. Same source, same compiler, same machine, different binary. That&amp;rsquo;s when I learned that reproducible builds aren&amp;rsquo;t automatic — even in Rust.&lt;/p&gt;
&lt;h2 id="why-reproducible-builds-matter"&gt;Why Reproducible Builds Matter&lt;/h2&gt;
&lt;p&gt;A reproducible build means: given the same source code, same dependencies, same compiler, and same configuration, you get a bit-for-bit identical binary every time, on any machine.&lt;/p&gt;</description></item><item><title>Lesson 7: Linking Strategies — Static, dynamic, LTO</title><link>/post/rust/rust-build-linking/</link><pubDate>Fri, 15 Aug 2025 10:40:00 +0000</pubDate><guid>/post/rust/rust-build-linking/</guid><description>&lt;p&gt;I deployed a Rust service to a minimal Docker container once — Alpine Linux, nothing installed except the binary. It crashed immediately with &amp;ldquo;not a dynamic executable.&amp;rdquo; Turns out my binary was dynamically linked against glibc, but Alpine uses musl. I&amp;rsquo;d never thought about linking before that day. Now it&amp;rsquo;s one of the first things I configure on any new project.&lt;/p&gt;
&lt;h2 id="what-linking-actually-is"&gt;What Linking Actually Is&lt;/h2&gt;
&lt;p&gt;When you write &lt;code&gt;cargo build&lt;/code&gt;, the compiler doesn&amp;rsquo;t produce a binary directly. It produces object files — chunks of machine code for each compilation unit. The &lt;em&gt;linker&lt;/em&gt; takes all those object files, plus any libraries you depend on, and stitches them together into a single executable.&lt;/p&gt;</description></item><item><title>Lesson 6: Monorepo Management with Workspaces — Scaling Rust projects</title><link>/post/rust/rust-build-monorepo/</link><pubDate>Tue, 12 Aug 2025 13:10:00 +0000</pubDate><guid>/post/rust/rust-build-monorepo/</guid><description>&lt;p&gt;Our Rust project started as a single crate. Then we split the API handlers from the domain logic. Then we extracted shared types. Then someone added a CLI tool. Then a worker service. Before we knew it, we had nine crates and &lt;code&gt;cargo build&lt;/code&gt; was doing weird things because three of them depended on different versions of &lt;code&gt;serde&lt;/code&gt;. That&amp;rsquo;s when we sat down and properly set up a workspace.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve now managed Rust workspaces ranging from 5 crates to over 40. The patterns I&amp;rsquo;m going to share come from real mistakes — dependency hell, circular imports, CI builds that took 45 minutes, the works.&lt;/p&gt;</description></item><item><title>Lesson 5: Code Generation — proc macros, build.rs, xtask</title><link>/post/rust/rust-build-code-generation/</link><pubDate>Sun, 10 Aug 2025 08:55:00 +0000</pubDate><guid>/post/rust/rust-build-code-generation/</guid><description>&lt;p&gt;I once inherited a codebase where someone had written a Python script that generated 4,000 lines of Rust from a YAML spec. The script ran outside of Cargo, the generated file was checked into git, and nobody remembered to re-run it when the spec changed. By the time I found it, the generated code and the spec had diverged in twelve places. That experience shaped how I think about code generation in Rust — it needs to be integrated into the build, not bolted on the side.&lt;/p&gt;</description></item><item><title>Lesson 4: Custom Lints with clippy and dylint — Your team's rules</title><link>/post/rust/rust-build-custom-lints/</link><pubDate>Thu, 07 Aug 2025 16:20:00 +0000</pubDate><guid>/post/rust/rust-build-custom-lints/</guid><description>&lt;p&gt;We had this rule on my old team: never use &lt;code&gt;.unwrap()&lt;/code&gt; on database query results. We wrote it in our contributing guide. We mentioned it in code reviews. We added it to the onboarding doc. And yet, every single sprint, someone would push an &lt;code&gt;.unwrap()&lt;/code&gt; on a &lt;code&gt;sqlx::Result&lt;/code&gt; that would blow up in production at 2 AM. That&amp;rsquo;s when I decided to make the compiler enforce our rules instead of relying on humans to remember them.&lt;/p&gt;</description></item><item><title>Lesson 3: Conditional Compilation — cfg, features, target</title><link>/post/rust/rust-build-conditional/</link><pubDate>Tue, 05 Aug 2025 11:45:00 +0000</pubDate><guid>/post/rust/rust-build-conditional/</guid><description>&lt;p&gt;A few months back I was debugging a test failure that only happened on our Linux CI server, never on my Mac. Turns out someone had written platform-specific file path handling without proper &lt;code&gt;cfg&lt;/code&gt; guards — the code compiled fine on both platforms but silently did the wrong thing on Linux. That&amp;rsquo;s when I really internalized why conditional compilation needs to be treated as a first-class skill, not something you google when you need it.&lt;/p&gt;</description></item><item><title>Lesson 2: build.rs — Code generation at compile time</title><link>/post/rust/rust-build-build-scripts/</link><pubDate>Sun, 03 Aug 2025 14:30:00 +0000</pubDate><guid>/post/rust/rust-build-build-scripts/</guid><description>&lt;p&gt;The first time I needed &lt;code&gt;build.rs&lt;/code&gt;, I was wrapping a C library that had about 200 constants defined in a header file. I could&amp;rsquo;ve copied them all by hand into Rust &lt;code&gt;const&lt;/code&gt; declarations. Instead, I wrote a build script that parsed the header and generated the constants automatically. Took 30 minutes to write the build script, and it saved me from maintaining a manual mapping that would&amp;rsquo;ve drifted out of sync within a month.&lt;/p&gt;</description></item><item><title>Lesson 1: Cargo Deep Dive — Workspaces, features, profiles</title><link>/post/rust/rust-build-cargo-deep-dive/</link><pubDate>Fri, 01 Aug 2025 09:15:00 +0000</pubDate><guid>/post/rust/rust-build-cargo-deep-dive/</guid><description>&lt;p&gt;I&amp;rsquo;d been writing Rust for about a year before I realized I was only using maybe 20% of what Cargo actually offers. &lt;code&gt;cargo build&lt;/code&gt;, &lt;code&gt;cargo run&lt;/code&gt;, &lt;code&gt;cargo test&lt;/code&gt; — that was my entire workflow. Then I joined a team managing a Rust monorepo with 30+ crates, custom build profiles, and feature flags controlling everything from database backends to telemetry. Suddenly my surface-level Cargo knowledge wasn&amp;rsquo;t cutting it.&lt;/p&gt;
&lt;h2 id="cargo-is-not-just-a-build-tool"&gt;Cargo Is Not Just a Build Tool&lt;/h2&gt;
&lt;p&gt;Most people coming from other languages think of Cargo as &amp;ldquo;npm for Rust&amp;rdquo; or &amp;ldquo;Maven for Rust.&amp;rdquo; That undersells it massively. Cargo is a build system, package manager, test runner, benchmark runner, documentation generator, and project convention enforcer — all rolled into one binary. And unlike most build tools, it&amp;rsquo;s actually pleasant to use.&lt;/p&gt;</description></item></channel></rss>