#!/usr/bin/env perl use File::Basename; use File::Compare; use File::Copy; use Cwd; # set sefaults for all options # the 3 paths below all need to be set if they are not defaults! # these are INSTALL prefixes, and are not saved in any binaries $var{prefix} = "/usr/local"; $var{debug} = "no"; $var{size} = "no"; $var{pthread} = "no"; $var{profile} = "no"; $var{static} = "no"; $var{efence} = "no"; $var{silent} = "yes"; $var{jobs} = "1"; $var{static} = "no"; $var{arch} = "i386"; # set defaults for all environment variables # TODO: these are not saved in reconfigure $var{cc} = "cc"; $var{make} = "make"; $var{ar} = "ar"; $var{objcopy} = "objcopy"; # determine dirs. we use absolute paths for convenience # this means that if you move the project, you need to re-run # configure, or modify the SRCDIR and BUILDIR variables in Makefile.defs $var{builddir} = $ENV{BUILDDIR}; $var{srcdir} = $ENV{SRCDIR}; $var{ldflags} = $ENV{LDFLAGS}; $LOGFILE = "$var{builddir}/build.log" ; # set default target name open UNAME, "uname|"; $target = ; $target =~ s/\n//; close UNAME; $var{target} = $target; # default prefix is still /usr/local #if ("Darwin" eq $target){ # $var{prefix}="/sw"; #} # perform a test in the pbuild/tests/ directory. return false on success. sub troubles { my $testname = shift; my @args = ($var{make}, "-s", "$var{builddir}/test/$testname\.test"); #($var{make}, "-s", "-C", "test", "$testname\.test"); my $retval = system (@args); return $retval; } sub errorexit { print "Test Failed. Check your build environment and/or configure flags.\n" ; print "See $LOGFILE for details.\n" ; exit(1); } # perform a required test sub check_deps { my $thing = shift; my $error_msg = shift; print "checking $thing"; print "\n"; my $retval = troubles($thing); if ($retval) { print $error_msg; } # print "\n"; return $retval; } # print valid options sub print_options { foreach $key (keys %var){ print "\t--$key=$var{$key}\n"; } } # override with command line args while ($a = shift) { if ($a eq "--help") { do_help; } elsif ($a =~ m/^--enable-(.+)/) { $var{$1} = "yes"; } elsif ($a =~ m/^--disable-(.+)/) { $var{$1} = "no"; } elsif ($a =~ m/^--(.+?)=(.+)/) { $var{$1} = $2; } else {print "invalid argument ".$a."\n"; do_help;} } # Is there a standard way of doing this? if ($var{cross} eq "") { # print "Not using GCC cross compiler: $var{cross}\n"; } else { print "cross: $var{cross}\n"; $var{cc} = "$var{cross}-cc"; $var{ar} = "$var{cross}-ar"; } # all options parsed: start config if ($var{builddir} eq $var{srcdir}) { print "Building in source directory: " . $var{builddir} . "\n"; } else { # mkdir "test"; cp $var{srcdir} } # create config files chdir $var{builddir}; open PKGCONFIG, ">libprim.pc"; sub pkgconfig { my $line = shift; print PKGCONFIG $line . "\n"; } # FIXME: this isn't correct for debian package pkgconfig "home=$var{prefix}/share/prim"; pkgconfig ""; pkgconfig "Name: libprim"; pkgconfig "Description: libprim: a collection of primitive language objects + scripting languages."; $VERSION=`$var{srcdir}/bin/version`; pkgconfig "Version: $VERSION"; open MAKEFILE, ">Makefile.defs"; sub makefile { my $line = shift; print MAKEFILE $line . "\n"; } makefile "LDFLAGS := $var{ldflags}" ; makefile "PREFIX := $var{prefix}" ; makefile "SRCDIR := $var{srcdir}" ; makefile "BUILDDIR := $var{builddir}" ; makefile "CPPFLAGS += -I$var{builddir} -I$var{srcdir}"; makefile "LOG := $LOGFILE" ; makefile "SDL_CONFIG := $var{sdl}-config" ; makefile "CEXT := c"; # default is c. for cc see build/plugins/ftgl/Makefile makefile "COMPILE := $CC"; makefile "MZSCHEME := mzscheme"; # FIXME: check this! makefile "PLATFORM := $var{target}"; if ($var{jobs} > 1){ makefile "MAKE += -j$var{jobs}"; # run multiple jobs } if ($var{static} eq "yes") { makefile "APP_LDFLAGS += -static"; } open HEADER, ">config.h.new"; sub header { my $line = shift; print HEADER $line . "\n"; } header "#ifndef __PF_CONFIG__"; header "#define __PF_CONFIG__"; header "#define PRIM_HOME \"$var{prefix}/share/prim/\""; header "#include \"target/$var{target}.h\"\n"; # start tests and fill config files for base system chdir "$var{builddir}/tests"; # dir where we will run the tests # keep track of libs used for base package # to fill pkgconfig file @LIBS = (); sub check_base { push @LIBS, "-lm"; makefile "LDFLAGS += -lm" ; if (check_deps "base-deps") { errorexit; } } sub check_dl { push @LIBS, "-ldl"; makefile "LDFLAGS += -ldl" ; if (check_deps "libdl") { errorexit; } } sub toolchain { makefile "CC := $var{cc}" ; makefile "AR := $var{ar}" ; makefile "MAKE := $var{make}" ; makefile "OBJCOPY := $var{objcopy}" ; makefile "OBJDUMP := $var{objdump}" ; makefile "STRIP := $var{strip}" ; if ($var{silent} eq "yes"){ makefile "MAKE += -s"; # have a bit less verbose build } } # add prefix lib & include path makefile "LDFLAGS += -L$var{prefix}/lib"; makefile "CPPFLAGS += -I$var{prefix}/include"; # link to pf lib makefile "LDFLAGS_PF = -L$var{builddir}/libpf -lpf"; makefile "MODEXT = pfo"; # static modules if ($var{static} eq "yes"){ header "#define PF_STATIC"; # compile static modules makefile "COMPILE_TARGET = echo skipping CC"; # skip target compilation } else { makefile "COMPILE_TARGET = \$(CC)"; } makefile "COMPILE_COMPONENT = \$(CC)"; # check GCC print "gcc: "; $gccver = `$var{cc} -dumpversion`; chomp $gccver; if (not $gccver){ print "C compiler is not gcc.\n"; exit(1); } @gccver = split '\.', $gccver; if ($gccver[0] < 3){ print "Need gcc version >= 3\n"; exit(1); } elsif ($gccver[0] == 3){ header "#define GCC3"; } print $gccver . "\n"; # todo: include prefix etc # goal: to compile run in non-root environment for testing # this means locally some packages need to be installed # testsuite = pack of libraries. # platform specific setup printf "target: $var{target}\n"; if ("Linux" eq $var{target}){ # on Darwin, lots of header files are not strict, so i do this only on linux. $EXTRA_DEBUG_CFLAGS="-Wstrict-prototypes"; $DLIB_PATH="LD_LIBRARY_PATH"; makefile "DLEXT = so"; makefile "LDFLAGS_SHARED = -shared"; makefile "LDFLAGS_MODULE = -shared"; # same on linux makefile "OPT_MODULES += v4l rtc SDL"; makefile "CFLAGS += -fPIC" ; toolchain; check_base; check_dl; } elsif ("FreeBSD" eq $var{target}){ $DLIB_PATH="LD_LIBRARY_PATH"; $var{make}="gmake"; makefile "DLEXT = so"; makefile "LDFLAGS_SHARED = -shared"; makefile "LDFLAGS_MODULE = -shared"; # same on linux toolchain; check_base; } elsif ("Darwin" eq $var{target}){ $EXTRA_DEBUG_CFLAGS="-Wno-long-double"; $DLIB_PATH="DYLD_LIBRARY_PATH"; makefile "CPPFLAGS += -I$var{finkpath}/include -fpascal-strings"; makefile "LDFLAGS += -L$var{finkpath}/lib"; makefile "DLEXT = dylib"; makefile 'LDFLAGS_SHARED = -dynamiclib -install_name $(PREFIX)/lib/$(TARGET)'; makefile "LDFLAGS_MODULE = -dynamic -bundle -flat_namespace -undefined suppress" ; makefile "CFLAGS += -fPIC -dynamic"; makefile "OPT_MODULES += carbon"; push @LIBS, "-L$var{finkpath}/lib"; toolchain; check_base; check_dl; } # However, if you are building a dll as an export library, # you will probably want to use the complete syntax: # gcc -shared -o cyg${module}.dll \ # -Wl,--out-implib=lib${module}.dll.a \ # -Wl,--export-all-symbols \ # -Wl,--enable-auto-import \ # -Wl,--whole-archive ${old_libs} \ # -Wl,--no-whole-archive ${dependency_libs} # The name of your library is ${module}, prefixed with cyg # for the DLL and lib for the import library. Cygwin DLLs # use the cyg prefix to differentiate them from native-Windows # MinGW DLLs, see the MinGW website for more details. ${old_libs} # are all your object files, bundled together in static libs or # single object files and the ${dependency_libs} are import libs # you need to link against, e.g '-lpng -lz -L/usr/local/special -lmyspeciallib'. # TODO: use libtool, or add a platform dependent linker script elsif ("CYGWIN_NT-5.0" eq $var{target}){ makefile "DLEXT = dll"; makefile "LDFLAGS_SHARED = -shared"; makefile "LDFLAGS_MODULE = -shared"; toolchain; check_base; #check_dl; # dlopen is 'just there' on cygwin } elsif ("ecos" eq $var{target}){ # For ecos we just need to generate C files. The rest should be # included in the project build. makefile "CPPFLAGS += -I$var{prefix}/include"; makefile "LDFLAGS += -L$var{prefix}/lib -Ttarget.ld -nostdlib"; toolchain; # defaults, overridden by the rest makefile "include $var{prefix}/include/pkgconf/ecos.mak"; makefile "CC := \$(ECOS_COMMAND_PREFIX)gcc"; makefile "LD := \$(ECOS_COMMAND_PREFIX)ld"; makefile "AR := \$(ECOS_COMMAND_PREFIX)ar"; makefile "OBJCOPY := \$(ECOS_COMMAND_PREFIX)objcopy"; makefile "LDFLAGS += \$(ECOS_GLOBAL_LDFLAGS)"; makefile "CFLAGS += \$(ECOS_GLOBAL_CFLAGS)"; # We guess the target platform based on the toolchain command # prefix used. makefile "GDB := $var{srcdir}/bin/\$(notdir \$(ECOS_COMMAND_PREFIX))gdb" } else { printf "Target not supported.\n"; errorexit(); } # tools if ("i386" eq $var{arch}) { makefile "OBJCOPY_ARCH = -O elf32-i386 -B i386"; } elsif ("arm" eq $var{arch}) { makefile "OBJCOPY_ARCH = -O elf32-littlearm -B arm"; } else { printf "Architecture not supported.\n"; errorexit(); } header "#ifndef HAVE_LIBDL"; header "#define HAVE_LIBDL"; header "#endif"; # DEBUG if ($var{debug} eq "yes"){ makefile "CC += $EXTRA_DEBUG_CFLAGS"; makefile "DEBUG_CFLAGS = -g -Wall -Wno-unused -Wno-parentheses -Werror"; # parentheses warning is actually quite valueable.. i still make mistakes to if (a = b) vs (a == b) things # but most of the code triggers warnings here.. clean up some day. header "#define PRIM_DEBUG 1"; # this is changed to not conflict with pf } elsif ($var{size} eq "yes") { makefile "OPTI_CFLAGS = -Os -fomit-frame-pointer -fdata-sections -ffunction-sections"; } else{ makefile "OPTI_CFLAGS = -O3 -ffast-math -funroll-loops"; if ($var{profile} eq "yes") { makefile "OPTI_CFLAGS += -pg -g -O3"; makefile "LDFLAGS += -pg"; } else { makefile "OPTI_CFLAGS += -fomit-frame-pointer"; } header "#define PRIM_DEBUG 0"; } # PTHREAD if ($var{pthread} eq "yes"){ header "#define HAVE_PTHREAD"; push @LIBS, "-lpthread"; makefile "LDFLAGS += -lpthread"; makefile "OPT_MODULES += console"; check_deps "libpthread"; } pkgconfig "Libs: -L$var{prefix}/lib -lprim_sc -lprim_ex -lprim -lprim_leaf -lprim_media" . join " ", @LIBS; pkgconfig "Cflags: -I$var{prefix}/include/prim"; # don't include efence in LIBS or pgkconfig if ($var{efence} eq "yes"){ makefile "DEBUG_LDFLAGS += -lefence"; } header "#endif"; close HEADER; close MAKEFILE; close PGKCONFIG; close FAKEPF; # only update header file if C defs have changed # this is to speed up rebuilding a bit if (compare("config.h.new","config.h") == 0) { # print "config.h did not change\n"; } else { # print "updating config.h\n"; copy("config.h.new","config.h"); } print "Type 'make install' to build and install the package.\n\n"; exit(0);