Alien-Xmake

 view release on metacpan or  search on metacpan

lib/Alien/Xmake.pm  view on Meta::CPAN

        chomp $libs;
        return { cflags => $cflags, libs => $libs };
    }

    sub capture_cmd (@cmd) {
        return capture { system @cmd }
    }
    method version ()             { $self->install_type eq 'system' ? $self->_getver : $config->{version} }
    method buildid ()             { $self->_getbuild }
    method config ( $key //= () ) { defined $key ? $config->{$key} : $config }

    sub alien_helper () {
        { xmake => sub { __PACKAGE__->new->exe }, xrepo => sub { __PACKAGE__->new->xrepo } }
    }

    # Task plumbing
    method _cmd ( $action, @args ) {

        # Inject auto-confirm flags so captured/streamed installs never hang on a prompt.
        unshift @args, '--confirm=' . $confirm if defined $confirm && length $confirm;
        unshift @args, '-y'                    if $yes             && !( defined $confirm && length $confirm );

        # Inject the build file so every action reads the given xmake.lua rather than one in the cwd.
        unshift @args, '-F', $file if defined $file && length $file;
        my @cmd = ( $self->exe, $action, @args );
        $self->blah("Running: @cmd");
        @cmd;
    }

    # Stream a task to the terminal (builds, runs, installs ...) and return success.
    method _run ( $action, @args ) {
        my @cmd = $self->_cmd( $action, @args );
        return system(@cmd) == 0;
    }

    # Run a task capturing output; returns ($out, $err, $exit).
    method _capture ( $action, @args ) {
        my @cmd = $self->_cmd( $action, @args );
        return capture { system @cmd };
    }

    # Slurp the extra trailing arguments out of %opts.
    method _extra_args ($opts) {
        my @args;
        push @args, @{ $opts->{targets} // [] };
        push @args, @{ $opts->{args}    // [] };
        @args;
    }

    # Format a scalar or arrayref as a comma/separator joined flag value.
    method _join ( $value, $sep //= ',' ) {
        return () unless defined $value;
        ref $value eq 'ARRAY' ? join( $sep, map { _bool_str($_) } @$value ) : _bool_str($value);
    }

    sub _bool_str ($value) {
        return $value ? 'true' : 'false' if is_bool($value);
        return $value;
    }

    # Generic escape hatch: run any task/plugin by name.
    method task ( $name, %opts ) {
        my @args = $self->_extra_args( \%opts );
        $self->_run( $name, @args );
    }

    # Actions
    method build ( $target //= (), %opts ) {
        my @args;
        push @args, '-r'        if $opts{rebuild};
        push @args, '-a'        if $opts{all};
        push @args, '--shallow' if $opts{shallow};
        push @args, '-g', $opts{group} if $opts{group};
        push @args, '--dry-run' if $opts{dry_run};
        push @args, '-j', $opts{jobs} if $opts{jobs};
        push @args, '--linkjobs=' . $opts{linkjobs}                if $opts{linkjobs};
        push @args, '--linkonly'                                   if $opts{linkonly};
        push @args, '--files=' . $self->_join( $opts{files}, ';' ) if $opts{files};
        push @args, $target                                        if defined $target && length $target;
        push @args, $self->_extra_args( \%opts );
        $self->_run( 'build', @args );
    }

    method clean ( $target //= (), %opts ) {
        my @args;
        push @args, '-a' if $opts{all};
        push @args, '-g', $opts{group} if $opts{group};
        push @args, $target if defined $target && length $target;
        push @args, $self->_extra_args( \%opts );
        $self->_run( 'clean', @args );
    }

    method create ( $target //= (), %opts ) {
        my @args;
        push @args, '-f'     if $opts{force};
        push @args, '--list' if $opts{list};
        push @args, '-l', $opts{language} if $opts{language};
        push @args, '-t', $opts{template} if $opts{template};
        push @args, '-P', $opts{project}  if $opts{project};
        push @args, $target if defined $target && length $target;
        push @args, $self->_extra_args( \%opts );
        $self->_run( 'create', @args );
    }

    method configure (%opts) {
        my @args = $self->_config_args( \%opts );
        push @args, '-c'                        if $opts{clean};
        push @args, '--check'                   if $opts{check};
        push @args, '--menu'                    if $opts{menu};
        push @args, '--export=' . $opts{export} if $opts{export};
        push @args, '--import=' . $opts{import} if $opts{import};
        push @args, '-o', $opts{builddir} if $opts{builddir};
        push @args, $self->_extra_args( \%opts );
        $self->_run( 'config', @args );
    }

    method global (%opts) {
        my @args;
        push @args, '-c'                                                             if $opts{clean};
        push @args, '--check'                                                        if $opts{check};
        push @args, '--menu'                                                         if $opts{menu};

lib/Alien/Xmake.pm  view on Meta::CPAN

        push @args, '-m', $opts->{mode} if $opts->{mode};
        push @args, '-k', $opts->{kind} if $opts->{kind};
        for my $key (
            qw[toolchain toolchain_host cross target_os bin sdk runtimes ndk ndk_sdkver android_sdk
            build_toolver ndk_stdcxx cuda cuda_sdkver qt qt_host qt_sdkver vcpkg mingw emsdk vs vs_toolset
            vs_sdkver vs_runtime wdk wdk_sdkver wdk_winver debugger ccache ccachedir trybuild tryconfigs
            require pkg_searchdirs pkg_cachedir pkg_installdir rc rcld rcar rcsh fc fcld fcsh linkdirs links
            syslinks includedirs ]
        ) {
            push @args, "--$key=" . $self->_join( $opts->{$key}, ';' ) if defined $opts->{$key};
        }
        push @args, "--$_=$opts->{set}{$_}" for sort keys %{ $opts->{set} // {} };
        @args;
    }

    # Introspection helpers
    method _getver() {
        my ( $ver, undef ) = $self->_getver_build;
        "v$ver";
    }

    method _getbuild() {
        my ( undef, $build ) = $self->_getver_build;
        $build;
    }

    method _getver_build() {
        my $cmd = $self->exe;
        state $out //= do {
            my ( $stdout, undef, $exit ) = capture_cmd( $cmd, '--version' );
            $exit == 0 ? $stdout : '';
        };
        return ( $1, $2 ) if $out =~ /xmake\s+v?(\d+\.\d+\.\d+)(?:\+(.+),)?/i;
        ( '0.0.0', () );
    }

    method _scrub_env () {
        delete @ENV{qw[XMAKE_PROGRAM_DIR XMAKE_PROGRAM_FILE XMAKE_ROOTDIR]} if $self->install_type eq 'share';
    }

    # Resolve absolute path without quotes
    method _resolve_path () {
        my $bin = $config->{bin};

        # If ConfigData failed or we are in a fallback state:
        $bin = File::Spec->catfile( $dir, 'xmake' . ( $windows ? '.exe' : '' ) ) if !$bin && $dir;
        $bin //= 'xmake';
        $self->_scrub_env;

        # Ensure we return a stringified absolute path safe for system()
        File::Spec->rel2abs($bin);
    }

    # Quote path if on Windows and spaces exist
    method _quote_path ($path) {
        return qq{"$path"} if $windows && $path =~ /\s/;
        $path;
    }

    # Safely quote arguments for Windows cmd.exe
    method _escape_args (@args) { return @args }
};
#
1;
__END__
Copyright (C) Sanko Robinson.

This library is free software; you can redistribute it and/or modify it under the terms found in
the Artistic License 2. Other copyrights, terms, and conditions may apply to data transmitted
through this module.



( run in 1.760 second using v1.01-cache-2.11-cpan-54e63673c56 )