Documentation
Getting started
Open raw manual.mdThis page builds a minimal C++ hello world program with nobs. The point of the example is to show the basic project shape: source files describe the program, and nobs.txt describes what the target is made from.
1. Create a project
Create this directory structure:
hello-nobs
|-- nobs.txt
`-- src
`-- main.cpp
2. Add the source file
src/main.cpp:
#include <iostream>
int main()
{
std::cout << "Hello from nobs\n";
return 0;
}
3. Add nobs.txt
nobs.txt:
app:
{
CPP_FILES = P"(src/*.cpp)"
}
This declares one target named app. The target says that the program is built from every C++ source file under src/.
CPP_FILES is what makes a C++ compiler builder applicable. The P"(...) syntax creates a path value. It is resolved relative to the nobs.txt file and supports globbing, so src/*.cpp expands to the matching source files.
4. Configure toolchains once
If this is the first time you are running nobs on the machine, let it detect installed compilers:
nobs --find-compilers
This writes or updates the machine-local registry used for compiler selection. On Windows this registry is %APPDATA%\nobs\.nobs_registry.txt; on Unix-like systems it is ~/.config/nobs/.nobs_registry.txt. You normally only need to do this after installing nobs or after changing compiler installations.
5. Build
From the hello-nobs directory, run:
nobs app
nobs reads nobs.txt, creates the context for app, selects the best matching compiler toolchain from the registry, and builds the executable.
If app is the first target in the file, this is equivalent:
nobs
6. Add build settings
Targets are just contexts, so adding compiler inputs is a matter of adding variables:
app:
{
CPP_FILES = P"(src/*.cpp)"
C_DEFINES = ["UNICODE", "TRACE_LEVEL=1"]
}
C_DEFINES adds preprocessor definitions. CPP_FILES is resolved to the matching source files before the compiler is run.
Compiler flags are passed to the selected compiler as-is, so use flags that belong to that toolchain. _FLAGS variables should be lists, with one compiler option per list item, because each list item is passed as one command-line argument.
For MSVC:
app:
{
MSVC
CPP_FILES = P"(src/*.cpp)"
C_DEFINES = ["UNICODE", "TRACE_LEVEL=1"]
C_FLAGS += ["/std:c++latest"]
}
For GNU g++:
app:
{
GNU
CPP_FILES = P"(src/*.cpp)"
C_DEFINES = ["UNICODE", "TRACE_LEVEL=1"]
C_FLAGS += ["-std=c++20"]
}
The exact compiler path and resolved source path depend on your machine, but the command line has this shape:
cl.exe /std:c++latest "...\hello-nobs\src\main.cpp" /DUNICODE /DTRACE_LEVEL=1 /Fe"app.exe"- Tool
- selected from the registry because the target matches
MSVCandCPP_FILES C_FLAGS- copied directly as compiler arguments
CPP_FILES- expanded from
P"(src/*.cpp)"to resolved source file paths C_DEFINES- emitted as
/D...arguments - Target output
- named from the target when
OUTPUT_NAMEis not set
g++ -std=c++20 ".../hello-nobs/src/main.cpp" -DUNICODE -DTRACE_LEVEL=1 -o "app"- Tool
- selected from the registry because the target matches
GNUandCPP_FILES C_FLAGS- copied directly as compiler arguments
CPP_FILES- expanded from
P"(src/*.cpp)"to resolved source file paths C_DEFINES- emitted as
-D...arguments - Target output
- named from the target when
OUTPUT_NAMEis not set
What to remember
- A target describes what should be built.
- Variables such as
CPP_FILES,C_FILES,C_DEFINES, andC_FLAGSdescribe the target inputs and compiler arguments. - nobs chooses the builder by matching the target context against available tools.
- Run
nobs --find-compilersonce on a machine so normal builds can select a registered compiler. - Dependencies are added after the target name. Use
app: corefor a normal dependency, orapp: +corewhen the dependency output should be merged directly intoapp.