Alien-IUP
view release on metacpan or search on metacpan
inc/My/Builder/Unix.pm view on Meta::CPAN
package My::Builder::Unix;
use strict;
use warnings;
use base 'My::Builder';
use File::Spec::Functions qw(catdir catfile rel2abs);
use File::Spec;
use File::Glob qw(bsd_glob);
use File::Copy;
use Config;
sub build_binaries {
my ($self, $build_out, $srcdir) = @_;
my $success = 1;
my ($extra_cflags, $extra_lflags) = ('-I/usr/local/include', '-L/usr/local/lib');
#try to detect some inc/lib directories
my $d;
$d = $self->run_stdout2str(qw[pkg-config --variable=libdir x11]);
my $dir_x11_lib = ($d && -d $d && $d ne '/usr/lib') ? $d : '';
$d = $self->run_stdout2str(qw[pkg-config --variable=includedir x11]);
my $dir_x11_inc = ($d && -d $d && $d ne '/usr/include') ? $d : '';
$d = $self->run_stdout2str(qw[pkg-config --variable=libdir gl]);
my $dir_opengl_lib = ($d && -d $d && $d ne '/usr/lib') ? $d : '';
$d = $self->run_stdout2str(qw[pkg-config --variable=includedir gl]);
my $dir_opengl_inc = ($d && -d $d && $d ne '/usr/include') ? $d : '';
my $dir_mot_inc = ''; # Xm/Xm.h (do not know where to get a sane default)
$dir_mot_inc ||= '/usr/local/include' if (-f '/usr/local/include/Xm/Xm.h');
my $dir_mot_lib = ''; # -lXm (do not know where to get a sane default)
$dir_mot_lib ||= '/usr/local/lib' if (-f '/usr/local/lib/libXm.a');
$dir_mot_lib ||= '/usr/local/lib' if (-f '/usr/local/lib/libXm.so');
$dir_mot_lib ||= '/usr/local/lib' if (-f '/usr/local/lib/libXm.la');
#platform specific hacks
if ($^O eq 'solaris') {
$dir_mot_inc ||= '/usr/dt/include' if (-f '/usr/dt/include/Xm/Xm.h');
$dir_mot_lib ||= '/usr/dt/lib' if (-f '/usr/dt/lib/libXm.so');
$dir_opengl_inc ||= '/usr/X11/include' if (-f '/usr/X11/include/GL/gl.h');
$dir_opengl_lib ||= '/usr/X11/lib/GL' if (-f '/usr/X11/lib/GL/libGL.so');
$dir_x11_inc ||= '/usr/openwin/include' if (-f '/usr/openwin/include/X11/Xlib.h');
$dir_x11_lib ||= '/usr/openwin/lib' if (-f '/usr/openwin/lib/libX11.so');
$dir_x11_inc ||= '/usr/openwin/share/include' if (-f '/usr/openwin/share/include/X11/Xlib.h');
$dir_x11_lib ||= '/usr/openwin/share/lib' if (-f '/usr/openwin/share/lib/libX11.so');
}
if ($^O eq 'darwin') {
$extra_cflags .= ' -I/opt/local/include';
$extra_lflags .= ' -L/opt/local/lib';
}
#generic /usr/X11R6/...
$dir_x11_inc ||= '/usr/X11R6/include' if (-f '/usr/X11R6/include/X11/Xlib.h');
$dir_x11_lib ||= '/usr/X11R6/lib' if (-f '/usr/X11R6/lib/libX11.so');
$dir_opengl_inc ||= '/usr/X11R6/include' if (-f '/usr/X11R6/include/GL/gl.h');
$dir_opengl_lib ||= '/usr/X11R6/lib' if (-f '/usr/X11R6/lib/libGL.so');
#generic /usr/X11R7/...
$dir_x11_inc ||= '/usr/X11R7/include' if (-f '/usr/X11R7/include/X11/Xlib.h');
$dir_x11_lib ||= '/usr/X11R7/lib' if (-f '/usr/X11R7/lib/libX11.so');
$dir_opengl_inc ||= '/usr/X11R7/include' if (-f '/usr/X11R7/include/GL/gl.h');
$dir_opengl_lib ||= '/usr/X11R7/lib' if (-f '/usr/X11R7/lib/libGL.so');
$extra_cflags .= " -I$dir_x11_inc" if $dir_x11_inc;
$extra_lflags .= " -L$dir_x11_lib" if $dir_x11_lib;
$extra_cflags .= " -I$dir_opengl_inc" if $dir_opengl_inc;
$extra_lflags .= " -I$dir_opengl_lib" if $dir_opengl_lib;
inc/My/Builder/Unix.pm view on Meta::CPAN
my $gtk_base = ($build_target eq 'GTK2') ?
$self->run_stdout2str(qw[pkg-config --variable=prefix gtk+-2.0]) :
$self->run_stdout2str(qw[pkg-config --variable=prefix gtk+-3.0]);
push(@makeopts, "GTK_BASE=$gtk_base") if $gtk_base;
push(@makeopts, "GTK=$gtk_base") if $gtk_base;
#detected libs
push(@makeopts, "X11_LIBS=" . join(' ', @x11_libs));
push(@makeopts, "X11_LIB=$dir_x11_lib") if $dir_x11_lib;
push(@makeopts, "X11_INC=$dir_x11_inc") if $dir_x11_inc;
push(@makeopts, "OPENGL_LIBS=" . join(' ', @opengl_libs));
push(@makeopts, "OPENGL_LIB=$dir_opengl_lib") if $dir_opengl_lib;
push(@makeopts, "OPENGL_INC=$dir_opengl_inc") if $dir_opengl_inc;
push(@libs, @opengl_libs);
#Note: $extra_?flags will be stored into ConfigData - they are not used for building
my @mods = ($build_target eq 'GTK2') ?
qw[gtk+-2.0 gdk-2.0 pango cairo] :
qw[gtk+-3.0 gdk-3.0 pango cairo];
$extra_cflags = $self->run_stdout2str(qw[pkg-config --cflags], @mods) . " $extra_cflags";
$extra_lflags = $self->run_stdout2str(qw[pkg-config --libs], @mods) . " $extra_lflags";
}
elsif ($build_target eq 'X11/Motif') {
push(@makeopts, 'USE_X11=Yes');
push(@makeopts, 'USE_MOTIF=Yes');
#additional X11 related libs
push(@x11_libs, 'Xp') if $has{l_Xp};
push(@x11_libs, 'Xt') if $has{l_Xt};
push(@x11_libs, 'Xm') if $has{l_Xm};
push(@x11_libs, 'Xmu') if $has{l_Xmu};
#detected libs
push(@makeopts, "X11_LIBS=" . join(' ', @x11_libs));
push(@makeopts, "X11_LIB=$dir_x11_lib") if $dir_x11_lib;
push(@makeopts, "X11_INC=$dir_x11_inc") if $dir_x11_inc;
push(@makeopts, "OPENGL_LIBS=" . join(' ', @opengl_libs));
push(@makeopts, "OPENGL_LIB=$dir_opengl_lib") if $dir_opengl_lib;
push(@makeopts, "OPENGL_INC=$dir_opengl_inc") if $dir_opengl_inc;
push(@makeopts, "MOTIF_INC=$dir_mot_inc") if $dir_mot_inc;
push(@makeopts, "MOTIF_LIB=$dir_mot_lib") if $dir_mot_lib;
push(@libs, @x11_libs, @opengl_libs);
#Note: $extra_?flags set at the beginning of this sub
}
else {
die "###ERROR### Wrong build target '$build_target!";
}
#extra options for iup/imglib
push(@makeopts, 'USE_IUP_IMGLIB_LARGE=1') if $self->notes('build_large_imglib');
if ($Config{cc} eq 'cc') {
# fix for: https://rt.cpan.org/Public/Bug/Display.html?id=94615
push(@makeopts, 'CC=cc', 'CPPC=c++');
}
#do the job
$success = $self->build_via_tecmake($build_out, $srcdir, \@makeopts, \@iuptargets, \@cdtargets, \@imtargets, $ftgl_target);
warn "###MAKE FAILED###" unless $success;
#make a list of libs necessary to link with IUP and related libraries
my %seen;
my @gl_l = bsd_glob("$build_out/lib/*");
my @gl_i = bsd_glob("$build_out/include/*");
print STDERR "Output counts: lib=" . scalar(@gl_l) . " include=" . scalar(@gl_i) . "\n";
if ((scalar(@gl_l) < 3) || (scalar(@gl_i) < 3)) {
warn "###WARN### $build_out/lib/ or $build_out/include/ not complete";
$success = 0;
}
foreach (@gl_l) {
print STDERR "Created lib: $_\n" if $self->notes('build_debug_info');
if ($_ =~ /lib([a-zA-Z0-9\_\-\.]*?)\.(so|dylib|bundle|a|dll\.a)$/) {
$seen{$1} = 1;
}
elsif ($_ !~ /\.dll$/) { # *.dll on cygwin is OK
warn "###WARN### Unexpected filename '$_'";
$success = 0;
}
}
push(@libs, 'stdc++') if $has{'l_stdc++'}; # -lstdc++ needed by Linux (at least)
my @iuplibs = $self->sort_libs(keys %seen);
$self->config_data('iup_libs', {map {$_=>1} @iuplibs} );
$self->config_data('linker_libs', [@iuplibs, @libs] );
$self->config_data('extra_cflags', $extra_cflags);
$self->config_data('extra_lflags', $extra_lflags);
print STDERR "Build finished!\n";
return $success;
};
sub build_via_tecmake {
my ($self, $build_out, $srcdir, $mopts, $iuptgs, $cdtgs, $imtgs, $ftgl_target) = @_;
$srcdir ||= 'src';
my $prefixdir = rel2abs($build_out);
my $make = $self->notes('gnu_make') || $self->get_make;
die "###ERROR## make command not defined" unless $make;
my $success = 1;
#create output directory structure
mkdir "$prefixdir" unless -d "$prefixdir";
mkdir "$prefixdir/lib" unless -d "$prefixdir/lib";
mkdir "$prefixdir/include" unless -d "$prefixdir/include";
my %done;
if(-d "$srcdir/freetype/src") {
print STDERR "Gonna build 'freetype'\n";
chdir "$srcdir/freetype/src";
copy('../../iup/tecmake.mak', '../tecmake.mak') unless -f '../tecmakewin.mak'; #WORKAROUND
$done{"freetype"} = $self->run_custom($make, 'freetype', @{$mopts});
$success = 0 unless $done{"freetype"};
copy($_, "$prefixdir/include/") foreach (bsd_glob("../include/*.h"));
copy($_, "$prefixdir/lib/") foreach (bsd_glob("../lib/*/*"));
chdir $self->base_dir();
}
if($ftgl_target && -d "$srcdir/ftgl/src") {
print STDERR "Gonna build 'ftgl'\n";
chdir "$srcdir/ftgl/src";
copy('../../iup/tecmake.mak', '../tecmake.mak') unless -f '../tecmakewin.mak'; #WORKAROUND
$done{"ftgl"} = $self->run_custom($make, 'ftgl', @{$mopts});
$success = 0 unless $done{"ftgl"};
copy($_, "$prefixdir/include/") foreach (bsd_glob("../include/*.h"));
copy($_, "$prefixdir/lib/") foreach (bsd_glob("../lib/*/*"));
chdir $self->base_dir();
}
if(-d "$srcdir/im/src") {
print STDERR "Gonna build 'im'\n";
chdir "$srcdir/im/src";
foreach my $t (@{$imtgs}) {
$done{"im:$t"} = $self->run_custom($make, $t, @{$mopts});
$success = 0 unless $done{"im:$t"};
}
copy($_, "$prefixdir/include/") foreach (bsd_glob("../include/*.h"));
copy($_, "$prefixdir/lib/") foreach (bsd_glob("../lib/*/*"));
chdir $self->base_dir();
}
if (-d "$srcdir/cd/src") {
print STDERR "Gonna build 'cd'\n";
chdir "$srcdir/cd/src";
foreach my $t (@{$cdtgs}) {
$done{"cd:$t"} = $self->run_custom($make, $t, @{$mopts});
$success = 0 unless $done{"cd:$t"};
}
copy($_, "$prefixdir/include/") foreach (bsd_glob("../include/*.h"));
copy($_, "$prefixdir/lib/") foreach (bsd_glob("../lib/*/*"));
chdir $self->base_dir();
}
if (-d "$srcdir/iup") {
print STDERR "Gonna build 'iup'\n";
chdir "$srcdir/iup";
foreach my $t (@{$iuptgs}) {
$done{"iup:$t"} = $self->run_custom($make, $t, @{$mopts});
$success = 0 unless $done{"iup:$t"};
}
copy($_, "$prefixdir/include/") foreach (bsd_glob("./include/*.h"));
copy($_, "$prefixdir/lib/") foreach (bsd_glob("./lib/*/*"));
chdir $self->base_dir();
}
# save it for future use in ConfigData
$self->config_data('build_prefix', $prefixdir);
$self->config_data('info_makeopts', $mopts);
$self->config_data('info_done', \%done);
return $success;
}
sub get_make {
my ($self) = @_;
my $devnull = File::Spec->devnull();
my @try = ($Config{gmake}, 'gmake', 'make', $Config{make});
my %tested;
print STDERR "Gonna detect GNU make\n" if $self->notes('build_debug_info');
foreach my $name ( @try ) {
next unless $name;
next if $tested{$name};
$tested{$name} = 1;
print STDERR "- testing: '$name'\n" if $self->notes('build_debug_info');
my $ver = `$name --version 2> $devnull`;
if ($ver =~ /GNU Make/i) {
print STDERR "- found: '$name'\n" if $self->notes('build_debug_info');
return $name
}
}
warn "###WARN### it seems we do not have GNU make, build is likely gonna fail!";
return;
#print STDERR "- fallback to: 'make'\n";
#return 'make';
}
sub quote_literal {
my ($self, $txt) = @_;
$txt =~ s|'|'\\''|g;
return "'$txt'";
}
sub detect_sys_libs {
my $self = shift;
$self->pkg_config('pkg-config', '/dev/null');
};
1;
( run in 0.908 second using v1.01-cache-2.11-cpan-e1769b4cff6 )