diff --git a/Makefile.PL b/Makefile.PL index 7cf1284..d1fb261 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -20,6 +20,7 @@ use strict; use warnings; use ExtUtils::MakeMaker; use File::Spec; +use Config; use Cwd; my %PREREQ_PM = ( @@ -30,6 +31,7 @@ my %PREREQ_PM = ( my %BUILD_REQ = ( 'gobject-introspection-1.0' => '0.10.0', + 'libffi' => '3.0.0', ); my $dep_success = eval <<__EOE__; @@ -55,6 +57,18 @@ if (!$cfg_success) { exit 0; } +$cfg_success = eval { + my %cfg_ffi = ExtUtils::PkgConfig->find ( + "libffi >= $BUILD_REQ{'libffi'}"); + $cfg{cflags} .= " $cfg_ffi{cflags}"; + $cfg{libs} .= " $cfg_ffi{libs}"; + 1; +}; +if (!$cfg_success) { + warn $@; + exit 0; +} + my @xs_files = qw(GObjectIntrospection.xs); my %pm_files = ( @@ -118,42 +132,108 @@ sub compile_test_libraries { ExtUtils::PkgConfig->find ('cairo-gobject') : (cflags => '', libs => ''); my %gio_flags = ExtUtils::PkgConfig->find ('gio-2.0'); - my %glib_flags = ExtUtils::PkgConfig->find ('glib-2.0'); - - !system (qq(gcc -shared -fPIC -g \\ - $cairo_flags{cflags} $cairo_gobject_flags{cflags} $gio_flags{cflags} \\ - $testsdir/regress.c \\ - $cairo_flags{libs} $cairo_gobject_flags{libs} $gio_flags{libs} \\ - -o libregress.so 1>/dev/null 2>/dev/null)) - && !system (qq(LD_LIBRARY_PATH=$build_dir:\$LD_LIBRARY_PATH \\ - g-ir-scanner \\ - --include=cairo-1.0 --include=Gio-2.0 \\ - --namespace=Regress --nsversion=1.0 \\ - --quiet --warn-all --warn-error \\ - --library=regress \\ - --output=Regress-1.0.gir \\ - $testsdir/regress.h $testsdir/regress.c \\ - 1>/dev/null 2>/dev/null)) - && !system (qq(g-ir-compiler Regress-1.0.gir -o Regress-1.0.typelib \\ - 1>/dev/null 2>/dev/null)) - && !system (qq(gcc -shared -fPIC -g \\ - $glib_flags{cflags} \\ - $testsdir/gimarshallingtests.c \\ - $glib_flags{libs} \\ - -o libgimarshallingtests.so 1>/dev/null 2>/dev/null)) - && !system (qq(LD_LIBRARY_PATH=$build_dir:\$LD_LIBRARY_PATH \\ - g-ir-scanner \\ - --include=GObject-2.0 \\ - --namespace=GIMarshallingTests \\ - --symbol-prefix=gi_marshalling_tests --nsversion=1.0 \\ - --quiet --warn-all --warn-error \\ - --library=gimarshallingtests \\ - --output=GIMarshallingTests-1.0.gir \\ - $testsdir/gimarshallingtests.h $testsdir/gimarshallingtests.c \\ - 1>/dev/null 2>/dev/null)) - && !system (qq(g-ir-compiler GIMarshallingTests-1.0.gir \\ - -o GIMarshallingTests-1.0.typelib 1>/dev/null 2>/dev/null)) + my $optimize = ''; + + if (grep /^OPTIMIZE=.+/, @ARGV) { + # XXX: Workaround Glib built with atomic intrinsics by adding OPTIMIZE to + # CFLAGS (without -march=pentium you get undefined references to + # __sync_fetch_and_sub_4 for example). + $optimize = ((grep /^OPTIMIZE=.+/, @ARGV)[0] =~ /^OPTIMIZE=(.+)$/)[0]; + } + + my @commands; + my $c_flags = qq(-shared -fPIC $optimize); + my $gir_cmd = qq(LD_LIBRARY_PATH=$build_dir:\$LD_LIBRARY_PATH g-ir-scanner); + my $prefix = q(); + my $pipe = qq(1>/dev/null 2>/dev/null); + + if ($^O eq 'MSWin32') { + my @path = File::Spec->path; + my $found = 0; + + foreach my $base ( map { File::Spec->catfile($_, 'g-ir-scanner') } @path ) { + if ( -f $base ) { + $gir_cmd = qq(python $base); + $found = 1; + last; + } + } + + return 0 if (!$found); + + $c_flags = qq(-shared $optimize); + $pipe = qq(1>NUL 2>NUL); + # XXX: We need the lib prefix for --library argument to G-O-I on Win32, + # else DLL resolution fails... + $prefix = 'lib'; + } + + push(@commands, + qq(gcc $c_flags -g \\ + $cairo_flags{cflags} $cairo_gobject_flags{cflags} $gio_flags{cflags} \\ + $testsdir/regress.c \\ + $cairo_flags{libs} $cairo_gobject_flags{libs} $gio_flags{libs} \\ + -o libregress.$Config{dlext} $pipe)); + push(@commands, + qq($gir_cmd \\ + --include=cairo-1.0 --include=Gio-2.0 \\ + --namespace=Regress --nsversion=1.0 \\ + --quiet --warn-all --warn-error \\ + --library=${prefix}regress \\ + --output=Regress-1.0.gir \\ + $testsdir/regress.h $testsdir/regress.c \\ + $pipe)); + push(@commands, + qq(g-ir-compiler Regress-1.0.gir -o Regress-1.0.typelib \\ + $pipe)); + push(@commands, + qq(gcc $c_flags -g \\ + $gio_flags{cflags} \\ + $testsdir/gimarshallingtests.c \\ + $gio_flags{libs} \\ + -o libgimarshallingtests.$Config{dlext} $pipe)); + push(@commands, + qq($gir_cmd \\ + --include=Gio-2.0 \\ + --namespace=GIMarshallingTests \\ + --symbol-prefix=gi_marshalling_tests --nsversion=1.0 \\ + --quiet --warn-all --warn-error \\ + --library=${prefix}gimarshallingtests \\ + --output=GIMarshallingTests-1.0.gir \\ + $testsdir/gimarshallingtests.h $testsdir/gimarshallingtests.c \\ + $pipe)); + push(@commands, + qq(g-ir-compiler GIMarshallingTests-1.0.gir \\ + -o GIMarshallingTests-1.0.typelib $pipe)); + + if ($^O eq 'MSWin32') { + my $path = $ENV{PATH}; + + # XXX: G-O-I defaults to CC=cc + $ENV{CC} = 'gcc' if (!defined $ENV{CC}); + $ENV{PATH} .= ';' . $build_dir; + + foreach my $command (@commands) { + # XXX: Cmd.exe do not support \ as line break ... + $command =~ s/\\\n//mg; + $command =~ s/\s\s+/ /mg; + + system($command) == 0 or return 0; + } + + $ENV{PATH} = $path; + } + else { + foreach my $command (@commands) { + system($command) == 0 or return 0; + } + } + + 1; }; + if ($@) { + print "\n\n$ \n"; + } print $success ? "OK\n" : "not OK\n"; @@ -164,8 +244,15 @@ package MY; # so that "SUPER" works right sub test { my $inherited = shift->SUPER::test(@_); - # put "build" into LD_LIBRARY_PATH for the tests - $inherited =~ s/(test_dynamic :: pure_all)\n\t/$1\n\tLD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:build /; + if ($^O eq 'MSWin32') { + # put "build" into PATH for the tests + # FIXME: Might need tweaking for nmake... + $inherited =~ s/(test_dynamic :: pure_all\n\t)/.IMPORT: PATH\nPATH += ;build\n.EXPORT: PATH\n$1/; + } + else { + # put "build" into LD_LIBRARY_PATH for the tests + $inherited =~ s/(test_dynamic :: pure_all)\n\t/$1\n\tLD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:build /; + } $inherited; } diff --git a/t/inc/setup.pl b/t/inc/setup.pl index 039f33d..cb2a3a9 100644 --- a/t/inc/setup.pl +++ b/t/inc/setup.pl @@ -1,14 +1,27 @@ +use Config; use Glib::Object::Introspection; use Test::More; -unless (-e 'build/libregress.so' && -e 'build/libgimarshallingtests.so') { +unless (-e qq(build/libregress.$Config{dlext}) && + -e qq(build/libgimarshallingtests.$Config{dlext})) +{ plan skip_all => 'Need the test libraries'; } -unless (defined $ENV{LD_LIBRARY_PATH} && - $ENV{LD_LIBRARY_PATH} =~ m/\bbuild\b/) -{ - plan skip_all => 'Need "build" in LD_LIBRARY_PATH'; +if ($^O eq 'MSWin32') { + # FIXME: Not sure how to get this to actually work with dmake + unless (defined $ENV{PATH} && + $ENV{PATH} =~ m/\bbuild\b/) + { + plan skip_all => 'Need "build" in PATH'; + } +} +else { + unless (defined $ENV{LD_LIBRARY_PATH} && + $ENV{LD_LIBRARY_PATH} =~ m/\bbuild\b/) + { + plan skip_all => 'Need "build" in LD_LIBRARY_PATH'; + } } Glib::Object::Introspection->setup(