Alien-Xmake
view release on metacpan or search on metacpan
lib/Alien/Xmake.pod view on Meta::CPAN
$xmake->service( start => 1, distcc => 1 ); # run the distcc service
$xmake->service( status => 1 );
Controls the built-in xmake services. One of C<start>, C<stop>, C<restart>, C<status>, C<connect>, C<disconnect>,
C<reconnect>, C<sync>, C<clean>; C<remote>, C<distcc>, C<ccache>, C<add-user>, C<rm-user>, C<gen-token> select or
modify the service, C<host> and C<session> target a specific server/session, and C<logs>/C<pull> fetch server logs.
=head2 C<addon( [$name], %options )>
$xmake->addon('gcc_flags', install => 1);
my $found = $xmake->addon('flags', search => 1); # captured output
Installs, removes, lists or searches xmake addon packages (C<install>, C<remove>, C<list>, C<search>, C<upgrade>).
C<all> applies an operation to every addon and C<force> bypasses checks.
=head2 C<check( [$checker], %options )>
my $list = $xmake->check( list => 1 );
$xmake->check('gcc_flags.logic');
Lists available checkers (captured) or runs a named check script. C<info> explains a checker (captured).
=head2 C<doxygen( [$srcdir], %options )>
$xmake->doxygen('./src', outputdir => './docs');
Generates Doxygen documentation for C<$srcdir>. C<outputdir> selects the documentation directory.
=head2 C<format( [$target], %options )>
$xmake->format('hello', style => 'google');
$xmake->format( dry_run => 1, files => ['a.c', 'b.c'] );
Formats the project sources with clang-format. C<style> chooses the style (C<google>, C<llvm>, ...), C<create> writes a
default C<.clang-format>, C<dry_run> only reports files that would change (C<-n>), C<error> treats style mismatches as
errors (C<-e>), C<files> limits formatting to the given files, and C<all>/C<group>/C<jobs> behave as elsewhere.
=head2 C<lua( [$script], %options )>
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 C<xmake> Lua script. Pass inline Lua code, or the path to a C<.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. C<list> lists the built-in scripts (captured) and C<deserialize> records the
output in the given format. C<command> and C<stdin> are accepted and treated as inline code.
=head2 C<lua_json( [$code], %options )>
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 C<import>ing C<core.base.json> and passing C<print(json.encode(...))>. With C<return =E<gt> 1> just give the value,
e.g. a string, a number, a table (C<{1,2,3}>), or a nested structure (C<{name='z', libs={'z','m'}}>), and the wrapper
prints the encoded JSON for you.
xmake's C<lua> runner appends a stray C<{ }> chunk even on success, so the wrapper locates and decodes the emitted JSON
value and returns an empty list if none is found. C<lua_json> is the general escape hatch when a specific method (like
C<< target_info >>) does not yet exist for a structured query.
=head2 C<macro( [$name], %options )>
$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 C<xmake macro>). C<begin>/C<end> control recording,
C<show> prints a recorded macro, C<list> lists them (captured), C<delete>/C<clear> remove them and C<export>/C<import>
move them between machines.
=head2 C<project( %options )>
$xmake->project( kind => 'vsxmake' );
$xmake->project( kind => 'make', targets => ['hello'] );
Generates IDE/third-party project files (C<vs>, C<vsxmake>, C<make>, C<cmake>, C<compile_commands>, ...). C<kind>
selects the generator, C<modes>/C<archs> restrict the configs to generate, C<target> generates only for that target and
C<lsp> writes LSP-friendly output (C<compile_flags.txt> or C<compile_commands.json>).
=head2 C<repo( [$name], %options )>
my $repos = $xmake->repo( list => 1 );
$xmake->repo('local_extra', add => 1, url => 'git@github.com:me/xmake-repo.git');
Manages custom package repositories. C<add>, C<remove>, C<update>, C<clear> and C<list> select the operation (C<list>
returns captured output); C<global> restricts the change to the global config; C<url> and C<branch> are used when
adding.
=head2 C<show( [$list], %options )>
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 C<xmake> installation.
=over
=item B<$list>
List name: C<platforms>, C<architectures>, C<toolchains>, C<buildmodes>, C<targets>, C<packages>, C<rules>, C<themes>,
C<envs>, C<apis> or C<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.
=item B<format>
Output format. C<json> returns the decoded data structure, C<dot> renders dependency graphs. Only meaningful with
C<info =E<gt> 'depgraph'> or a listing.
=item B<target>
Restrict output to a specific target (C<--target=>).
=item B<info>
What to show (C<depgraph>, ...). Combine with C<format>.
=item B<group>
Filter targets by group.
=item B<pretty>
C<--format=json> output (and the other formats) is already decoded/structured; C<pretty> only adds pretty-printed
formatting to the raw listing output.
=back
=head2 C<target_info( $name, %options )>
my $t = $xmake->target_info('hello'); # decoded HASH
say $t->{targetfile}; # build\windows\x64\release\hello.exe
Shows the rich, per-target detail that C<xmake show -t E<lt>targetE<gt>> produces: C<name>, C<kind>, C<files>,
C<compilers>, C<linker>, C<rules>, C<at> and C<targetfile>.
Returns the decoded JSON structure (a HASH) by default. Pass C<plain =E<gt> 1> (or C<format =E<gt> 'plain'>) to get the
human-readable output instead. C<group> filters by target group. An empty list is returned if the target does not
exist.
=head2 C<watch( %options )>
$xmake->watch( commands => 'xmake build' );
$xmake->watch( script => 'my_script.lua' );
Rebuilds (or runs) the project whenever source files change. C<commands> holds the command to rerun (C<-c>), C<script>
the path of the script to watch, C<watchdirs>/C<plaindirs> add extra watched/ignored directories, C<run> reruns the
given target and C<target> the target to build. Arbitrary program arguments are passed via C<argv>.
=head2 C<task( $name, %options )>
$xmake->task('show', args => ['-l', 'toolchains']);
Generic escape hatch that runs any xmake task/plugin by name with C<%options>, streaming output and returning success.
Reach for this when a dedicated method doesn't exist yet.
=head2 C<version( )>
my $ver = $xmake->version;
Returns the xmake version (e.g. C<v3.0.6>).
=head2 C<buildid( )>
my $build = $xmake->buildid;
Returns the xmake build stamp (e.g. C<HEAD.9fdcf69f6>), if any.
=head2 C<config( )>
my %conf = %{ $xmake->config };
my $bin = $xmake->config('bin');
Returns the install-time data stored by L<Alien::Xmake::ConfigData>: the install type, install directory, and version.
The details of the Alien::Xmake::ConfigData object created at install time describe the exact contents.
=head2 C<pkg_config( $package )>
my $flags = $xmake->pkg_config('zlib');
# { cflags => '-I...', libs => '-L... -lz' }
Installs C<$package> with C<xrepo install -y>, then returns its compile/link flags via C<xrepo fetch>.
=head2 C<install_type( )>
Returns 'system' or 'shared'.
=head2 C<exe( )>
system $xmake->exe;
Returns the full path to the Xmake executable.
=head2 C<xrepo( )>
system $xmake->xrepo;
Returns the full path to the L<xrepo|https://github.com/xmake-io/xmake-repo> executable.
=head2 C<bin_dir( )>
use Env qw[@PATH];
unshift @PATH, $xmake->bin_dir;
Returns the directory containing the Xmake executable; push it onto your C<PATH>. For a 'system' install this step will
not be required.
=head2 C<cflags( )>
A stub returning an empty value, provided for compatibility with consumers that expect the standard Alien API surface.
Use C<pkg_config( )> or L<Alien::Xrepo> for real flags.
=head2 C<libs( )>
lib/Alien/Xmake.pod view on Meta::CPAN
The list queries also work from a bare C<show> (no project needed) for the global catalogs. Several return rich JSON:
the C<apis> value is a big HASH of the built-in module APIs, while C<buildmodes>, C<platforms>, C<rules>, C<themes> and
C<targets> come back as ARRAY refs. C<architectures>, C<envs>, C<policies> and C<toolchains> still print aligned table
text (xmake does not JSON-serialize them), so those come back as a plain listing:
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
=head2 Lint the project from Perl
C<check> runs xmake's B<analysis> checkers - C<syntax> validates the source compiles without linking and C<clang.tidy>
drives clang-tidy. It is a linter, not a compiler probe; C<'c'> and C<'cxx'> are not checkers. C<list =E<gt> 1> returns
the available checker names:
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
=head2 Fetch pkg-config style flags for a dependency
C<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 C<-libpath:...> rather than C<-L...>:
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
=head2 Use the bundled xrepo from the same handle
The dist ships xrepo alongside xmake; C<xrepo> returns its path so you can mix xmake project work with xrepo package
operations in one script:
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
=head2 Query structured target info and arbitrary Lua as JSON
Capture methods return decoded Perl data instead of streaming. C<target_info> gives the rich per-target detail, and
C<lua_json> is the escape hatch for any other structured query:
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"
=head2 Emit the build file from Perl and drive it
The C<xmake.lua> is just a Lua file. Because every action accepts C<-F/--file>, you can write that description directly
from Perl (no interactive scaffolding), point the handle at it with the C<file> constructor option, and run the whole
lifecycle. The Perl DSL below composes the same statements you would type in a build file:
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
=head2 Compose a project from Perl instead of writing Lua
Hand-writing the build-file string works, but for authoring at runtime prefer L<Alien::Xmake::Project>: a fluent Perl
DSL that accumulates the C<xmake.lua> statements for you, writes the file on C<save>, and returns an L<Alien::Xmake>
handle already bound to it. Targets are built with chains like C<< set_kind('binary')->add_files('src/*.cpp') >>:
use v5.40;
use Alien::Xmake::Project;
my $p = Alien::Xmake::Project->new( file => 'build/xmake.lua' );
$p->set_project('myapp')->set_version('0.1.0');
$p->add_requires('zlib');
( run in 1.790 second using v1.01-cache-2.11-cpan-54e63673c56 )