System Overview
Generator Architecture
generate.ts - Entry Point
The main generator file. Parses command-line arguments and controls project generation.
// Parse command-line arguments
const args = parseArgs(Deno.args, {
boolean: ["help", "with-git"],
string: ["name", "author", "version", "output"],
default: {
name: "MyApp",
author: "Your Name",
version: "1.0.0",
},
});
// Build project configuration
const config: ProjectConfig = {
name: projectName,
nameLower: toSnakeCase(projectName),
nameUpper: nameLower.toUpperCase(),
author: args.author,
version: args.version,
outputDir: args.output || projectName.toLowerCase(),
withGit: args["with-git"],
};
templates.ts - Template Generation
Functions that generate templates for each file. Dynamically generates content based on project configuration.
// Example: CMakeLists.txt generation
export function generateCMakeLists(config: ProjectConfig): string {
return `cmake_minimum_required(VERSION 3.15)
project(${config.name} VERSION ${config.version} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
...
`;
}
How Deno URL Execution Works
Deno can execute remote TypeScript directly with deno run <url>.
This allows users to use the generator without installing any tools.
Run with URL
deno run https://...generate.ts
Auto Download
Deno downloads script and dependencies
Local Execution
Generates project on local filesystem
Build System Architecture
build.ts - Build Script
Cross-platform build script using Deno and dax.
import $ from "jsr:@david/dax@0.42.0";
// CMake configuration
async function configure(): Promise<void> {
await $`mkdir -p build`;
await setupFileAPI("build");
await $`cmake -B build -DCMAKE_BUILD_TYPE=${args.config}`;
}
// Build execution
async function build(): Promise<BuildArtifact[]> {
await $`cmake --build build --config ${args.config}`;
const artifacts = await parseFileAPI("build");
return artifacts;
}
Features of dax
-
Cross-Platform
-
$`mkdir -p`works on Windows too - Template Literals - Safe variable interpolation
- Error Handling - Automatic exception throwing on command failure
- Pipes & Redirects - Shell-like operations possible
CMake File API Integration
Uses CMake File API v1 to programmatically retrieve build artifact information. This enables automatic detection of correct paths regardless of platform or generator, without relying on hardcoded paths.
How It Works
1. Create Query
Create empty file at build/.cmake/api/v1/query/codemodel-v2
2. Run CMake
CMake detects query during configuration and generates reply
3. Parse Reply
Parse JSON files in build/.cmake/api/v1/reply/
Reply Structure
// From cmake-types.ts
interface FileAPIIndex {
cmake: { version: {...} };
objects: Array<{ kind: string; jsonFile: string; }>;
reply: {
[key: string]: { kind: string; jsonFile: string; };
};
}
interface CodeModelV2 {
paths: { source: string; build: string; };
configurations: Array<{
name: string;
targets: Array<{ name: string; jsonFile: string; }>;
}>;
}
interface TargetInfo {
name: string;
type: "EXECUTABLE" | "STATIC_LIBRARY" | "SHARED_LIBRARY";
artifacts?: Array<{ path: string; }>;
}
Benefits
- Works with any generator: Visual Studio, Unix Makefiles, Ninja, etc.
- Automatically recognizes build types like Debug/Release
- Auto-detects all generated targets (executables, libraries)
C++ Project Structure
Target Configuration
Static Library: [project]_core
add_library(myapp_core STATIC
src/core/core.cpp
src/core/core.h
)
Static library for internal linking. Linked directly into binaries.
Shared Library: [project]_utils
add_library(myapp_utils SHARED
src/utils/utils.cpp
src/utils/utils.h
)
target_compile_definitions(myapp_utils
PRIVATE MYAPP_UTILS_EXPORTS)
Dynamic link library. Includes Windows DLL export macros.
Executable: [project]
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE
myapp_core
myapp_utils
)
Main application using both libraries.
Windows DLL Export
On Windows, shared library symbols must be properly exported/imported:
// utils.h
#ifdef _WIN32
#ifdef MYAPP_UTILS_EXPORTS
#define MYAPP_UTILS_API __declspec(dllexport)
#else
#define MYAPP_UTILS_API __declspec(dllimport)
#endif
#else
#define MYAPP_UTILS_API
#endif
MYAPP_UTILS_API void myFunction();
Dependencies
| Package | Version | Purpose |
|---|---|---|
| @david/dax | 0.42.0 | Cross-platform shell command execution |
| @std/cli | 1.0.6 | Command-line argument parsing |
| @std/path | 1.0.8 | Path manipulation |
| @std/fs | 1.0.8 | Filesystem operations |
All dependencies are fetched from JSR (JavaScript Registry). Deno automatically downloads and caches them at runtime.
Security Model
Deno is secure by default. The generator only requests minimum necessary permissions:
| Permission | Flag | Purpose |
|---|---|---|
| File Read | --allow-read |
Check existing directories |
| File Write | --allow-write |
Generate project files |
| Command Execution | --allow-run |
Run git init (optional) |
build.ts uses --allow-all.
This grants comprehensive permissions needed to run CMake and compilers.