Xmake Templates
A template is a directory tree with an xmake.lua and some starter source files. xmake create copies it into a new project directory, substituting a few placeholders. Templates come from three places, searched in this order:
- xmake-repo templates — third-party, under any registered global repo (
xmake repo --list), e.g.packages/templatesfromxmake-repo. - User-global templates —
~/.xmake/templates/. - Built-in templates — shipped with xmake under
$(programdir)/repository/templates/.
1. Listing templates
xmake create --list # all languages, all sources
xmake create --list -l c++ # only C++ templates
Output groups templates by source (repo / global / builtin) and by language, so you can see which names are available for -t.
2. Creating a project from a template
xmake create hello # default: c++ console
xmake create -l c hello # C, default "console" template
xmake create -l c++ -t console myapp
xmake create -l c++ -t static mylib
xmake create -l c++ -t shared mydyn
xmake create -l c -t module mymod
xmake create -l rust hello
xmake create -l go -t console hello
Flags:
-l, --language— language (c,c++,rust,go,swift,objc,cuda,dlang,fortran,kotlin,nim,pascal,vala,zig,csharp).-t, --template— template id inside that language.-P <dir>— create into a specific directory instead of the current one.- The positional arg is the target name (defaults to the directory basename or
demo).
Third-party templates from xmake-repo
Qt, SDL, Python bindings, Linux drivers, raylib, verilator, wxWidgets, etc. are shipped in xmake-repo/templates/. They live under nested template ids using . as separator:
xmake create -l c++ -t qt.widgetapp myqtapp
xmake create -l c++ -t qt.quickapp myquick
xmake create -l c++ -t wxwidgets mywx
xmake create -l c++ -t python.pybind11 mybind
xmake create -l c -t sdl mysdl
xmake create -l c -t raylib mygame
xmake create -l c -t linux.driver mydriver
qt.widgetapp resolves to <repo>/templates/c++/qt/widgetapp/. Each path segment between dots is a directory level.
Targeting a specific directory
xmake create -P myproj -l c++ -t console hello
cd myproj && xmake
3. What a template actually is
A template is just:
<root>/<language>/<template-id-path>/
├── xmake.lua # with ${TARGET_NAME} / ${FAQ} placeholders
└── src/
└── main.cpp # or whatever source files the template needs
When you run xmake create, xmake copies the entire directory tree to the destination and substitutes placeholders in both filenames and file contents.
Built-in placeholders
Verified from xmake/actions/create/template.lua:
| Placeholder | Value |
|---|---|
${TARGET_NAME} |
The positional project/target name passed to xmake create |
${FAQ} |
Contents of $(programdir)/scripts/faq.lua — a short FAQ block appended to the generated xmake.lua |
Example built-in c/console/xmake.lua:
add_rules("mode.debug", "mode.release")
target("${TARGET_NAME}")
set_kind("binary")
add_files("src/*.c")
${FAQ}
After xmake create -l c hello, the emitted xmake.lua has target("hello") and the FAQ block inlined.
4. Authoring a custom template
Step 1 — pick a location
Either of these is picked up automatically; no registration step needed:
- User-global —
~/.xmake/templates/<language>/<template-id>/— personal, visible on your machine only. - Inside an xmake-repo clone —
<repo>/templates/<language>/<template-id>/— distributable to anyone who adds your repo.
Template IDs can be nested: ~/.xmake/templates/c++/game/sdl2/ → -t game.sdl2.
Step 2 — create the tree
~/.xmake/templates/c++/game/sdl2/
├── xmake.lua
├── src/
│ └── main.cpp
└── assets/
└── .gitkeep
Template xmake.lua:
add_rules("mode.debug", "mode.release")
set_languages("c++17")
add_requires("libsdl2")
target("${TARGET_NAME}")
set_kind("binary")
add_files("src/*.cpp")
add_packages("libsdl2")
${FAQ}
Template src/main.cpp:
#include <SDL2/SDL.h>
int main(int, char**) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Quit();
return 0;
}
Step 3 — verify
xmake create --list -l c++ # your template should appear under "c++/game.sdl2"
xmake create -l c++ -t game.sdl2 myshooter
cd myshooter
xmake
Placeholder substitution scope
- Applies to file contents of every copied file.
- Applies to filenames as well — a file named
${TARGET_NAME}.hbecomesmyshooter.h. - Only the two placeholders above are substituted. Do not invent new
${...}— they will be left as literal text in the output.
Multi-target / multi-file templates
Nothing special — just drop more files into the template tree. Globs in the template xmake.lua (add_files("src/*.cpp")) will pick up whatever the user adds later, so keep file lists glob-based rather than enumerated.
5. Distributing a template via xmake-repo
If you want other people to use your template:
- Fork
xmake-repo. - Drop your template under
templates/<language>/<id...>/. - Submit a PR.
Or, for a private template library, host your own repo:
xrepo add-repo my-templates https://github.com/me/my-xmake-templates
Once the repo is registered globally, its templates/ directory is picked up by xmake create --list and usable via -t.
6. Common pitfalls
- Template id path separators. Use
.on the CLI (-t qt.widgetapp) — not/. xmake splits on.to walk the template tree. --listdoesn't show my template. Either the directory is not at<root>/<language>/<id>/, or there is noxmake.luain it.templatedir()requires both.- Placeholder not substituted. Only
${TARGET_NAME}and${FAQ}are real. Anything else you write with${...}is left verbatim. - Wrong language flag.
-lmust exactly match the directory name undertemplates/.c++notcpp;objc++notobjcxx. - Path traversal protection.
xmake createrejects.,..,/,\,:, or NUL in template ids and language names. Keep template ids to plain identifiers separated by dots. - Using
xmake createfor scaffolding an existing project. It creates files in an otherwise empty directory; running it inside a populated directory will error out if files would be overwritten. Use a fresh directory or-P <new-dir>.
When to branch out
- Basic
xmake createflow as part of "getting started" →xmake-basics - Adding packages the template depends on →
xmake-packages - Writing the
xmake.luabody that ends up in the template →xmake-targets,xmake-rules