@@ -4,25 +4,36 @@ use version 0.77; our $VERSION = qv(v0.1.1);
4
4
use strict;
5
5
use warnings;
6
6
use JSON::PP 2.0104 qw( decode_json) ;
7
- use File::Path 2.07 qw( make_path) ;
7
+ use File::Path 2.07 qw( make_path remove_tree ) ;
8
8
use Cwd qw( abs_path getcwd) ;
9
9
use Data::Dumper qw( Dumper) ;
10
10
use File::Basename qw( basename dirname) ;
11
- use File::Copy qw( copy) ;
11
+ use File::Copy qw( copy move) ;
12
+ use Env qw( @PATH) ;
12
13
use FindBin qw( ) ;
13
14
use Getopt::Long qw( GetOptionsFromArray) ;
14
15
Getopt::Long::Configure qw( gnu_getopt) ;
15
16
16
17
use constant {
17
- SITE_CONFIG_DIR => (($ENV {XDG_CONFIG_HOME } // ($ENV {HOME }.' /.config' )).' /apperl' ),
18
- SITE_REPO_DIR => (($ENV {XDG_DATA_HOME } // ($ENV {HOME }.' /.local/share' )).' /apperl' ),
19
- PROJECT_FILE => ' apperl-project.json' ,
20
18
START_WD => getcwd(),
21
- PROJECT_TMP_DIR => abs_path(' .apperl' )
19
+ PROJECT_FILE => ' apperl-project.json' ,
20
+ };
21
+ use constant {
22
+ PROJECT_TMP_DIR => (START_WD.' /.apperl' ),
23
+ };
24
+ use constant {
25
+ # DEFDATAROOT is used if the XDG base directories cannot be found
26
+ DEFDATAROOT => defined ($ENV {HOME }) ? $ENV {HOME }
27
+ : defined ($ENV {APPDATA }) ? $ENV {APPDATA } .' /apperl'
28
+ : PROJECT_TMP_DIR.' /site' ,
29
+ PROJECT_TMP_CONFIG_FILE => (PROJECT_TMP_DIR.' /user-project.json' ),
30
+ };
31
+ use constant {
32
+ SITE_CONFIG_DIR => ($ENV {XDG_CONFIG_HOME } // (DEFDATAROOT.' /.config' )) . ' /apperl' ,
33
+ SITE_REPO_DIR => ($ENV {XDG_DATA_HOME } // (DEFDATAROOT.' /.local/share' )).' /apperl' ,
22
34
};
23
35
use constant {
24
36
SITE_CONFIG_FILE => (SITE_CONFIG_DIR." /site.json" ),
25
- PROJECT_TMP_CONFIG_FILE => (PROJECT_TMP_DIR.' /user-project.json' )
26
37
};
27
38
28
39
sub _load_apperl_configs {
@@ -887,7 +898,10 @@ sub Set {
887
898
chdir ($SiteConfig -> {perl_repo }) or die " Failed to enter perl repo" ;
888
899
print " make veryclean\n " ;
889
900
system (" make" , " veryclean" );
890
- _command_or_die(' rm' , ' -f' , ' miniperl.com' , ' miniperl.elf' , ' perl.com' , ' perl.elf' );
901
+ foreach my $todelete (' miniperl.com' , ' perl.com' , ' miniperl.elf' , ' perl.elf' ) {
902
+ print " rm $todelete \n " ;
903
+ unlink ($todelete ) || $! {ENOENT } or die " failed to delete $todelete " ;
904
+ }
891
905
_command_or_die(' git' , ' checkout' , $itemconfig -> {perl_id });
892
906
893
907
print " cd " .START_WD." \n " ;
@@ -957,7 +971,23 @@ sub _fix_bases {
957
971
return $in ;
958
972
}
959
973
974
+ # system is pretty broken on APPerl when running on Windows
975
+ # let's search PATH ourselves ...
976
+ sub _find_zip {
977
+ if (($^O ne ' cosmo' ) || (! -f ' /C/Windows/System32/cmd.exe' )) {
978
+ return ' zip' ;
979
+ }
980
+ else {
981
+ foreach my $dir (@PATH ) {
982
+ my $zippath = " $dir /zip.exe" ;
983
+ return $zippath if (-f $zippath );
984
+ }
985
+ }
986
+ die (" Failed to find zip.exe, did you download Info-Zip and add the folder containing zip.exe to \% PATH\% ?" );
987
+ }
988
+
960
989
sub Build {
990
+ my ($zippath ) = @_ ;
961
991
my $Configs = _load_apperl_configs();
962
992
my $UserProjectConfig = _load_valid_user_project_config_with_default($Configs ) or die " cannot Build without valid UserProjectConfig" ;
963
993
my $CurAPPerlName = $UserProjectConfig -> {current_apperl };
@@ -986,10 +1016,12 @@ sub Build {
986
1016
-f $PERL_APE or die " apperlm build: perl ape not found" ;
987
1017
my $OUTPUTDIR = " $UserProjectConfig ->{apperl_output}/$CurAPPerlName " ;
988
1018
if (-d $OUTPUTDIR ) {
989
- _command_or_die(' rm' , ' -rf' , $OUTPUTDIR );
1019
+ print " rm -rf $OUTPUTDIR \n " ;
1020
+ remove_tree($OUTPUTDIR );
990
1021
}
991
1022
my $TEMPDIR = " $OUTPUTDIR /tmp" ;
992
- _command_or_die(' mkdir' , ' -p' , $TEMPDIR );
1023
+ print " mkdir -p $TEMPDIR \n " ;
1024
+ make_path($TEMPDIR );
993
1025
my $PERL_PREFIX = _cmdoutput_or_die(@perl_config_cmd , ' -e' , ' use Config; print $Config{prefix}' );
994
1026
my $PREFIX_NOZIP = $PERL_PREFIX ;
995
1027
$PREFIX_NOZIP =~ s / ^\/ zip\/ *// ;
@@ -1001,7 +1033,9 @@ sub Build {
1001
1033
# install cosmo perl if this isn't a nobuild config
1002
1034
if (! exists $UserProjectConfig -> {nobuild_perl_bin }){
1003
1035
_command_or_die(' make' , " DESTDIR=$TEMPDIR " , ' install' );
1004
- _command_or_die(' rm' , " $TEMPDIR$PERL_PREFIX /bin/perl" , " $TEMPDIR$PERL_PREFIX /bin/perl$PERL_VERSION " );
1036
+ my @toremove = (" $TEMPDIR$PERL_PREFIX /bin/perl" , " $TEMPDIR$PERL_PREFIX /bin/perl$PERL_VERSION " );
1037
+ print ' rm ' .join (' ' , @toremove )." \n " ;
1038
+ unlink (@toremove ) == scalar (@toremove ) or die " Failed to unlink some files" ;
1005
1039
}
1006
1040
else {
1007
1041
make_path($ZIP_ROOT );
@@ -1010,8 +1044,10 @@ sub Build {
1010
1044
# pack
1011
1045
my $APPNAME = basename($PERL_APE );
1012
1046
my $APPPATH = " $TEMPDIR /$APPNAME " ;
1013
- _command_or_die(' cp' , $PERL_APE , $APPPATH );
1014
- _command_or_die(' chmod' , ' u+w' , $APPPATH );
1047
+ print " cp $PERL_APE $APPPATH \n " ;
1048
+ copy($PERL_APE , $APPPATH ) or die " copy failed: $! " ;
1049
+ print " chmod 755 $APPPATH \n " ;
1050
+ chmod (0755, $APPPATH ) or die $! ;
1015
1051
if ((! exists $UserProjectConfig -> {nobuild_perl_bin }) || scalar (keys %{$itemconfig -> {zip_extra_files }})) {
1016
1052
print " cd $ZIP_ROOT \n " ;
1017
1053
chdir ($ZIP_ROOT ) or die " failed to enter ziproot" ;
@@ -1021,15 +1057,18 @@ sub Build {
1021
1057
_copy_recursive($file , $dest );
1022
1058
}
1023
1059
}
1024
- _command_or_die(' zip ' , ' -r' , $APPPATH , @zipfiles );
1060
+ _command_or_die($zippath // _find_zip() , ' -r' , $APPPATH , @zipfiles );
1025
1061
}
1026
- _command_or_die(' mv' , $APPPATH , " $OUTPUTDIR /perl.com" );
1062
+ print " mv $APPPATH $OUTPUTDIR /perl.com\n " ;
1063
+ move($APPPATH , " $OUTPUTDIR /perl.com" ) or die " move failed: $! " ;
1027
1064
1028
1065
# copy to user specified location
1029
1066
if (exists $itemconfig -> {dest }) {
1030
1067
print " cd " .START_WD." \n " ;
1031
1068
chdir (START_WD) or die " Failed to restore cwd" ;
1032
- _command_or_die(' cp' , " $UserProjectConfig ->{apperl_output}/$CurAPPerlName /perl.com" , $itemconfig -> {dest });
1069
+ my @args = (" $UserProjectConfig ->{apperl_output}/$CurAPPerlName /perl.com" , $itemconfig -> {dest });
1070
+ print ' cp ' .join (' ' , @args )." \n " ;
1071
+ copy(@args ) or die " copy failed: $! " ;
1033
1072
}
1034
1073
}
1035
1074
@@ -1064,12 +1103,21 @@ END_USAGE
1064
1103
}
1065
1104
elsif ($command eq ' build' ) {
1066
1105
my $usage = <<'END_USAGE' ;
1067
- apperlm build
1106
+ apperlm build [-z|--zippath <zip_binary_path>]
1107
+ -z|--zippath Path to InfoZip zip executable
1068
1108
Build APPerl. If the current config is a from-scratch build, you must
1069
1109
run `apperlm configure` first.
1070
1110
END_USAGE
1071
- die ($usage ) if (@_ );
1072
- Perl::Dist::APPerl::Build();
1111
+ my $zippath ;
1112
+ my $help ;
1113
+ GetOptionsFromArray(\@_ , " zippath|z=s" => \$zippath ,
1114
+ " help|h" => \$help ,
1115
+ ) or die ($usage );
1116
+ if ($help ) {
1117
+ print $usage ;
1118
+ exit 0;
1119
+ }
1120
+ Perl::Dist::APPerl::Build($zippath );
1073
1121
}
1074
1122
elsif ($command eq ' configure' ) {
1075
1123
Perl::Dist::APPerl::Configure(@_ );
@@ -1482,7 +1530,10 @@ and runs Perl's C<Configure>
1482
1530
1483
1531
C<apperlm build > C<make > s perl and builds apperl. The output binary by
1484
1532
default is copied to C<perl.com > in the current directory, set dest in
1485
- C<apperl-project.json > to customize output binary path and name.
1533
+ C<apperl-project.json > to customize output binary path and name. A
1534
+ C<zip > binary is required to build, see README.md for details. The
1535
+ C<zip > binary path may be explictly set by passing in
1536
+ --zippath <zip_binary_path> .
1486
1537
1487
1538
=back
1488
1539
@@ -1603,9 +1654,11 @@ permissively already.
1603
1654
1604
1655
If your application requires non-standard C or XS extensions, APPerl
1605
1656
must be built from scratch as it does not support dynamic libraries,
1606
- only static linking. This tutorial assumes you already have an APPerl
1607
- project, possibly from following the
1608
- L</BUILDING AN APPLICATION FROM EXISTING APPERL> tutorial.
1657
+ only static linking. Note, this process can only be completed on
1658
+ Linux as building the Cosmopolitan Libc from scratch is only supported
1659
+ on Linux and APPerl uses the unix-like C<Configure > to configure perl.
1660
+ This tutorial assumes you already have an APPerl project, possibly from
1661
+ following the L</BUILDING AN APPLICATION FROM EXISTING APPERL> tutorial.
1609
1662
1610
1663
First install the APPerl build dependencies and create a new config
1611
1664
based on the current small config, checkout, configure, and build.
0 commit comments