[Mono-list] Re: [DotGNU]C# compiler command line parsing

Rhys Weatherley rweather@zip.com.au
Thu, 28 Mar 2002 19:31:42 +1000


This is a multi-part message in MIME format.
--------------B15878C6D882B391DB5D5641
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Fergus Henderson wrote:

> One way to do this would be to just add support for Microsoft's
> command-line interface to the .NET and Mono C# compilers.  Another way
> to do it would be to define a Unix-like command-line syntax, and write
> a wrapper for Microsoft's csc that would convert the Unix-like syntax
> into Microsoft's syntax and then invoke csc.  Software written in C#
> could ship with this wrapper program included.

Portable.NET's C# compiler already uses the gcc syntax.
Attached is a script I wrote to wrap up "csc" and give it
the same gcc-like syntax, so as to improve interoperability.

Microsoft's syntax does not fit into a Unix environment very
well, because it uses '/' as a switch character.  I don't see
why we should dumb down our compilers, when a shell script
can be used to smarten up Microsoft's.

The only drawback with the script is that it only works in
Cygwin and Unix environments.  It doesn't work at the
raw Windows command prompt.  That could be easily fixed
by re-implementing the script in C or C#.

As another option, Portable.NET's "csant" tool, which is
a C-only variant of NAnt, supports csc, mcs, and cscc
syntax transparently.  The XML file describes what needs
to be compiled, and "csant" converts it into the correct
conventions depending upon which compiler has been
configured.  Environment variables or command-line
options are used to specify which compiler to use.

Cheers,

Rhys.


--------------B15878C6D882B391DB5D5641
Content-Type: application/x-sh;
 name="mscsc.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="mscsc.sh"

#! /bin/sh
#
# mscsc.sh - Wrapper around Microsoft's CSC.EXE to give it a more
#            cscc-like command-line syntax.
#
# Copyright (C) 2001  Southern Storm Software, Pty Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Get the name of the compiler to invoke.
if test -z "$1" ; then
	echo "Usage: $0 csc [options] inputfiles" 1>&2
	exit 1
fi
PROGNAME="$0"
CSC="$1"
shift

# Parse the command-line options.
FLAGS="/nologo"
FILES=""
NEEDARG=""
DEFINES=""
LIBDIRS=""
LIBRARIES=""
RESOURCES=""
for i in $*; do
	if test -z "$NEEDARG" ; then
		case "$i" in
			-nostdlib)				FLAGS="$FLAGS /nostdlib" ;;
			-g)						FLAGS="$FLAGS /debug+" ;;
			-O|-O2|-O3)				FLAGS="$FLAGS /optimize+" ;;
			-O0)					FLAGS="$FLAGS /optimize-" ;;
			-o)						NEEDARG="o" ;;
			-c|-S|-E|-v|-vv)		;;
			-Werror)				FLAGS="$FLAGS /warnaserror+" ;;
			-Wall)					FLAGS="$FLAGS /warn:4" ;;
			-Wno-dll-import)		FLAGS="$FLAGS /nowarn:626" ;;
			-Wno-field-assign)		FLAGS="$FLAGS /nowarn:649" ;;
			-Wno-event-unused)		FLAGS="$FLAGS /nowarn:67" ;;
			-fsyntax-check)			;; #FLAGS="$FLAGS /nooutput" ;;
			-fchecked)				FLAGS="$FLAGS /checked+" ;;
			-funchecked)			FLAGS="$FLAGS /checked-" ;;
			-fincremental)			FLAGS="$FLAGS /incremental" ;;
			-funsafe)				FLAGS="$FLAGS /unsafe" ;;
			-fresources=)
				 RESOURCES=`expr "$i" : '-fresources=\(.*\)$'` ;;
			-e)						NEEDARG="e" ;;
			-I*|-f*|-W*)			;;
			-D*) if test -z "$DEFINES" ; then
					DEFINES=`expr "$i" : '-D\(.*\)$'`
				 else
				 	DEFINES="$DEFINES;"`expr "$i" : '-D\(.*\)$'`
				 fi ;;
			-L*) LIBDIRS="$LIBDIRS "`expr "$i" : '-L\(.*\)$'` ;;
			-l*) LIBRARIES="$LIBRARIES "`expr "$i" : '-l\(.*\)$'` ;;
			-*)	 echo "${PROGNAME}: unknown option $i" 1>&2
				 exit 1 ;;
			 *)	 FILES="$FILES $i" ;;
		esac
	else
		case "$NEEDARG" in
			o)	case "$i" in
					*.dll) FLAGS="$FLAGS /target:library" ;;
					*.exe) FLAGS="$FLAGS /target:exe" ;;
					    *) FLAGS="$FLAGS /target:module" ;;
				esac
				FLAGS="$FLAGS /out:$i" ;;
			e)	FLAGS="$FLAGS /main:$i" ;;
			*)	;;
		esac
		NEEDARG=""
	fi
done

# Add extra flags as necessary.
if test -n "$DEFINES" ; then
	FLAGS="$FLAGS /define:$DEFINES"
fi
if test -n "$LIBRARIES" -a -n "$LIBDIRS" ; then
	REFS=""
	for lib in $LIBRARIES; do
		for dir in $LIBDIRS; do
			if test -f "${dir}/${lib}.dll" ; then
				if test -z "$REFS" ; then
					REFS="${dir}/${lib}.dll"
				else
					REFS="$REFS;${dir}/${lib}.dll"
				fi
			fi
		done
	done
	if test -n "$REFS" ; then
		FLAGS="$FLAGS /reference:"`echo "$REFS" | sed -e '1,$s%/%\\\\%g' -`
	fi

fi
if test -n "$RESOURCES" ; then
	FLAGS="$FLAGS /resource:"`echo "$RESOURCES" | sed -e '1,$s%/%\\\\%g' -`
fi

# Convert forward slashes in the filenames into backslashes
# so that CSC.EXE doesn't try to treat the names as options.
FILES=`echo "$FILES" | sed -e '1,$s%/%\\\\%g' -`

# Execute the compiler.
echo "$CSC" $FLAGS $FILES
exec "$CSC" $FLAGS $FILES

--------------B15878C6D882B391DB5D5641--