Alien-Xmake
view release on metacpan or search on metacpan
lib/Alien/Xmake.pod view on Meta::CPAN
Global UI/terminal settings.
=item B<cachedir>
Global cache directory.
=item B<policies>
Global policy overrides (C<--policies=>).
=item B<network>, B<proxy>, B<proxy_hosts>, B<proxy_pac>
Network settings, e.g. C<network =E<gt> 'n'> to go offline, C<insecure_ssl =E<gt> 1> to skip HTTPS verification.
=item B<pkg_searchdirs>, B<pkg_cachedir>, B<pkg_installdir>
Global package search/cache/install directories.
=back
=head2 C<install( [$target], %options )>
$xmake->install;
$xmake->install('hello', installdir => './dist');
Installs the built binaries to a staging directory (C<DESTDIR>).
=over
=item B<installdir>
The install directory (C<-o>); C<bindir>, C<libdir>, C<includedir> adjust the per-kind subdirectories.
=item B<all>
Install all targets (C<-a>).
=item B<group>
Install all targets in the group (C<-g>).
=item B<binaries>, B<headers>, B<libraries>, B<packages>
Set to C<y> or C<n> to enable or disable installing that kind of file.
=back
=head2 C<uninstall( [$target], %options )>
$xmake->uninstall;
$xmake->uninstall('hello');
Uninstalls installed binaries from the install directory. Supports C<installdir>, C<bindir>, C<libdir>, C<includedir>,
C<group> and C<admin>.
=head2 C<package( [$target], %options )>
$xmake->package; # package release artifacts
$xmake->package('hello', outputdir => './dist');
Packages the built targets into distribution archives/installers. C<outputdir> selects the destination, C<format> the
package format (C<-f>, e.g. C<deb>, C<rpm>, C<nsis>), C<all> includes dependent targets, and C<homepage>,
C<description>, C<url>, C<version> and C<shasum> fill the package metadata.
=head2 C<pack( [$pkg], %options )>
$xmake->pack('libpng', formats => ['zip', 'targz'], jobs => 4);
Bundles an installed package from the local package cache into distribution archives. C<outputdir> selects the
destination, C<formats> the archive format(s) (C<zip>, C<targz>, ...), C<basename>, C<autobuild> and C<jobs> tune the
archive name, rebuild behavior and parallelism.
=head2 C<require( [$pkg], %options )>
$xmake->require('libpng');
my $list = $xmake->require( list => 1 );
my $json = $xmake->require( 'libpng', depgraph => 1, format => 'json' );
Installs and manages the packages declared (or requested) for the current project.
=over
=item B<list>
List the required packages (C<-l>, captured output).
=item B<scan>
Scan for missing/unused package configs (C<--scan>, captured).
=item B<info>
Show package information (C<--info>, captured).
=item B<depgraph>
Show the package dependency graph (C<--depgraph>, captured; combine with C<format =E<gt> 'json'> or C<'dot'>).
=item B<force>, B<shallow>, B<jobs>, B<linkjobs>, B<clean>
Standard package-install controls. B<clean_modes> resets the configs of the matched packages, B<clean> only clears
unused packages, B<build> always build from source, and B<addon> manages addon packages.
=back
=head2 C<run( [$target], %options )>
$xmake->run;
$xmake->run('hello', args => [qw[--flag value]]);
Runs the build target (or the C<run> script). C<debug> attaches a debugger, C<all>/C<group> select targets, C<workdir>
sets the working directory (C<-w>), C<jobs> sets the parallelism and C<detach> runs the target in the background. Extra
program arguments go in C<args>.
=head2 C<test( [$target], %options )>
$xmake->test;
$xmake->test( 'hello', rebuild => 1 );
Runs the project's tests. C<group>, C<workdir>, C<jobs> and C<rebuild> behave as elsewhere.
=head2 C<update( [$version], %options )>
$xmake->update; # update xmake itself
$xmake->update('v3.0.6', scriptonly => 1);
Updates the C<xmake> installation. C<version> optionally pins a version. C<scriptonly> only updates the scripts
(C<-s>), C<integrate> re-integrates the shell environment, C<force> downloads even when up to date and C<uninstall>
flags the previous version for removal.
=head2 C<service( %options )>
$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' );
lib/Alien/Xmake.pod view on Meta::CPAN
=head2 C<alien_helper( )>
use alienfile;
# ...
[ '%{xmake}', 'install' ],
Returns a hashref of helpers: C<%{xmake}> and C<%{xrepo}>, suitable for use in C<alienfile> recipes.
=head1 Alien::Base Helper
To use Xmake in your C<alienfile>s, require this module and use C<%{xmake}> and C<%{xrepo}>.
use alienfile;
# ...
[ '%{xmake}', 'install' ],
[ '%{xrepo}', 'install ...' ]
# ...
=head1 Xmake Cookbook
Xmake is severely underrated so I'll add more nifty things here but for now just a quick example.
You're free to create your own projects, of course, but Xmake comes with the ability to generate an entire project for
you:
$ xmake create -P hi # generates a basic console project in C++ and xmake.lua build script
$ cd hi
$ xmake -y # builds the project if required, installing defined prerequisite libs, etc.
$ xmake run # runs the target binary which prints 'hello, world!'
C<xmake create> is a lot like C<minil new> in that it generates a new project for you that's ready to build even before
you change anything. It even tosses a C<.gitignore> file in. You can generate projects in C++, Go, Objective C, Rust,
Swift, D, Zig, Vale, Pascal, Nim, Fortran, and more. You can also generate boilerplate projects for simple console
apps, static and shared libraries, macOS bundles, GUI apps based on Qt or wxWidgets, IOS apps, and more.
See C<xmake create --help> for a full list.
The following examples drive xmake from Perl. These all call the wrapper methods (see L</METHODS>), so output is
streamed to your terminal and each returns truthy on success.
=head2 Scaffold, configure, build, test and run a target
The whole edit-run-debug lifecycle. C<create> scaffolds a fresh project (C<template> picks the base), C<configure> sets
the build mode, then C<build>/C<test>/C<run> compile, run the tests (if any) and launch the binary:
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
=head2 Generate files for another build system or IDE
C<project> reads your C<xmake.lua> and emits other build systems' project files, so you never maintain a second build
config by hand. C<kind> selects the generator and C<lsp> asks for IDE-friendly compile data:
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
=head2 Ask xmake what it can target
C<show> introspects the C<xmake> install and the current project. Hand it a list name and (optionally) C<format =E<gt>
'json'> to get the parsed result; the L</METHODS> list names are C<platforms>, C<architectures>, C<toolchains>,
C<buildmodes>, C<targets>, C<packages>, C<rules>, C<themes>, C<envs>, C<apis> and C<policies>. C<config> reflects the
metadata of this L<Alien::Xmake> install itself (set up at construction; see C<new> under L</METHODS>):
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 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
( run in 0.665 second using v1.01-cache-2.11-cpan-e623d60df62 )