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 )