ProgrammingPro #93: CMake for Dependency Management, Faster TypeScript, AI Agent Tools, and Rust-Powered NVIDIA Driver
One Tool to Link Them All: Tom Hulton-Harrop Breaks Down CMake for Modern Devs, Plus the Latest in AI Agents, Rust Drivers, and TypeScript Speed
Welcome to a brand new issue of ProgrammingPro.
In today’s special edition of Expert Insight, we bring you an original article, "CMake, the one tool you’ll need for dependency management", written by Tom Hulton-Harrop, the author of Minimal CMake. The article discusses CMake's key features for dependency management focusing on FetchContent, ExternalProject, and Generators.
News Highlights: TypeScript transitions to a Go-based compiler for a 10x speed increase; OpenAI launches Responses API and Agents SDK to facilitate complex AI agent development; NVIDIA releases a new Rust-written "NOVA" driver for RTX 20 GPUs; and Veracode's report reveals greater security risks in third-party libraries compared to first-party code.
My top 5 picks from today’s learning resources:
Building Modern Web Applications Using Blazor ASP.NET Core🛠️
How to Implement a Cosine Similarity Function in TypeScript for Vector Comparison🔢
But there’s more, so dive right in.
Stay Awesome!
Divya Anne Selvaraj
Editor-in-Chief
On-Demand Webinar—Your Salesforce Data, Your Responsibility
🗞️News and Analysis🔎
A 10x Faster TypeScript: The language is transitioning to a native compiler port written in Go, targeting a 10x boost in performance for large codebases, with significant reductions in memory usage and editor startup times.
OpenAI reveals Responses API, Agents SDK for building agentic experiences: The tools are meant to enhance developers' ability to create AI agents for complex tasks across industries, with features like multi-tool integration and multi-agent workflow orchestration.
The New Rust-Written NVIDIA "NOVA" Driver Submitted Ahead Of Linux 6.15: Targeting NVIDIA RTX 20 "Turing" GPUs and newer, NOVA leverages the NVIDIA GSP for firmware support, simplifying the driver development process.
Third-party libraries cause more security woes than first-party code, open-source flaws take longer to fix: A new report by Veracode reveals that 70% of applications contain flaws in third-party components compared to 64% in proprietary code.
DeepSeek is unsafe for enterprise use, tests reveal: Significant security vulnerabilities, such as susceptibility to jailbreaking, prompt injection, and the ease of malware creation render it unsafe for enterprise use, have been revealed.
Fortran, Delphi rise in Tiobe popularity index: Older programming languages are experiencing a resurgence, as shown in the latest Tiobe index, where they're competing for top 10 spots due to their critical roles in maintaining legacy systems.
New Programming Language Vine Based on Interaction Nets: The language is designed for parallel and distributed computing, integrates functional and imperative patterns, and compiles to Ivy on the Interaction Virtual Machine.
🎓Tutorials and Learning Resources💡
Legend:🎓 Tutorial/Course | 💼 Case Study | 💡 Insight/Analysis
Python
💡Guarantee a Locked & Reproducible Environment with Every Python Run: Introduces Fetter, a command-line tool designed to enforce locked and reproducible Python environments by validating dependencies before every Python execution.
🎓Airgapped Python: Setting up Python without a net(work): Covers downloading the appropriate Python installers and package files on a networked computer and transferring and installing them on the offline system.
For more Python resources, go to PythonPro
C# and .NET
🎓TypeScript is Like C#: Outgrowing Node.js?: Addresses common myths and misconceptions about C#, presenting it as a robust alternative for backend development with a strong type system and efficient runtime.
🎓Writing a .NET Garbage Collector in C# - Part 5: Explains the GCDesc structure, which stores information about object references for garbage collection and details how GCDesc encodes reference ranges in memory.
🎓Building Modern Web Applications Using Blazor ASP.NET Core: Provides a comprehensive guide to building modern web applications using Blazor ASP.NET Core, highlighting its benefits for creating interactive applications with C# and .NET.
C++ and C
🎓Compiling C++ with the Clang API: Explains how to compile a C++ source file into an object file using the Clang API, simulating a basic version of the Clang executable.
💡Understanding Memory Management, Part 3: C++ Smart Pointers: Covers how C++ smart pointers simplify memory management, prevent memory leaks, and facilitate cleaner and safer code by automating resource cleanup and ownership strategies.
💡Writing a C Compiler in Clojure: Offers practical strategies for managing program symbols and types, as well as insights into generating assembly code that adheres to calling conventions.
Java
💡Porting LangGraph to Java in one weekend? (with Claude Code): Describes the author's ambitious weekend project of porting the LangGraph framework from Python to Java using Claude Code, an LLM tool.
💡Java is the New Python: Discusses how Java is evolving through Projects Panama, Valhalla, and Babylon to simplify interfacing with other programming languages and potentially positioning it as an alternative to Python.
💡New build tool in Java!: Critiques existing Java build tools and introduces the author's own, aimed at simplifying the development process by enhancing dependency management and integration with Java’s built-in tools.
JavaScript and TypeScript
💡JavaScript best practice: use return await: Demonstrates the importance of using
return await
in JavaScript to ensure proper error handling withintry..catch
blocks and to manage resource cleanup intry..finally
constructs effectively.💡Let’s Be Serious About Node Dependency Injection.: Promotes the adoption of Object-Oriented Programming and proper dependency injection in Node applications using TypeScript, outlining the benefits of a structured approach.
🎓How to Implement a Cosine Similarity Function in TypeScript for Vector Comparison: Explains how to implement a cosine similarity function in TypeScript for comparing vectors, which is essential in AI to understand relationships like "cat" to "kitten."
Go
💡Slow, flaky, and failing: Discusses strategies for addressing perpetually failing tests by adopting a zero-defects methodology and suggests practical measures to speed up slow test suites.
💡An overview of parallel programming (Go edition): Introduces goroutines, a lightweight alternative to threads, and discusses data races, synchronization tools, and performance considerations.
Rust
💼Training a Rust 1.5B Coder LM with Reinforcement Learning with Group Relative Policy Optimization (GRPO): Discusses the application of the GRPO algorithm in training a small Language Model (LM) for Rust programming.
💡Rust trait object layout: Clarifies the distinction between values and references, particularly with dynamically sized types which can't be directly stored due to their unknown size at compile time, but can be referred to by pointers.
Swift
🎓Picker in SwiftUI explained with code examples: Explains how to implement and customize SwiftUI's Picker and ColorPicker controls, providing code examples and discussing various styles to enhance user interaction in applications.
🎓Loops in Swift: Explains for, while, and repeat-while loops, focusing on their uses through practical code examples. Also covers loop control statements like break and continue for loop execution control.
PHP
🎓Mastering SAML Implementation in PHP (Revised): Covers the benefits, recent advancements, and best practices in SAML implementation, including integration tips for frameworks and tools like Okta, and enhanced security features.
SQL
💡Life Altering Postgresql Patterns: Shares impactful PostgreSQL practices that have significantly improved operational efficiency, such as using UUIDs for primary keys, automated timestamping, and restrictive foreign key actions.
💼Writing a Rust SQL Parser in One Week: Details the development of an in-house SQL parser by the LakeSail Team, written in Rust for their Sail framework, a replacement for Apache Spark.
Ruby
🎓Caching Strategies for Ultra-High Performance in Ruby on Rails, Part 1: Explains various caching methods like page caching, action caching, fragment caching, and Russian Doll caching.
Kotlin
🎓Learn Kotlin by Example: Designed to help newcomers familiarize themselves with the language through interactive examples.
🧠Expert Insight: CMake, the one tool you’ll need for dependency management📚
Three key CMake features for seamless dependency management.
By Tom Hulton-Harrop, author of Minimal CMake
CMake can be a tricky technology to explain, because on its own, it isn’t particularly useful. That isn’t really a problem though, because the entire point of CMake, is to connect bits of software together, be that source files on your computer, or libraries from other developers on the internet. CMake is the glue that binds these individual software components together. However, describing CMake as just glue, might actually be doing it a disservice. Making a project compatible with CMake is a bit more like attaching a universal adapter to your code to make connecting it with other software (be that as a library or application) possible, and relatively straightforward too.
In this article, we’ll learn about three key CMake features that make CMake an excellent choice for adding to your development tools. We will explore these using a simple application which simulates Conway’s Game of Life. The project is a desktop, windowed application that is fully cross platform, spanning Windows, macOS and Linux (thanks to the help of the excellent SDL 3.0 library). The complete code for the game-of-life-sdl3 project is available on GitHub. The project is an evolution of the application accompanying my book, Minimal CMake, upgraded from SDL2 to SDL3, with improved input handling and some other small changes.
We’ll only be focussing on the CMakeLists.txt files at the root of the repository and in the third-party folder (see <root>/CMakeLists.txt and <root>/third-party/CMakeLists.txt). Now let’s look at the three features CMake provides which make building software fast and simple:
FetchContent: The first standout feature CMake offers is the FetchContent module. This is a relatively new addition to CMake but is transformational when it comes to quickly composing software together. The key part to focus on here, is the FetchContent_Declare command in the root CMakeLists.txt file:
FetchContent_Declare( as GIT_REPOSITORY https://github.com/pr0g/as.git GIT_TAG a47a6deb8b5dbe408137aa4ce5cd556d26dc77c6)FetchContent_MakeAvailable(as)
What the snippet above does is inform CMake to download and build this dependency automatically for us as part of our project. There are a wide array of different options for this, but the most common is just specifying a Git repository and a commit (or tag). All that’s then needed is to add the as dependency to our target_link_libraries command and that library will be available for use (this does rely on as itself being CMake compatible, the details of which are covered in “Chapter 3: Using FetchContent with External Dependencies” in Minimal CMake):
target_link_libraries(
${PROJECT_NAME} PRIVATE as ...)
ExternalProject: This module is closely related to FetchContent but works slightly differently. Instead of building a dependency as part of our project, ExternalProject_Add is used to build dependencies separately, and these dependencies are then referenced using the find_package If you review the CMakeLists.txt file in the third-party folder, you’ll see a string of dependencies listed using ExternalProject_Add:
ExternalProject_Add( SDL3 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git GIT_TAG release-3.2.4 GIT_SHALLOW TRUE PREFIX ${PREFIX_DIR}/SDL3 BINARY_DIR ${PREFIX_DIR}/SDL3/build/${build_type_dir} INSTALL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/install CMAKE_ARGS ${build_type_arg} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>)
ExternalProject_Add is incredibly useful for building larger dependencies that we may only want to build once, and then rely on for multiple projects. Having the build artifacts of these third-party dependencies kept separate can also be very convenient when wanting to delete and regenerate our own project’s build files, without then having to rebuild all of our third-party dependencies over again.
In the Game of Life project, to make working with ExternalProject_Add even easier, we’ve employed what’s often referred to as a super build. A super build is a way to combine the benefits of ExternalProject_Add with FetchContent, to allow us to build our project and all dependencies with one command (cmake --build <build-folder>). See the bottom of the CMakeLists.txt file in the third-party folder for how this is configured:
if(SUPERBUILD AND NOT PROJECT_IS_TOP_LEVEL) set(THIRD_PARTY_BINARY_DIR "${CMAKE_SOURCE_DIR}/build-third-party" CACHE STRING "Third-party build folder") if(NOT IS_ABSOLUTE ${THIRD_PARTY_BINARY_DIR}) set(THIRD_PARTY_BINARY_DIR "${CMAKE_SOURCE_DIR}/${THIRD_PARTY_BINARY_DIR}") endif() set(PREFIX_DIR ${THIRD_PARTY_BINARY_DIR})else() set(PREFIX_DIR ${CMAKE_CURRENT_BINARY_DIR})endif()
And the top of the root CMakeLists.txt file for where we check if a super build is enabled or not:
option(SUPERBUILD "Perform a superbuild (or not)" OFF)if(SUPERBUILD) add_subdirectory(third-party) return()endif()
The great thing is, we can easily disable the super build if we don’t want to use it or switch back and forward whenever is convenient. Providing this option is great for users to make building your project a more straightforward and less painful experience. The super build technique mentioned above is covered in more detail in “Chapter 8: Using Super Builds to Simplify Onboarding” in Minimal CMake.
Generators: This feature allows us to do something incredible: we can generate build files for Visual Studio if we’re on Windows, Xcode if we’re on Mac, or Make if we’re on Linux. There’s also an excellent cross platform build system and supported generator called Ninja which works across all three. This flexibility is incredibly useful as it doesn’t constrain what development environment a contributor or team member would like to use; they just pick the generator they prefer.
To take advantage of this feature, when first configuring a project (before we actually build anything), we must specify what’s called a generator (using -G, or the system default), and use that to build our project (this is because CMake is technically a ‘build system generator’, and not a ‘build system’ itself; this distinction makes CMake very flexible). Below is an example showing how to specify various generators:
cmake -B build # use system default generatorcmake -B build -G “Ninja” # use Ninja generator
cmake -B build -G “Visual Studio 17 2022” # use Visual Studio generator
And then to build, we simply run cmake –build build, no matter which generator we picked.
We’ve only scratched the surface of what’s possible with CMake, the ease with which you can integrate dependencies once you have a basic understanding of CMake cannot be overstated, and being able to build libraries others can use just as easily is incredibly satisfying. Do have a play around with the accompanying project, and if I’ve piqued your interest and you’d like to learn more, do give Minimal CMake a look. It’s packed full of practical examples, and explains all of this in much more detail, giving you everything you need to know to start building your own libraries and applications using CMake.
Author Bio: Tom Hulton-Harrop is a software developer with over 10 years of experience in game and engine development. Tom started his career in 2011 at Electronic Arts working on the Need for Speed series of racing games. In 2014, he joined Fireproof Games where he worked on The Room Three and later joined Amazon as part of the Lumberyard Game Engine team (later becoming Open 3D Engine). During this time, Tom became interested in open source development and started sharing multiple hobby projects on GitHub.
It was this experience that led Tom to CMake, where he slowly came to appreciate the power and simplicity of the tool. Tom now works at a start-up called Amutri, helping deliver 3D experiences to engineering, manufacturing, and lighting customers.
His book Minimal CMake, was published by Packt in January 2025.
🌟Advanced Concepts🚀
Automated architecture diagrams: Addresses the challenge of maintaining up-to-date architecture diagrams by implementing an automated system that integrates an extended enterprise architecture framework with interactive, reusable diagrams.
Writing terrible code: Argues that writing incorrect functions deliberately can be a powerful way to validate and enhance test effectiveness, ensuring they genuinely verify the correctness of the code.
How fast can you open 1000 files?: Compares performance between macOS and Linux using different threading models, revealing that macOS experiences slower file-opening speeds despite having superior hardware.
🛠️Useful Tools⚒️
iMCP: An open source macOS application that connects AI with users' digital lives by interfacing with Claude Desktop and other clients.
ruby_llm: A Ruby library that simplifies AI integration, offering a unified API for services like chat, image analysis, and PDF analysis.
That’s all for today.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most useful here.
If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want to advertise with us.
If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, leave a comment below!