gcc-opt-1.20/0002755000000000000000000000000011373002730007654 5ustar gcc-opt-1.20/gcc-opt.conf0000644000000000000000000000314611373002730012061 0ustar # Format is # #... a comment, anywhere. # NAME: flags - flags that may be overridden # NAME.prefix: - prefix the command with this (e.g., /usr/bin/ccache) # NAME.force: - These flags are forced to be what they say. # NAME.clear: - These flags may not be specified by the user. # NAME.opt: min max defaultflags # min and max are numbers, default flags is a flaglist to be # used if the optimization is outside of min..max. # -Os is treated as '2' for the min/max check. # HACK: To force optimization flags, make min larger than max. # IF NO MATCHING .opt RULE IS FOUND, then '0 3' is used (and there are no # default flags.) # The first matching rule wins (for each of the flagsets). NAME can be # preceeded by , in which case it will only match for that package. # package is in __GCC_OPT_PACKAGE, or is read from /CurrentlyBuilding. gcc: gcc.force: gcc.clear: gcc-3.3: gcc-3.3.force: -pipe gcc-3.3.clear: gcc-3.3.opt: 0 3 gcc-3.3.prefix: /usr/bin/ccache g++-3.3: g++-3.3.force: -pipe g++-3.3.clear: g++-3.3.opt: 0 3 g++-3.3.prefix: /usr/bin/ccache gcc-3.4: gcc-3.4.force: -pipe gcc-3.4.clear: gcc-3.4.opt: 0 3 gcc-3.4.prefix: /usr/bin/ccache g++-3.4: g++-3.4.force: -pipe g++-3.4.clear: g++-3.4.opt: 0 3 g++-3.4.prefix: /usr/bin/ccache gcc-4.0: gcc-4.0.force: -pipe gcc-4.0.clear: gcc-4.0.opt: 0 3 gcc-4.0.prefix: /usr/bin/ccache g++-4.0: g++-4.0.force: -pipe g++-4.0.clear: g++-4.0.opt: 0 3 g++-4.0.prefix: /usr/bin/ccache gcc: gcc.force: -pipe gcc.clear: gcc.opt: 0 3 gcc.prefix: /usr/bin/ccache g++: g++.force: -pipe g++.clear: g++.opt: 0 3 g++.prefix: /usr/bin/ccache gcc-opt-1.20/Makefile0000644000000000000000000000027411373002730011315 0ustar FILES= gcc-4.0 g++-4.0 g++-3.4 gcc-3.4 gcc-3.3 g++-3.3 test: all @./test.sh all: ${FILES} clean: rm -f ${FILES} ${FILES}: gcc.c gcc -g -o $@ -DCOMPILER=\"/usr/bin/$@.gcc-opt\" gcc.c gcc-opt-1.20/gcc-opt.conf.i3860000644000000000000000000000372411373002730012553 0ustar # Format is # #... a comment, anywhere. # NAME: flags - flags that may be overridden # NAME.prefix: - prefix the command with this (e.g., /usr/bin/ccache) # NAME.force: - These flags are forced to be what they say. # NAME.clear: - These flags may not be specified by the user. # NAME.opt: min max defaultflags # min and max are numbers, default flags is a flaglist to be # used if the optimization is outside of min..max. # -Os is treated as '2' for the min/max check. # HACK: To force optimization flags, make min larger than max. # IF NO MATCHING .opt RULE IS FOUND, then '0 3' is used (and there are no # default flags.) # The first matching rule wins (for each of the flagsets). NAME can be # preceeded by , in which case it will only match for that package. # package is in __GCC_OPT_PACKAGE, or is read from /CurrentlyBuilding. gcc: gcc.force: gcc.clear: gcc-3.3: -mcpu=pentium4 -march=i486 gcc-3.3.force: -pipe gcc-3.3.clear: gcc-3.3.opt: 0 3 gcc-3.3.prefix: /usr/bin/ccache g++-3.3: -mcpu=pentium4 -march=i486 g++-3.3.force: -pipe g++-3.3.clear: g++-3.3.opt: 0 3 g++-3.3.prefix: /usr/bin/ccache gcc-3.4: -mtune=pentium4 -march=i486 gcc-3.4.force: -pipe gcc-3.4.clear: gcc-3.4.opt: 0 3 gcc-3.4.prefix: /usr/bin/ccache g++-3.4: -mtune=pentium4 -march=i486 g++-3.4.force: -pipe g++-3.4.clear: g++-3.4.opt: 0 3 g++-3.4.prefix: /usr/bin/ccache gcc-4.0: -mtune=pentium4 -march=i486 gcc-4.0.force: -pipe gcc-4.0.clear: gcc-4.0.opt: 0 3 gcc-4.0.prefix: /usr/bin/ccache g++-4.0: -mtune=pentium4 -march=i486 g++-4.0.force: -pipe g++-4.0.clear: g++-4.0.opt: 0 3 g++-4.0.prefix: /usr/bin/ccache # These only get picked when the target compiler is not specified above. # since diff versions get picked above, and since the -m{cpu,tune} option # can't make up its mind, don't bother with it here. gcc: gcc.force: -pipe gcc.clear: gcc.opt: 0 3 gcc.prefix: /usr/bin/ccache g++: g++.force: -pipe g++.clear: g++.opt: 0 3 g++.prefix: /usr/bin/ccache gcc-opt-1.20/test.conf0000644000000000000000000000042211373002730011476 0ustar optdefault.opt: 0 3 optdefault.opt: 1 6 -O2 optdefault.opt: 1 2 -O2 test.force: test.prefix: /bin/echo test.prefix: test.command: /bin/echo test: -march=i386 -fda=1 -fdb test.force: -mcpu=pentium4 -ffa=1 -ffb test.clear: -fca=1 -fcb gcc-opt-1.20/debian/0002755000000000000000000000000011373002730011076 5ustar gcc-opt-1.20/debian/control0000644000000000000000000000047411373002730012504 0ustar Source: gcc-opt Section: devel Priority: optional Maintainer: LaMont Jones Build-Depends: debhelper (>> 7.0.0) Standards-Version: 3.5.2.0 Package: gcc-opt Architecture: any Depends: ${misc:Depends}, ccache Description: allow global optimization flags for gcc, g++ set global flags for gcc, g++ gcc-opt-1.20/debian/rules0000755000000000000000000000375511373002730012166 0ustar #!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH) CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif #CONFIGURE# build: build-stamp build-stamp: make all touch build-stamp clean: dh_testdir dh_testroot make clean rm -f build-stamp dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/#PACKAGE#. install -m0755 gcc-3.3 debian/gcc-opt/usr/bin install -m0755 g++-3.3 debian/gcc-opt/usr/bin install -m0755 gcc-3.4 debian/gcc-opt/usr/bin install -m0755 g++-3.4 debian/gcc-opt/usr/bin install -m0755 gcc-4.0 debian/gcc-opt/usr/bin install -m0755 g++-4.0 debian/gcc-opt/usr/bin if [ -f gcc-opt.conf.${ARCH} ]; then \ install -m0644 gcc-opt.conf.${ARCH} debian/gcc-opt/usr/share/gcc-opt/gcc-opt.conf.dist; \ else \ install -m0644 gcc-opt.conf debian/gcc-opt/usr/share/gcc-opt/gcc-opt.conf.dist; \ fi # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir -a dh_testroot -a dh_installchangelogs -a #CHANGELOGS# dh_installdocs -a dh_installexamples -a # dh_install -a # dh_installmenu -a # dh_installdebconf -a # dh_installlogrotate -a # dh_installemacsen -a # dh_installpam -a # dh_installmime -a # dh_installinit -a # dh_installcron -a # dh_installinfo -a dh_installman -a dh_link -a dh_strip -a dh_compress -a dh_fixperms -a # dh_perl -a # dh_python -a # dh_makeshlibs -a dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install #PHONY_CONFIGURE# gcc-opt-1.20/debian/changelog0000644000000000000000000000122011373002730012741 0ustar gcc-opt (1.20) maverick; urgency=low * -m32 and -m64 are enough like -march to cause us to treat it like -march= -mtune=. And yes, that's ugly. * Check cleared flags first, so that we can clear certain values, while still having a default value. * make -m{tune,cpu}=pentium4 a default, not a force. * -O is -O2, not -O1. sigh * correctly order gcc/g++ lines in gcc-opt.conf* * Correctly handle -v. * Add gcc-4.0 hooks and 4.0 diversions. -- LaMont Jones Thu, 13 May 2010 07:47:56 -0600 gcc-opt (1.14) maverick; urgency=low * Release -- LaMont Jones Thu, 13 May 2010 07:18:36 -0600 gcc-opt-1.20/debian/preinst0000644000000000000000000000277711373002730012520 0ustar #! /bin/sh # preinst script for gcc-opt # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in install|upgrade) # if [ "$1" = "upgrade" ] # then # start-stop-daemon --stop --quiet --oknodo \ # --pidfile /var/run/#PACKAGE#.pid \ # --exec /usr/sbin/#PACKAGE# 2>/dev/null || true # fi dpkg-divert --package gcc-opt --add --rename \ --divert /usr/bin/g++-3.3.gcc-opt /usr/bin/g++-3.3 dpkg-divert --package gcc-opt --add --rename \ --divert /usr/bin/gcc-3.3.gcc-opt /usr/bin/gcc-3.3 dpkg-divert --package gcc-opt --add --rename \ --divert /usr/bin/g++-3.4.gcc-opt /usr/bin/g++-3.4 dpkg-divert --package gcc-opt --add --rename \ --divert /usr/bin/gcc-3.4.gcc-opt /usr/bin/gcc-3.4 dpkg-divert --package gcc-opt --add --rename \ --divert /usr/bin/g++-4.0.gcc-opt /usr/bin/g++-4.0 dpkg-divert --package gcc-opt --add --rename \ --divert /usr/bin/gcc-4.0.gcc-opt /usr/bin/gcc-4.0 ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 gcc-opt-1.20/debian/conffiles0000644000000000000000000000000011373002730012755 0ustar gcc-opt-1.20/debian/copyright0000644000000000000000000000130111373002730013022 0ustar This is the packaging of gcc-opt, a method for modifying options to gcc and friends. Copyright 2004-2010 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . gcc-opt-1.20/debian/dirs0000644000000000000000000000003211373002730011753 0ustar usr/bin usr/share/gcc-opt gcc-opt-1.20/debian/postrm0000644000000000000000000000303011373002730012337 0ustar #! /bin/sh # postrm script for gcc-opt # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `purge' # * `upgrade' # * `failed-upgrade' # * `abort-install' # * `abort-install' # * `abort-upgrade' # * `disappear' overwrit>r> # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in remove) dpkg-divert --package gcc-opt --remove --rename \ --divert /usr/bin/g++-3.3.gcc-opt /usr/bin/g++-3.3 dpkg-divert --package gcc-opt --remove --rename \ --divert /usr/bin/gcc-3.3.gcc-opt /usr/bin/gcc-3.3 dpkg-divert --package gcc-opt --remove --rename \ --divert /usr/bin/g++-3.4.gcc-opt /usr/bin/g++-3.4 dpkg-divert --package gcc-opt --remove --rename \ --divert /usr/bin/gcc-3.4.gcc-opt /usr/bin/gcc-3.4 dpkg-divert --package gcc-opt --remove --rename \ --divert /usr/bin/g++-4.0.gcc-opt /usr/bin/g++-4.0 dpkg-divert --package gcc-opt --remove --rename \ --divert /usr/bin/gcc-4.0.gcc-opt /usr/bin/gcc-4.0 ;; purge|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 gcc-opt-1.20/debian/compat0000644000000000000000000000000211373002730012272 0ustar 7 gcc-opt-1.20/debian/postinst0000644000000000000000000000255411373002730012710 0ustar #! /bin/sh # postinst script for gcc-opt # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package # # quoting from the policy: # Any necessary prompting should almost always be confined to the # post-installation script, and should be protected with a conditional # so that unnecessary prompting doesn't happen if a package's # installation fails and the `postinst' is called with `abort-upgrade', # `abort-remove' or `abort-deconfigure'. case "$1" in configure) if [ ! -f /etc/gcc-opt.conf ]; then cp /usr/share/gcc-opt/gcc-opt.conf.dist /etc/gcc-opt.conf fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 gcc-opt-1.20/debian/bzr-version0000644000000000000000000000006411373002730013277 0ustar 3 lamont@debian.org-20100513135944-3qga26i7l6q6bpni gcc-opt-1.20/test.sh0000755000000000000000000000216411373002730011173 0ustar #!/bin/sh # use the test config file, and just echo the arguments, for the tests. export __GCC_OPT_CONFIG_FILE=test.conf export __GCC_OPT_COMPILER_EXEC=/bin/echo typeset -i num=0 typeset -i pass=0 typeset -i fail=0 dotest() { pkg="$1" name="$2" args="$3" ret="$4" num=num+1 out=$(__GCC_OPT_PACKAGE=$pkg __GCC_OPT_COMPILER_NAME=$name ./gcc-3.3 $args) if [ "X$out" = "X$ret" ]; then pass=$pass+1 else echo test $num: echo " " \"$out\" != echo " " \"$ret\" echo fail=$fail+1 fi } [ -x gcc-3.3 ] || make gcc-3.3 dotest "" test "" "-march=i386 -fda=1 -fdb -mcpu=pentium4 -ffa=1 -ffb" dotest "" test "-march=i486 -fda=76 -fca=7 -ffa=76" "-fdb -mcpu=pentium4 -ffa=1 -ffb -march=i486 -fda=76" dotest memtest test "-march=i486" "-fda=1 -fdb -march=i486" dotest prefix test "" "/bin/echo -march=i386 -fda=1 -fdb -mcpu=pentium4 -ffa=1 -ffb" dotest "" optdefault "" "-O2" dotest "" optdefault "-O0" "-O2" dotest "" optdefault "-O1" "-O1" dotest "" optdefault "-O7" "-O2" dotest O6 optdefault "-O6" "-O6" dotest ONONE optdefault "" "" dotest nopref ONONE "" "" echo $num tests: $pass pass, $fail fail gcc-opt-1.20/gcc-opt0000644000000000000000000000017311373002730011132 0ustar # # options to add to gcc and g++ invocations # GCC_OPT="-march=i386 -mcpu=pentium4" GXX_OPT="-march=i386 -mcpu=pentium4" gcc-opt-1.20/gcc.c0000644000000000000000000002714511373002730010563 0ustar /* * (c) 2004 Canonical Software Ltd. All rights reserved. */ #include #include #include #include #include #include #include #include #define STRNEQ(a,b) (strcmp(a,b)!=0) #define STREQ(a,b) (strcmp(a,b)==0) #define STREQN(a,b) (strncmp(a,b,strlen(b))==0) #define CONFIG_FILE "/etc/gcc-opt.conf" int debug=0; #define DBG_ARGS 0x001 #define DBG_CMDS 0x002 #define DBG_PRINT_ARGS 0x002 extern char **environ; struct options { char **CompilerFlags; /* Flags were going to set if not specified */ char **ForcedFlags; /* Flags we force to be our way */ char **ClearedFlags; /* Flags the caller can't use (we clear them) */ char **Command; /* gcc-3.3.real for example, defaults to compile-time default */ char **Prefix; /* ccache for example, defaults to nothing */ int OptMin; /* minimum optimization level */ int OptMax; /* Max opt level */ char **OptDefault; /* If no -O given, use this. */ char **Env; /* changes to the environment */ }; void deleteArg(char **argv,int n) { for (;argv[n]!=NULL; n++) { argv[n]=argv[n+1]; } /* argv is now one pointer longer than it needs to be. So what. * That'll get fixed at the next insert. (Or execv() call.) */ } /* Insert NewArgs into argv starting at position n */ char **insertArgs(char **argv,int n, char **NewArgs) { int new; int old; char **ret; for (old=0;argv[old]!=NULL; old++) ; for (new=0;NewArgs[new]!=NULL; new++) ; ret=malloc((old+new+1)*sizeof(char*)); if (n>0) memcpy(ret,argv,n*sizeof(char*)); if (new) memcpy(&ret[n],NewArgs,new*sizeof(char*)); if (n%s",Package,Name); NewArgs[2]=NULL; argv=insertArgs(argv,n,NewArgs); return argv; } /* Given an option string, split it into component fields, using space * and tab as delimiters */ char ** splitOptions(char *flagsIn) { char *flags=strdup(flagsIn); char **ret=malloc(sizeof(char*)); int count=0; char *p; p=strtok(flags," \t"); while (p!=NULL) { ++count; ret=realloc(ret,(count+1)*sizeof(char*)); ret[count-1]=p; p=strtok(NULL," \t"); } ret[count]=NULL; return ret; } /* Read the config file to get options, and split them up. */ struct options *readOptions(char *name, char* config, char *Package) { static struct options opt; FILE *f; char buf[2048]; char *p; char **MyNames=calloc(1,sizeof(char*)); char **namep; /* set up some defaults */ memset(&opt,0,sizeof(opt)); opt.OptMin=-1; p=strrchr(name,'/'); if (p!=NULL) { MyNames=insertName(MyNames,0,name,Package); name=strdup(p+1); } else { name=strdup(name); } MyNames=insertName(MyNames,0,name,Package); if (strchr(name,'.')) { *strrchr(name,'.')='\0'; } MyNames=insertName(MyNames,0,name,Package); p=strrchr(name,'-'); if (p!=NULL) { *p='\0'; MyNames=insertName(MyNames,0,name,Package); } while ((p=strchr(name,'-'))!=NULL) { p++; MyNames=insertName(MyNames,0,p,Package); } free(name); name=NULL; f=fopen(config,"r"); if (f==NULL) { fprintf(stderr,"unable to open config file: %s\n",strerror(errno)); exit(2); } while (fgets(buf,sizeof(buf),f)!=NULL) { int l=strlen(buf); if (buf[l-1]=='\n') { buf[l-1]='\0'; } else { fprintf(stderr,"Line too long: %s\n",buf); exit(2); } if ((p=strchr(buf,'#'))!=NULL) { *p='\0'; } for (namep=MyNames; *namep; namep++) { int NameLength; name=*namep; NameLength=strlen(name); if (strncmp(buf,name,NameLength)==0) { if (opt.CompilerFlags==NULL && buf[NameLength]==':') { if (debug&DBG_ARGS) fprintf(stderr,"Picked %s\n",name); opt.CompilerFlags=splitOptions(buf+NameLength+1); } else if (opt.ForcedFlags==NULL && strncmp(buf+NameLength,".force:",7)==0) { if (debug&DBG_ARGS) fprintf(stderr,"Picked %s.force\n",name); opt.ForcedFlags=splitOptions(strchr(buf,':')+1); } else if (opt.Command==NULL && strncmp(buf+NameLength,".command:",9)==0) { if (debug&DBG_CMDS) fprintf(stderr,"Picked %s.command\n",name); opt.Command=splitOptions(strchr(buf,':')+1); } else if (opt.Env==NULL && strncmp(buf+NameLength,".env:",5)==0) { if (debug&DBG_CMDS) fprintf(stderr,"Picked %s.env\n",name); opt.Env=splitOptions(strchr(buf,':')+1); } else if (opt.Prefix==NULL && strncmp(buf+NameLength,".prefix:",8)==0) { if (debug&DBG_CMDS) fprintf(stderr,"Picked %s.prefix\n",name); opt.Prefix=splitOptions(strchr(buf,':')+1); } else if (opt.ClearedFlags==NULL && strncmp(buf+NameLength,".clear:",7)==0) { if (debug&DBG_ARGS) fprintf(stderr,"Picked %s.clear\n",name); opt.ClearedFlags=splitOptions(strchr(buf,':')+1); } else if (opt.OptMin==-1 && strncmp(buf+NameLength,".opt:",5)==0) { char **ap=splitOptions(strchr(buf,':')+1); int i; if (debug&DBG_ARGS) fprintf(stderr,"Picked %s.opt\n",name); for (i=0;ap[i];i++); opt.OptMax=3; opt.OptMin=0; switch (i) { case 2: opt.OptMax=atol(ap[1]); /* fall thru */ case 1: opt.OptMin=atol(ap[0]); /* fall thru */ case 0: opt.OptDefault=ap+i; break; default: opt.OptMin=atol(ap[0]); opt.OptMax=atol(ap[1]); opt.OptDefault=ap+2; break; } } } } } fclose(f); if (opt.CompilerFlags==NULL) { opt.CompilerFlags=calloc(1,sizeof(sizeof(opt.CompilerFlags[0]))); } if (opt.ForcedFlags==NULL) { opt.ForcedFlags=calloc(1,sizeof(sizeof(opt.ForcedFlags[0]))); } if (opt.ClearedFlags==NULL) { opt.ClearedFlags=calloc(1,sizeof(sizeof(opt.ClearedFlags[0]))); } if (opt.OptDefault==NULL) { opt.OptMin=0; opt.OptMax=3; opt.OptDefault=calloc(1,sizeof(sizeof(opt.OptDefault[0]))); } if (opt.Command==NULL) { char *ExecName; ExecName=getenv("__GCC_OPT_COMPILER_EXEC"); if (ExecName==NULL) if (strchr(name,'>')==NULL) ExecName=name; else ExecName=strchr(name,'>')+1; opt.Command=splitOptions(ExecName); } if (opt.Prefix==NULL) { opt.Prefix=calloc(1,sizeof(sizeof(opt.Prefix[0]))); } return &opt; } /* Return non-zero if the two flags are the same flag... f1 is from * the config file, f2 is from the caller. */ int argMatch(const char *f1,const char *f2) { const char *p1,*p2; if (f1[0]!=f2[0] || f1[1]!=f2[1]) return 0; /* for -f args, strip off the '-f' and any 'no-' */ if (f1[1]=='f') { f1+=2; if (f1[0]=='n' && f1[1]=='o' && f1[2]=='-') f1+=3; f2+=2; if (f2[0]=='n' && f2[1]=='o' && f2[2]=='-') f2+=3; } /* for -m args, deal with -m64 and -m32, which affect -march=... * and -mtune=... * * sigh. */ if (f1[1]=='m') { if ((STREQ(f2,"-m64") || STREQ(f2,"-m32")) && (STREQN(f1,"-march=") || STREQN(f1,"-mtune="))) f1=f2; if ((STREQ(f1,"-m64") || STREQ(f1,"-m32")) && (STREQN(f2,"-march=") || STREQN(f2,"-mtune="))) f1=f2; } /* Are they args that take '='? Ignore anything after the = */ p1=strchr(f1,'='); p2=strchr(f2,'='); if ((p1==NULL) && (p2==NULL)) { return strcmp(f1,f2)==0; } else if ((p1 && p2 && (p1-f1 == p2-f2)) || (p2 && (p1==NULL) && strlen(f1)==(p2-f2))) { return strncmp(f1,f2,(p2-f2))==0; } else { return 0; } } /* Return -1 if arg deleted from argv, 0 otherwise. */ int processOneArg(char **argv,int n,struct options *opt) { int j; /* Do ClearedFlags first, so that we can clear specific options, * while having a default otherwise. */ for (j=0;opt->ClearedFlags[j]!=NULL; j++) { char *p=opt->ClearedFlags[j]; if (argMatch(p,argv[n])) { fprintf(stderr,"gcc-opt: Clearing %s\n",argv[n]); deleteArg(argv,n); return -1; } } for (j=0;opt->CompilerFlags[j]!=NULL; j++) { char *p=opt->CompilerFlags[j]; if (argMatch(p,argv[n])) { deleteArg(opt->CompilerFlags,j); j--; continue; } } for (j=0;opt->ForcedFlags[j]!=NULL; j++) { char *p=opt->ForcedFlags[j]; if (argMatch(p,argv[n])) { if (STRNEQ(p,argv[n])) fprintf(stderr,"gcc-opt: Overriding %s with %s\n",argv[n],p); deleteArg(argv,n); return -1; } } return 0; } /* Walk through the user-supplied arguments, forcing things, clearing things * and so forth. */ char ** processArgs(int argc, char **argv, struct options *opt) { char **MyArgv=malloc((argc+1)*sizeof(char*)); int i,j; char *p; int optSpecified=0; memcpy(MyArgv,argv,argc*sizeof(char*)); MyArgv[argc]=NULL; if (!(argc==2 && STREQ(MyArgv[1],"-v"))) { for (i=1; MyArgv[i]!=NULL; i++) { if (MyArgv[i][0]=='-') if (MyArgv[i][1]=='O') { char c=MyArgv[i][2]; int OptLevel; if (c=='s') OptLevel=2; else if (c=='\0') OptLevel=2; else OptLevel=atoi(MyArgv[i]+2); if (OptLevel>=opt->OptMin && OptLevel<=opt->OptMax) { optSpecified=1; } else { if (OptLevelOptMin) { char *s=malloc(10); sprintf(s,"-O%d",opt->OptMin); fprintf(stderr,"gcc-opt: forcing %s\n",s); MyArgv[i]=s; } else { char *s=malloc(10); sprintf(s,"-O%d",opt->OptMax); fprintf(stderr,"gcc-opt: forcing %s\n",s); MyArgv[i]=s; } } } else { i+=processOneArg(MyArgv,i,opt); } } if (!optSpecified) { MyArgv=insertArgs(MyArgv,1,opt->OptDefault); } MyArgv=insertArgs(MyArgv,1,opt->ForcedFlags); MyArgv=insertArgs(MyArgv,1,opt->CompilerFlags); } deleteArg(MyArgv,0); /* Lose their command */ MyArgv=insertArgs(MyArgv,0,opt->Command); /* insert our command */ MyArgv=insertArgs(MyArgv,0,opt->Prefix); /* insert our prefix */ return MyArgv; } int main(int argc, char *argv[]) { struct options *opt; char *ConfigFile; char *name; char *Package; char *p; char **e; if (p=getenv("__GCC_OPT_DEBUG")) { debug=strtol(p,NULL,0); } Package=getenv("__GCC_OPT_PACKAGE"); if (Package==NULL) { FILE *f=fopen("/CurrentlyBuilding","r"); if (f) { static char buf[300]; static char buf2[sizeof(buf)]; Package=fgets(buf,sizeof(buf)-1,f); if (Package && *Package) { if (Package[strlen(Package)-1]=='\n') { Package[strlen(Package)-1]='\0'; } else if (strlen(Package)==sizeof(buf)-2) { fprintf(stderr,"gcc-opt: warning: Package name truncated\n"); } if (sscanf(Package,"Package: %s",buf2) == 1) { Package=buf2; } } else { fprintf(stderr,"gcc-opt: /CurrentlyBuilding is empty\n"); Package=""; } fclose(f); } else { fprintf(stderr,"gcc-opt: Failed to open /CurrentlyBuilding\n"); Package=""; } } name=getenv("__GCC_OPT_COMPILER_NAME"); ConfigFile=getenv("__GCC_OPT_CONFIG_FILE"); if (ConfigFile==NULL) ConfigFile=CONFIG_FILE; name=getenv("__GCC_OPT_COMPILER_NAME"); if (name==NULL) name=COMPILER; opt=readOptions(name,ConfigFile,Package); argv=processArgs(argc,argv,opt); if (debug&DBG_PRINT_ARGS) { int i; for (i=0;argv[i];i++) { fprintf(stderr,"%d: \"%s\"\n",i,argv[i]); } } if (opt->Env!=NULL) { for (e=opt->Env; e!=NULL; e++) { if (**e=='-') { unsetenv(*e+1); } else { p=strchr(*e,'='); if (p==NULL) { fprintf(stderr,"gcc-opt: bad envvar: %s\n",*e); } else { *p++='\0'; setenv(*e,p,1); } } } } execv(argv[0],argv); perror("execv"); exit(1); }