Alien-Xmake
view release on metacpan or search on metacpan
$xmake->create('hello', template => 'console');
$xmake->create('libz', template => 'shared', language => 'c');
```
Generates a new project directory named `$name` (clone of `xmake create`).
- **language**
Project language (`c`, `c++`, `go`, `rust`, ...).
- **template**
Project template (`console`, `static`, `shared`, `qt.widgetapp`, ...).
- **force**
Overwrite an existing directory (`-f`).
- **list**
List all available templates instead of creating (`--list`).
- **project**
Alternate project path (`-P`).
## `configure( %options )`
```perl
$xmake->configure(mode => 'debug', plat => 'windows', arch => 'x64');
```
Configures the current project (clone of `xmake config`). Accepts the shared platform/toolchain options (`plat`,
`arch`, `mode`, `kind`, `toolchain`, `toolchain_host`, `cross`, `target_os`, `sdk`, `runtimes`, `vs`,
`vs_toolset`, `vs_sdkver`, `vs_runtime`, `ndk`, `ndk_stdcxx`, `ndk_sdkver`, `android_sdk`, `mingw`, `emsdk`,
`cuda`, `qt`, `qt_host`, `vcpkg`, `wdk`, `build_toolver`, `ccache`, `ccachedir`, `debugger`, `trybuild`,
`tryconfigs`, `require`, `includedirs`, `linkdirs`, `links`, `syslinks`, `rc*`, `fc*`, ...) as well as the
compiler/flag subtables `cflags`, `cxflags`, `cxxflags`, `mflags`, `mmflags`, `mxflags`, `ldflags`, `arflags`,
`asflags`, `shflags`, and `cuflags`. Any `--key=value` pair can be passed via `set => { key => value }`.
- **clean**
Reset the configuration to defaults (`-c`).
- **check**
Only check the configuration and exit (`--check`).
- **menu**
Open the interactive configuration menu (`--menu`).
- **export**, **import**
Export/import configuration files.
- **builddir**
Alternate build directory (`-o`).
## `global( %options )`
```perl
$xmake->global(network => 'y', theme => 'default');
$xmake->global(vs => '2022');
```
Reads/writes global (user-level) configuration. Shares the platform/toolchain options from `configure( ... )` that
exist on `global` (`android_sdk`, `build_toolver`, `cuda`, `emsdk`, `mingw`, `ndk`, `ndk_sdkver`, `qt`,
`qt_host`, `vcpkg`, `vs`, `wdk`).
- **clean**
Reset global configuration to defaults (`-c`).
- **check**, **menu**
Same semantics as `configure( ... )`.
- **theme**, **debugger**, **ccache**
Global UI/terminal settings.
- **cachedir**
Global cache directory.
- **policies**
Global policy overrides (`--policies=`).
- **network**, **proxy**, **proxy\_hosts**, **proxy\_pac**
Network settings, e.g. `network => 'n'` to go offline, `insecure_ssl => 1` to skip HTTPS verification.
- **pkg\_searchdirs**, **pkg\_cachedir**, **pkg\_installdir**
Global package search/cache/install directories.
## `install( [$target], %options )`
```perl
$xmake->install;
$xmake->install('hello', installdir => './dist');
```
Installs the built binaries to a staging directory (`DESTDIR`).
- **installdir**
The install directory (`-o`); `bindir`, `libdir`, `includedir` adjust the per-kind subdirectories.
- **all**
Install all targets (`-a`).
- **group**
Install all targets in the group (`-g`).
- **binaries**, **headers**, **libraries**, **packages**
Set to `y` or `n` to enable or disable installing that kind of file.
## `uninstall( [$target], %options )`
```
$xmake->uninstall;
$xmake->uninstall('hello');
```
Uninstalls installed binaries from the install directory. Supports `installdir`, `bindir`, `libdir`, `includedir`,
`group` and `admin`.
## `lua( [$script], %options )`
```perl
my @scripts = $xmake->lua( list => 1 );
$xmake->lua('print(os.host())'); # inline code -> "windows"
$xmake->lua('./myscript.lua'); # or a script file on disk
```
Runs a `xmake` Lua script. Pass inline Lua code, or the path to a `.lua` file on disk. Inline code is written to a
temporary script file and executed, which sidesteps the MSWin32 argv-mangling and STDIN-piping problems that break
passing code as a command-line argument. `list` lists the built-in scripts (captured) and `deserialize` records the
output in the given format. `command` and `stdin` are accepted and treated as inline code.
## `lua_json( [$code], %options )`
```perl
my $host = $xmake->lua_json('os.host()', return => 1); # "windows"
my $info = $xmake->lua_json(q{import("core.base.json"); print(json.encode({arch=os.arch()}))});
```
Runs inline Lua and returns the decoded JSON it produced. In the simplest form the code prints one JSON value itself
via `import`ing `core.base.json` and passing `print(json.encode(...))`. With `return => 1` just give the value,
e.g. a string, a number, a table (`{1,2,3}`), or a nested structure (`{name='z', libs={'z','m'}}`), and the wrapper
prints the encoded JSON for you.
xmake's `lua` runner appends a stray `{ }` chunk even on success, so the wrapper locates and decodes the emitted JSON
value and returns an empty list if none is found. `lua_json` is the general escape hatch when a specific method (like
`target_info`) does not yet exist for a structured query.
## `macro( [$name], %options )`
```perl
$xmake->macro('mybuild', begin => 1); # begin recording
$xmake->macro('mybuild', end => 1); # and stop
my $list = $xmake->macro( list => 1 );
```
Records and replays the shell commands that follow (clone of `xmake macro`). `begin`/`end` control recording,
`show` prints a recorded macro, `list` lists them (captured), `delete`/`clear` remove them and `export`/`import`
move them between machines.
## `project( %options )`
```perl
$xmake->project( kind => 'vsxmake' );
$xmake->project( kind => 'make', targets => ['hello'] );
```
Generates IDE/third-party project files (`vs`, `vsxmake`, `make`, `cmake`, `compile_commands`, ...). `kind`
selects the generator, `modes`/`archs` restrict the configs to generate, `target` generates only for that target and
`lsp` writes LSP-friendly output (`compile_flags.txt` or `compile_commands.json`).
## `repo( [$name], %options )`
```perl
my $repos = $xmake->repo( list => 1 );
$xmake->repo('local_extra', add => 1, url => 'git@github.com:me/xmake-repo.git');
```
Manages custom package repositories. `add`, `remove`, `update`, `clear` and `list` select the operation (`list`
returns captured output); `global` restricts the change to the global config; `url` and `branch` are used when
adding.
## `show( [$list], %options )`
```perl
my @platforms = $xmake->show('platforms');
my @targets = $xmake->show('targets', format => 'json');
my $plain = $xmake->show('targets', target => 'hello');
```
Shows information about the current project or the `xmake` installation.
- **$list**
List name: `platforms`, `architectures`, `toolchains`, `buildmodes`, `targets`, `packages`, `rules`, `themes`,
`envs`, `apis` or `policies`. When given, the value(s) are returned as a list (whitespace-split; the raw lines if a
single value) and ANSI color codes are stripped.
- **format**
Output format. `json` returns the decoded data structure, `dot` renders dependency graphs. Only meaningful with
`info => 'depgraph'` or a listing.
- **target**
Restrict output to a specific target (`--target=`).
- **info**
What to show (`depgraph`, ...). Combine with `format`.
- **group**
Filter targets by group.
- **pretty**
`--format=json` output (and the other formats) is already decoded/structured; `pretty` only adds pretty-printed
formatting to the raw listing output.
## `target_info( $name, %options )`
```perl
my $t = $xmake->target_info('hello'); # decoded HASH
say $t->{targetfile}; # build\windows\x64\release\hello.exe
```
Shows the rich, per-target detail that `xmake show -t <target>` produces: `name`, `kind`, `files`,
`compilers`, `linker`, `rules`, `at` and `targetfile`.
Returns the decoded JSON structure (a HASH) by default. Pass `plain => 1` (or `format => 'plain'`) to get the
human-readable output instead. `group` filters by target group. An empty list is returned if the target does not
exist.
## `watch( %options )`
```perl
$xmake->watch( commands => 'xmake build' );
$xmake->watch( script => 'my_script.lua' );
```
The following examples drive xmake from Perl. These all call the wrapper methods (see ["METHODS"](#methods)), so output is
streamed to your terminal and each returns truthy on success.
## Scaffold, configure, build, test and run a target
The whole edit-run-debug lifecycle. `create` scaffolds a fresh project (`template` picks the base), `configure` sets
the build mode, then `build`/`test`/`run` compile, run the tests (if any) and launch the binary:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
$x->create('demo', template => 'console'); # writes xmake.lua + src/main.cpp
chdir 'demo';
$x->configure(mode => 'release'); # configure the build
$x->build; # compile it
$x->test; # run target tests (none for a console template)
$x->run; # execute the binary
```
## Generate files for another build system or IDE
`project` reads your `xmake.lua` and emits other build systems' project files, so you never maintain a second build
config by hand. `kind` selects the generator and `lsp` asks for IDE-friendly compile data:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
$x->project(kind => 'make'); # a Makefile
$x->project(kind => 'compile_commands', lsp => 1); # compile_commands.json for clangd/IDEs
```
## Ask xmake what it can target
`show` introspects the `xmake` install and the current project. Hand it a list name and (optionally) `format =>
'json'` to get the parsed result; the ["METHODS"](#methods) list names are `platforms`, `architectures`, `toolchains`,
`buildmodes`, `targets`, `packages`, `rules`, `themes`, `envs`, `apis` and `policies`. `config` reflects the
metadata of this [Alien::Xmake](https://metacpan.org/pod/Alien%3A%3AXmake) install itself (set up at construction; see `new` under ["METHODS"](#methods)):
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
say for $x->show('platforms'); # windows, linux, macosx, android, ...
say for $x->show('architectures');
my @targets = $x->show('targets', format => 'json'); # inside a project dir
say $targets[0]->{name};
say 'installed: ' . $x->config('install_type'); # share | system
say 'version : ' . $x->config('version');
```
The list queries also work from a bare `show` (no project needed) for the global catalogs. Several return rich JSON:
the `apis` value is a big HASH of the built-in module APIs, while `buildmodes`, `platforms`, `rules`, `themes` and
`targets` come back as ARRAY refs. `architectures`, `envs`, `policies` and `toolchains` still print aligned table
text (xmake does not JSON-serialize them), so those come back as a plain listing:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
my $apis = $x->show( 'apis', format => 'json' ); # HASH of built-in module APIs
say for @{ $apis->{description_builtin_module_apis} }; # hash.md5, hash.uuid, ...
my $platforms = $x->show( 'platforms', format => 'json' ); # ['windows', 'linux', ...]
say for @$platforms;
my $env = $x->show( undef, format => 'json' ); # environment object
say $env->{xmake}{version}; # xmake's own version string
```
## Lint the project from Perl
`check` runs xmake's **analysis** checkers - `syntax` validates the source compiles without linking and `clang.tidy`
drives clang-tidy. It is a linter, not a compiler probe; `'c'` and `'cxx'` are not checkers. `list => 1` returns
the available checker names:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
my @checkers = $x->check('', list => 1); # api.*, clang.tidy, cuda.devlink, syntax ...
$x->check('syntax'); # "syntax check ok" if the sources parse
```
## Fetch pkg-config style flags for a dependency
`pkg_config` installs a package via xrepo (when missing) and returns its compile/link flags as a hashref. On MSVC the
library flag is given as `-libpath:...` rather than `-L...`:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
my $zlib = $x->pkg_config('zlib'); # installs zlib on first call
say $zlib->{cflags}; # -IC:\...\zlib\...\include
say $zlib->{libs}; # -libpath:C:\...\lib zlib.lib
```
## Use the bundled xrepo from the same handle
The dist ships xrepo alongside xmake; `xrepo` returns its path so you can mix xmake project work with xrepo package
operations in one script:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
( run in 1.200 second using v1.01-cache-2.11-cpan-1236ad508bc )