Alien-Xmake
view release on metacpan or search on metacpan
my $found = $xmake->addon('flags', search => 1); # captured output
```
Installs, removes, lists or searches xmake addon packages (`install`, `remove`, `list`, `search`, `upgrade`).
`all` applies an operation to every addon and `force` bypasses checks.
## `check( [$checker], %options )`
```perl
my $list = $xmake->check( list => 1 );
$xmake->check('gcc_flags.logic');
```
Lists available checkers (captured) or runs a named check script. `info` explains a checker (captured).
## `doxygen( [$srcdir], %options )`
```perl
$xmake->doxygen('./src', outputdir => './docs');
```
Generates Doxygen documentation for `$srcdir`. `outputdir` selects the documentation directory.
## `format( [$target], %options )`
```perl
$xmake->format('hello', style => 'google');
$xmake->format( dry_run => 1, files => ['a.c', 'b.c'] );
```
Formats the project sources with clang-format. `style` chooses the style (`google`, `llvm`, ...), `create` writes a
default `.clang-format`, `dry_run` only reports files that would change (`-n`), `error` treats style mismatches as
errors (`-e`), `files` limits formatting to the given files, and `all`/`group`/`jobs` behave as elsewhere.
## `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' );
```
Rebuilds (or runs) the project whenever source files change. `commands` holds the command to rerun (`-c`), `script`
the path of the script to watch, `watchdirs`/`plaindirs` add extra watched/ignored directories, `run` reruns the
given target and `target` the target to build. Arbitrary program arguments are passed via `argv`.
## `task( $name, %options )`
```perl
$xmake->task('show', args => ['-l', 'toolchains']);
```
Generic escape hatch that runs any xmake task/plugin by name with `%options`, streaming output and returning success.
Reach for this when a dedicated method doesn't exist yet.
## `version( )`
```perl
my $ver = $xmake->version;
```
Returns the xmake version (e.g. `v3.0.6`).
## `buildid( )`
```perl
my $build = $xmake->buildid;
```
Returns the xmake build stamp (e.g. `HEAD.9fdcf69f6`), if any.
## `config( )`
```perl
my %conf = %{ $xmake->config };
my $bin = $xmake->config('bin');
```
Returns the install-time data stored by [Alien::Xmake::ConfigData](https://metacpan.org/pod/Alien%3A%3AXmake%3A%3AConfigData): the install type, install directory, and version.
The details of the Alien::Xmake::ConfigData object created at install time describe the exact contents.
## `pkg_config( $package )`
```perl
my $flags = $xmake->pkg_config('zlib');
# { cflags => '-I...', libs => '-L... -lz' }
```
Installs `$package` with `xrepo install -y`, then returns its compile/link flags via `xrepo fetch`.
## `install_type( )`
Returns 'system' or 'shared'.
## `exe( )`
```
system $xmake->exe;
```
Returns the full path to the Xmake executable.
## `xrepo( )`
```
system $xmake->xrepo;
```
Returns the full path to the [xrepo](https://github.com/xmake-io/xmake-repo) executable.
## `bin_dir( )`
```perl
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;
system $x->xrepo, qw[search zlib]; # find a package
system $x->xrepo, qw[info libpng]; # package details
```
## Query structured target info and arbitrary Lua as JSON
Capture methods return decoded Perl data instead of streaming. `target_info` gives the rich per-target detail, and
`lua_json` is the escape hatch for any other structured query:
```perl
use v5.40;
use Alien::Xmake;
my $x = Alien::Xmake->new;
$x->create('demo', template => 'console');
chdir 'demo';
$x->configure(mode => 'release');
# decoded target HASH (name, kind, files, compilers, linker, targetfile ...)
my $target = $x->target_info('demo');
say $target->{targetfile}; # build\windows\x64\release\demo.exe
# arbitrary Lua, decoded back to Perl
my $host = $x->lua_json('os.host()', return => 1); # "windows"
my $env = $x->lua_json(q{return { host = os.host(), arch = os.arch() }}, return => 1);
say $env->{arch}; # "x64"
```
## Emit the build file from Perl and drive it
The `xmake.lua` is just a Lua file. Because every action accepts `-F/--file`, you can write that description directly
from Perl (no interactive scaffolding), point the handle at it with the `file` constructor option, and run the whole
lifecycle. The Perl DSL below composes the same statements you would type in a build file:
```perl
use v5.40;
use Alien::Xmake;
use File::Slurper qw[write_text];
my $dir = 'build-dir';
mkdir $dir or die $!;
mkdir "$dir/src" or die $!;
write_text "$dir/src/main.cpp", "int main() { return 42; }\n";
my $lua = qq{
set_project("hello")
target("app")
set_kind("binary")
add_files("src/*.cpp")
};
write_text "$dir/mybuild.lua", $lua;
my $x = Alien::Xmake->new( file => "$dir/mybuild.lua" ); # every action uses -F mybuild.lua
chdir $dir;
$x->configure( mode => 'release' );
$x->build; # compiles src/main.cpp
say for @{ $x->show( 'targets', format => 'json' ) }; # app
```
## Compose a project from Perl instead of writing Lua
Hand-writing the build-file string works, but for authoring at runtime prefer [Alien::Xmake::Project](https://metacpan.org/pod/Alien%3A%3AXmake%3A%3AProject): a fluent Perl
DSL that accumulates the `xmake.lua` statements for you, writes the file on `save`, and returns an [Alien::Xmake](https://metacpan.org/pod/Alien%3A%3AXmake)
handle already bound to it. Targets are built with chains like `set_kind('binary')->add_files('src/*.cpp')`:
```perl
use v5.40;
( run in 1.369 second using v1.01-cache-2.11-cpan-54e63673c56 )