Alien-Xmake
view release on metacpan or search on metacpan
lib/Alien/Xmake.pod view on Meta::CPAN
=over
=item B<language>
Project language (C<c>, C<c++>, C<go>, C<rust>, ...).
=item B<template>
Project template (C<console>, C<static>, C<shared>, C<qt.widgetapp>, ...).
=item B<force>
Overwrite an existing directory (C<-f>).
=item B<list>
List all available templates instead of creating (C<--list>).
=item B<project>
Alternate project path (C<-P>).
=back
=head2 C<configure( %options )>
$xmake->configure(mode => 'debug', plat => 'windows', arch => 'x64');
Configures the current project (clone of C<xmake config>). Accepts the shared platform/toolchain options (C<plat>,
C<arch>, C<mode>, C<kind>, C<toolchain>, C<toolchain_host>, C<cross>, C<target_os>, C<sdk>, C<runtimes>, C<vs>,
C<vs_toolset>, C<vs_sdkver>, C<vs_runtime>, C<ndk>, C<ndk_stdcxx>, C<ndk_sdkver>, C<android_sdk>, C<mingw>, C<emsdk>,
C<cuda>, C<qt>, C<qt_host>, C<vcpkg>, C<wdk>, C<build_toolver>, C<ccache>, C<ccachedir>, C<debugger>, C<trybuild>,
C<tryconfigs>, C<require>, C<includedirs>, C<linkdirs>, C<links>, C<syslinks>, C<rc*>, C<fc*>, ...) as well as the
compiler/flag subtables C<cflags>, C<cxflags>, C<cxxflags>, C<mflags>, C<mmflags>, C<mxflags>, C<ldflags>, C<arflags>,
C<asflags>, C<shflags>, and C<cuflags>. Any C<--key=value> pair can be passed via C<set =E<gt> { key =E<gt> value }>.
=over
=item B<clean>
Reset the configuration to defaults (C<-c>).
=item B<check>
Only check the configuration and exit (C<--check>).
=item B<menu>
Open the interactive configuration menu (C<--menu>).
=item B<export>, B<import>
Export/import configuration files.
=item B<builddir>
Alternate build directory (C<-o>).
=back
=head2 C<global( %options )>
$xmake->global(network => 'y', theme => 'default');
$xmake->global(vs => '2022');
Reads/writes global (user-level) configuration. Shares the platform/toolchain options from C<configure( ... )> that
exist on C<global> (C<android_sdk>, C<build_toolver>, C<cuda>, C<emsdk>, C<mingw>, C<ndk>, C<ndk_sdkver>, C<qt>,
C<qt_host>, C<vcpkg>, C<vs>, C<wdk>).
=over
=item B<clean>
Reset global configuration to defaults (C<-c>).
=item B<check>, B<menu>
Same semantics as C<configure( ... )>.
=item B<theme>, B<debugger>, B<ccache>
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>,
lib/Alien/Xmake.pod view on Meta::CPAN
=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>
lib/Alien/Xmake.pod view on Meta::CPAN
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
=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:
( run in 1.273 second using v1.01-cache-2.11-cpan-1236ad508bc )