#!/usr/bin/perl ##---------------------------------------------------------------------------------------------- # generate very simple portable Makefile for Unix or MS Windows. For MS Windows it generates # Makefile for MS Visual C++. # # It's the perl version of my genmake which was a bourne shell script # # I just hate complex Makefiles. Why make complex Makefiles when a simple one does the job # just fine?? # # muquit@muquit.com Feb-29-2004 ##---------------------------------------------------------------------------------------------- # # $Revision: 8 $ # $Author: Muquit $ # $Date: 3/20/04 11:01a $ use strict; use Getopt::Long; $|=1; ##------------ global vars starts--- my $g_debug=0; my $g_version_s="1.1"; my $g_version=0; my $g_author="Muhammad A Muquit, muquit\@muquit.com"; my $g_url="genmake.pl home: http://muquit.com/muquit/software/"; my $g_license="Copryright: GNU GPL (http://www.gnu.org/copyleft/gpl.html)"; my ($g_unix,$g_windows,$g_app,$g_lib,$g_dll,$g_help)=''; my $GEN_APP=1; my $GEN_LIB=2; my $GEN_DLL=3; # # OS => ["compile command","compile command for shlib","linker","same for # shlb" my %g_os=( "SunOS" => ["cc","cc -KPIC","cc","ld -G"], "Linux" => ["gcc","gcc -fPIC","gcc","ld -shared"], ); my %g_op=(); ## ## Unix application template follows my $g_unix_app_template=<\$g_op{unix}, "win" =>\$g_op{win}, "app=s" =>\$g_op{app}, "lib=s" =>\$g_op{lib}, "dll=s" =>\$g_op{dll}, "help" =>\$g_help, "debug" =>\$g_debug, "version" =>\$g_version, ); ##------------ global vars ends--- &do_it(); # won't be here ##----- # show usage and exit ####### sub usage { print< Makefile $0 --win --app=myapp.exe main.c bar.c > Makefile.win $0 --unix --lib=libmyapp.a main.c bar.c > Makefile $0 --win --lib=myapp.lib main.c bar.c > Makefile.win $0 --win --dll=libmyapp.so main.c bar.c > Makefile.win $0 --win --dll=myapp.dll main.c bar.c > Makefile.win If no --unix or --win flag is specified, OS type will be guessed Edit the generated Makefile if nedeed. EOF ; exit(1); } ##----- # do everything and exit ##----- sub do_it { my $result=GetOptions(%g_options); $g_unix=$g_op{unix}; $g_windows=$g_op{win}; $g_app=$g_op{app}; $g_lib=$g_op{lib}; $g_dll=$g_op{dll}; if ($g_version) { print "genmake.p v$g_version_s\n"; exit(0); } if ($g_help) { &usage(); } if ($g_unix or $g_windows) { $argc--; } if ($g_app) { $argc--; } if ($g_lib) { $argc--; } if ($g_dll) { $argc--; } if ($g_help) { $argc--; } if ($g_unix and $g_windows) { &print_error("--unix and --win are mutually exclusive\n"); exit(0); } &print_debug("g_unix: $g_unix, g_win: $g_windows\n"); if (! $g_unix and ! $g_windows) { my $os=&detect_platform(); &print_debug("os: $os\n"); if ($os ne 'win') { $g_unix=1; } else { $g_windows=1; } } if (! $g_app and ! $g_lib and ! $g_dll) { &usage(); } if ($g_lib and $g_dll) { &print_error("--lib and --dll are mutually exclusive\n"); exit(0); } if ($g_app and $g_lib) { &print_error("--app and --lib are mutually exclusive\n"); exit(0); } if ($g_unix) { my $do_what=$GEN_APP; $do_what=$GEN_APP if ($g_app); $do_what=$GEN_LIB if ($g_lib); $do_what=$GEN_DLL if ($g_dll); &gen_unix_makefile($do_what); exit(0); } else { my $do_what=$GEN_APP; $do_what=$GEN_APP if ($g_app); $do_what=$GEN_LIB if ($g_lib); $do_what=$GEN_DLL if ($g_dll); &gen_windows_makefile($do_what); exit(0); } &usage(); } sub detect_platform() { my $os=&run_pg("uname"); &print_debug("os: $os\n"); if (length($os) > 0) { if ($os =~ /^cygwin.*$/i) { return("win"); } } else { return("win"); } return($os); } sub print_error { my $msg=shift; my $line_num=(caller(0))[2]; print STDERR "$line_num: $msg"; } sub print_debug { my $msg=shift; my $line_num=(caller(0))[2]; if ($g_debug) { print STDERR "(debug) $line_num: $msg"; } } sub has_ranlib { #my $w=`which anlib`; my $w=&run_pg("which ranlib"); return($w); } ##---- # run a external program and return the output #----- sub run_pg { my $pg_orig=shift; my $pg="$pg_orig |"; local *FD; my @out=(); unless((open(FD,"$pg"))) { &print_error("Could not run: $pg_orig\n"); return(''); } my $l=''; while () { $l=$_; chomp($l); push(@out,$l); } close(FD); my $o=''; if (scalar(@out) == 1) { $o=$out[0]; return($o); } return(''); } ##----- # generate Makefile for Linux/Unix ##----- sub gen_unix_makefile { my $do_what=shift; my $srcs=''; my $objs=''; if ($argc != 0) { my $i; my $date=localtime(time()); my $created="Created with genmake.pl v$g_version_s on $date"; for ($i=0; $i < $argc; $i++) { &print_debug("ARGV[$i]=$ARGV[$i]\n"); $srcs .= "$ARGV[$i] "; } $objs=$srcs; $objs =~ s/\.[a-zA-Z]+/\.o/g; if ($do_what == $GEN_APP) { $g_unix_app_template =~ s/-=PROG=-/$g_app/g; $g_unix_app_template =~ s/-=VERSION=-/$created/g; $g_unix_app_template =~ s/-=URL=-/$g_url/g; $g_unix_app_template =~ s/-=CC=-/cc/g; $g_unix_app_template =~ s/-=SRCS=-/$srcs/g; $g_unix_app_template =~ s/-=OBJS=-/$objs/g; print $g_unix_app_template; } elsif ($do_what == $GEN_LIB) { my $ranlib=&has_ranlib(); $g_unix_lib_template =~ s/-=LIBN=-/$g_lib/g; $g_unix_lib_template =~ s/-=VERSION=-/$created/g; $g_unix_lib_template =~ s/-=URL=-/$g_url/g; $g_unix_lib_template =~ s/-=CC=-/cc/g; $g_unix_lib_template =~ s/-=SRCS=-/$srcs/g; $g_unix_lib_template =~ s/-=OBJS=-/$objs/g; $g_unix_lib_template =~ s/-=ranlib=-/$ranlib/g; print $g_unix_lib_template; } elsif ($do_what == $GEN_DLL) { my $ranlib=&has_ranlib(); my $os=&detect_platform(); &print_debug("Os: $os\n"); my $linker="cc"; my $cc="cc"; $cc=$g_os{$os}[1]; $linker=$g_os{$os}[3]; $g_unix_lib_template =~ s/-=LIBN=-/$g_dll/g; $g_unix_lib_template =~ s/-=VERSION=-/$created/g; $g_unix_lib_template =~ s/-=URL=-/$g_url/g; $g_unix_lib_template =~ s/-=CC=-/$cc/g; $g_unix_lib_template =~ s/-=LINK=-/$linker/g; $g_unix_lib_template =~ s/-=SRCS=-/$srcs/g; $g_unix_lib_template =~ s/-=OBJS=-/$objs/g; $g_unix_lib_template =~ s/-=ranlib=-/$ranlib/g; $g_unix_lib_template =~ s/\t\$\(AR\) \$@ \$\(OBJS\)/\t\$(LINK) -o \$(LIBNAME) \$(LIBS)/g; $g_unix_lib_template =~ s/\t\$\(RANLIB\) \$@//g; print $g_unix_lib_template; } } } ##----- # Generate Makefile for MS Windows to be used with MS Visual C++ compiler ##----- sub gen_windows_makefile { my $do_what=shift; &print_debug("do_what: $do_what\n"); my $srcs=''; my $objs=''; if ($argc != 0) { my $i; my $date=localtime(time()); my $created="Created with genmake.pl v$g_version_s on $date"; for ($i=0; $i < $argc; $i++) { &print_debug("ARGV[$i]=$ARGV[$i]\n"); $srcs .= "$ARGV[$i] "; } $objs=$srcs; $objs =~ s/\.[a-zA-Z]+/\.obj/g; if ($do_what == $GEN_APP) { $g_win_app_template =~ s/-=PROGN=-/$g_app/g; $g_win_app_template =~ s/-=VERSION=-/$created/g; $g_win_app_template =~ s/-=URL=-/$g_url/g; $g_win_app_template =~ s/-=CC=-/cc/g; $g_win_app_template =~ s/-=SRCS=-/$srcs/g; $g_win_app_template =~ s/-=OBJS=-/$objs/g; print $g_win_app_template; } elsif ($do_what == $GEN_LIB) { $g_win_lib_template =~ s/-=LIBN=-/$g_lib/g; $g_win_lib_template =~ s/-=VERSION=-/$created/g; $g_win_lib_template =~ s/-=URL=-/$g_url/g; $g_win_lib_template =~ s/-=CC=-/cc/g; $g_win_lib_template =~ s/-=SRCS=-/$srcs/g; $g_win_lib_template =~ s/-=OBJS=-/$objs/g; $g_win_lib_template =~ s/-=WHAT=-/\/lib/g; print $g_win_lib_template; } elsif ($do_what == $GEN_DLL) { &print_debug("GEN_DLL,dll=$g_dll\n"); $g_win_lib_template =~ s/-=LIBN=-/$g_dll/g; $g_win_lib_template =~ s/-=VERSION=-/$created/g; $g_win_lib_template =~ s/-=URL=-/$g_url/g; $g_win_lib_template =~ s/-=CC=-/cc/g; $g_win_lib_template =~ s/-=SRCS=-/$srcs/g; $g_win_lib_template =~ s/-=OBJS=-/$objs/g; $g_win_lib_template =~ s/-=WHAT=-/\/dll/g; print $g_win_lib_template; } } }