automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

C# support for automake


From: Bruno Haible
Subject: C# support for automake
Date: Mon, 5 Dec 2005 13:02:10 +0100
User-agent: KMail/1.5

Hi,

At least two GNU packages (gettext and libidn) now have parts of their
source code written in C#. Simon Josefsson, author of libidn, suggests
that C# support be added to automake. Let me here present the basic facts
about C# compilation, and a few macros and scripts that are in use in
GNU gettext for a few years and that make be useful in their solution.


The situation
=============

C# is a general-purpose programming language, and is basically a mix of
70% Java and 30% C++.

C# source files always have the extension ".cs".

Source files are often named hierarchically in correspondence to the
class(es) defined in the source files, i.e. class Foo.Bar.Baz could
be defined in Foo/Bar/Baz.cs. This convention is optional; some
programmers follow it, some don't.

The three main implementations of C# are:
  - The GNU pnet and pnetlib package.
  - Novell's mono package and its class library.
  - Microsoft's implementation.
The first two are open-source, share some of their code but are architected
with different goals: pnet is more GNU style, whereas mono is more complete
and more Microsoft-compatible. Microsoft's implementation is available in
different versions; one of them, called 'sscli', is available with source
code (but not open source). I believe that the other Microsoft implementations
are invoked in the same way as the sscli implementation.

For all implementations, C# source code has to be compiled into object code
libraries and object code executables, in order to be executable. The
names of the compilers are different, and their command line arguments
are different as well:

   Implementation | Compiler
   ---------------+---------
   pnet           | cscc
   mono           | mcs
   sscli          | csc

Executables are run via a launcher program, whose name is again different:

   Implementation | Executor
   ---------------+---------
   pnet           | ilrun
   mono           | mono
   sscli          | clix (don't know for non-sscli versions)

The object code generated from C# source code is platform-dependent.
Although most (or all?) of the file format of C# libraries and executables
is platform-independent, C# source code is processed by a preprocessor that
understands #if conditionals. For this reason we must consider that object
code generated for, say, x86_64, is different from object code generated for
i586.

Object code libraries are files with suffix ".dll". They are installed
under $prefix/lib.

Object code executables are files with suffix ".exe". There are two ways
to install them:
  a) Install the executable under $prefix/lib. Let the user invoke it through
     an explicit "ilrun $prefix/lib/foo.exe" or "mono $prefix/lib/foo.exe".
  b) Install the executable under $prefix/bin. Additionally install a one-line
     invocation script $prefix/bin/foo:
         #!/bin/sh
         exec mono $prefix/bin/foo.exe "$@"
I don't know which of these conventions should be preferred.

Things that are quite different from the C/C++ world:

- There are no object code files for individual source files. The mcs
  manual page makes this clear; it is probably also related to the fact
  that in C# 2.0, parts of the source code can be moved to separate .cs
  files.

- There is no equivalent for include files. All .cs files share equal rights.

- A second kind of source files, called resources, files ending in
  ".resources", can be embedded in object code libraries and executables.

- The compiler flags for different purposes (specifying optimization or
  debugging settings or lookup directories) differ between compilers.
  But a script "csharpcomp.sh" exists that provides a unified interface
  for the different compilers. (See below.)


Proposed syntax in Makefile.am files
====================================

How could a programmer declare his/her project's structure in a Makefile.am
file? I would propose that for a library foobar.dll that combines module1.cs,
module2.cs and libres.resources, the programmer would write

  ================================================================
  lib_LIBRARIES = foobar.dll
  foobar_dll_SOURCES = module1.cs module2.cs libres.resources
  ================================================================

and for an executable proggie.exe that combines main1.cs, main2.cs,
mainres.resources and foobar.dll, the programmer would write

  ================================================================
  bin_PROGRAMS = proggie.exe
  proggie_exe_SOURCES = main1.cs main2.cs mainres.resources
  proggie_exe_LDADD = -lfoobar
  ================================================================


Proposed macros and scripts
===========================

Automake should provide two macros that check for a C# compiler and
two that provide for a C# execution engines:
  AM_CSHARPCOMP for the compiler,
  AM_CSHARPEXEC for the execution engine,
  AM_CSHARPCOMP_OPTIONAL for the compiler, without aborting the configure
                         script if it is missing,
  AM_CSHARPEXEC_OPTIONAL for the execution engine, without aborting the
                         configure script if missing.
Normal projects would use AM_CSHARPCOMP, AM_CSHARPEXEC. For GNU gettext,
however, the C# part is optional (because C# is not widely available),
therefore it should be able to use the same logic for finding the C#
compiler and executor, but without an AC_FATAL call.

AM_CSHARPEXEC should check for the common mistake of installing pnet
without pnetlib. (Like with earlier versions of GCC, many people
installed g++ without a libstdc++ or libg++, leading to many stupid
bug reports to various package maintainers. This kind of thing needs
to be caught early in the configure script.)

Here are proposed implementations of these macros, derived from those
in GNU gettext and gnulib (already owned by the FSF).

==========================================================================
# Sets CSHARP_CHOICE to the preferred C# implementation:
# 'pnet' or 'mono' or 'any' or 'no'.
AC_DEFUN([AM_CSHARP_CHOICE],
[
  AC_MSG_CHECKING([for preferred C[#] implementation])
  AC_ARG_ENABLE(csharp,
    [  --enable-csharp[[=IMPL]]  choose preferred C[#] implementation (pnet or 
mono)],
    [CSHARP_CHOICE="$enableval"],
    CSHARP_CHOICE=any)
  AC_SUBST(CSHARP_CHOICE)
  AC_MSG_RESULT([$CSHARP_CHOICE])
  case "$CSHARP_CHOICE" in
    pnet)
      AC_DEFINE([CSHARP_CHOICE_PNET], 1,
        [Define if pnet is the preferred C# implementation.])
      ;;
    mono)
      AC_DEFINE([CSHARP_CHOICE_MONO], 1,
        [Define if mono is the preferred C# implementation.])
      ;;
  esac
])

# Prerequisites of csharpcomp.sh.
# Checks for a C# compiler.
# Sets at most one of HAVE_CSCC, HAVE_MCS, HAVE_CSC.
# Sets HAVE_CSHARPCOMP to nonempty if csharpcomp.sh will work.
# Also sets CSHARPCOMPFLAGS.
AC_DEFUN([AM_CSHARPCOMP_OPTIONAL],
[
  AC_REQUIRE([AM_CSHARP_CHOICE])
  AC_MSG_CHECKING([for C[#] compiler])
  HAVE_CSHARPCOMP=1
  pushdef([AC_MSG_CHECKING],[:])dnl
  pushdef([AC_CHECKING],[:])dnl
  pushdef([AC_MSG_RESULT],[:])dnl
  AC_CHECK_PROG(HAVE_CSCC_IN_PATH, cscc, yes)
  AC_CHECK_PROG(HAVE_MCS_IN_PATH, mcs, yes)
  AC_CHECK_PROG(HAVE_CSC_IN_PATH, csc, yes)
  popdef([AC_MSG_RESULT])dnl
  popdef([AC_CHECKING])dnl
  popdef([AC_MSG_CHECKING])dnl
  for impl in "$CSHARP_CHOICE" pnet mono sscli no; do
    case "$impl" in
      pnet)
        if test -n "$HAVE_CSCC_IN_PATH" \
           && cscc --version >/dev/null 2>/dev/null \
           && (
             # See if pnetlib is well installed.
             echo 'class ConfTest { static void Main() { } }' > conftest.cs
             cscc -o conftest.exe conftest.cs 2>/dev/null
             error=$?
             rm -f conftest.cs conftest.exe
             exit $error
            ); then
          HAVE_CSCC=1
          ac_result="cscc"
          break
        fi
        ;;
      mono)
        if test -n "$HAVE_MCS_IN_PATH" \
           && mcs --version >/dev/null 2>/dev/null; then
          HAVE_MCS=1
          ac_result="mcs"
          break
        fi
        ;;
      sscli)
        if test -n "$HAVE_CSC_IN_PATH" \
           && csc -help >/dev/null 2>/dev/null \
           && { if csc -help 2>/dev/null | grep -i chicken > /dev/null; then 
false; else true; fi; }; then
          HAVE_CSC=1
          ac_result="csc"
          break
        fi
        ;;
      no)
        HAVE_CSHARPCOMP=
        ac_result="no"
        break
        ;;
    esac
  done
  AC_MSG_RESULT([$ac_result])
  AC_SUBST(HAVE_CSCC)
  AC_SUBST(HAVE_MCS)
  AC_SUBST(HAVE_CSC)
  dnl Provide a default for CSHARPCOMPFLAGS.
  if test -z "${CSHARPCOMPFLAGS+set}"; then
    CSHARPCOMPFLAGS="-O -g"
  fi
  AC_SUBST(CSHARPCOMPFLAGS)
])

AC_DEFUN([AM_CSHARPCOMP],
[
  AC_REQUIRE([AM_CSHARPCOMP_OPTIONAL])
  if test -z "$HAVE_CSHARPCOMP"; then
    AC_FATAL([No C# compiler found.])
  fi
])

# Prerequisites of csharpexec.sh.
# Checks for a C# execution engine.
# AM_CSHARPEXEC or AM_CSHARPEXEC(testexecutable, its-directory)
# Sets at most one of HAVE_ILRUN, HAVE_MONO, HAVE_CLIX.
# Sets HAVE_CSHARPEXEC to nonempty if csharpexec.sh will work.
AC_DEFUN([AM_CSHARPEXEC_OPTIONAL],
[
  AC_REQUIRE([AM_CSHARP_CHOICE])
  AC_REQUIRE([AC_CANONICAL_HOST])
  AC_MSG_CHECKING([for C[#] program execution engine])
  AC_EGREP_CPP(yes, [
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
  yes
#endif
], MONO_PATH_SEPARATOR=';', MONO_PATH_SEPARATOR=':')
  HAVE_CSHARPEXEC=1
  pushdef([AC_MSG_CHECKING],[:])dnl
  pushdef([AC_CHECKING],[:])dnl
  pushdef([AC_MSG_RESULT],[:])dnl
  AC_CHECK_PROG(HAVE_ILRUN_IN_PATH, ilrun, yes)
  AC_CHECK_PROG(HAVE_MONO_IN_PATH, mono, yes)
  AC_CHECK_PROG(HAVE_CLIX_IN_PATH, clix, yes)
  popdef([AC_MSG_RESULT])dnl
  popdef([AC_CHECKING])dnl
  popdef([AC_MSG_CHECKING])dnl
  for impl in "$CSHARP_CHOICE" pnet mono sscli no; do
    case "$impl" in
      pnet)
        if test -n "$HAVE_ILRUN_IN_PATH" \
           && ilrun --version >/dev/null 2>/dev/null \
           ifelse([$1], , , [&& ilrun $2/$1 >/dev/null 2>/dev/null]); then
          HAVE_ILRUN=1
          ac_result="ilrun"
          break
        fi
        ;;
      mono)
        if test -n "$HAVE_MONO_IN_PATH" \
           && mono --version >/dev/null 2>/dev/null \
           ifelse([$1], , , [&& mono $2/$1 >/dev/null 2>/dev/null]); then
          HAVE_MONO=1
          ac_result="mono"
          break
        fi
        ;;
      sscli)
        if test -n "$HAVE_CLIX_IN_PATH" \
           ifelse([$1], , , [&& clix $2/$1 >/dev/null 2>/dev/null]); then
          HAVE_CLIX=1
          case $host_os in
            cygwin* | mingw* | pw32*)
              CLIX_PATH_VAR=PATH
              ;;
            darwin* | rhapsody*)
              CLIX_PATH_VAR=DYLD_LIBRARY_PATH
              ;;
            *)
              CLIX_PATH_VAR=LD_LIBRARY_PATH
              ;;
          esac
          eval CLIX_PATH=\"\$CLIX_PATH_VAR\"
          ac_result="clix"
          break
        fi
        ;;
      no)
        HAVE_CSHARPEXEC=
        ac_result="no"
        break
        ;;
    esac
  done
  AC_MSG_RESULT([$ac_result])
  AC_SUBST(MONO_PATH)
  AC_SUBST(MONO_PATH_SEPARATOR)
  AC_SUBST(CLIX_PATH_VAR)
  AC_SUBST(CLIX_PATH)
  AC_SUBST(HAVE_ILRUN)
  AC_SUBST(HAVE_MONO)
  AC_SUBST(HAVE_CLIX)
])

AC_DEFUN([AM_CSHARPEXEC],
[
  AM_CSHARPEXEC_OPTIONAL([$1],[$2])
  if test -z "$HAVE_CSHARPEXEC"; then
    AC_FATAL([No C# execution engine found.])
  fi
])
==========================================================================

The test executable serves to protect against incomplete pnet installations;
I suggest to take the trivial csharpexec-test.exe from GNU gettext and
install that in the aux-dir.

Here is the compiler wrapper:

====================== build-aux/csharpcomp.sh.in ======================
#!/bin/sh
# Compile a C# program.

# Copyright (C) 2003-2005 Free Software Foundation, Inc.
# Written by Bruno Haible <address@hidden>, 2003.
#
# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# This uses the same choices as csharpcomp.c, but instead of relying on the
# environment settings at run time, it uses the environment variables
# present at configuration time.
#
# This is a separate shell script, because the various C# compilers have
# different command line options.
#
# Usage: /bin/sh csharpcomp.sh [OPTION] SOURCE.cs ... RES.resources ...
# Options:
#   -o PROGRAM.exe  or  -o LIBRARY.dll
#                     set the output assembly name
#   -L DIRECTORY      search for C# libraries also in DIRECTORY
#   -l LIBRARY        reference the C# library LIBRARY.dll
#   -O                optimize
#   -g                generate debugging information

# func_tmpdir
# creates a temporary directory.
# Sets variable
# - tmp             pathname of freshly created temporary directory
func_tmpdir ()
{
  # Use the environment variable TMPDIR, falling back to /tmp. This allows
  # users to specify a different temporary directory, for example, if their
  # /tmp is filled up or too small.
  : ${TMPDIR=/tmp}
  {
    # Use the mktemp program if available. If not available, hide the error
    # message.
    tmp=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
    test -n "$tmp" && test -d "$tmp"
  } ||
  {
    # Use a simple mkdir command. It is guaranteed to fail if the directory
    # already exists.  $RANDOM is bash specific and expands to empty in shells
    # other than bash, ksh and zsh.  Its use does not increase security;
    # rather, it minimizes the probability of failure in a very cluttered /tmp
    # directory.
    tmp=$TMPDIR/gt$$-$RANDOM
    (umask 077 && mkdir "$tmp")
  } ||
  {
    echo "$0: cannot create a temporary directory in $TMPDIR" >&2
    { (exit 1); exit 1; }
  }
}

sed_quote_subst='s/\([|&;<>()$`"'"'"'*?[#~=%    \\]\)/\\\1/g'
options_cscc=
options_mcs=
options_csc="-nologo"
sources=
while test $# != 0; do
  case "$1" in
    -o)
      case "$2" in
        *.dll)
          options_cscc="$options_cscc -shared"
          options_mcs="$options_mcs -target:library"
          options_csc="$options_csc -target:library"
          ;;
        *.exe)
          options_csc="$options_csc -target:exe"
          ;;
      esac
      options_cscc="$options_cscc -o "`echo "$2" | sed -e "$sed_quote_subst"`
      options_mcs="$options_mcs -o "`echo "$2" | sed -e "$sed_quote_subst"`
      options_csc="$options_csc -out:"`echo "$2" | sed -e "$sed_quote_subst"`
      shift
      ;;
    -L)
      options_cscc="$options_cscc -L "`echo "$2" | sed -e "$sed_quote_subst"`
      options_mcs="$options_mcs -L "`echo "$2" | sed -e "$sed_quote_subst"`
      options_csc="$options_csc -lib:"`echo "$2" | sed -e "$sed_quote_subst"`
      shift
      ;;
    -l)
      options_cscc="$options_cscc -l "`echo "$2" | sed -e "$sed_quote_subst"`
      options_mcs="$options_mcs -r "`echo "$2" | sed -e "$sed_quote_subst"`
      options_csc="$options_csc -reference:"`echo "$2" | sed -e 
"$sed_quote_subst"`".dll"
      shift
      ;;
    -O)
      options_cscc="$options_cscc -O"
      options_csc="$options_csc -optimize+"
      ;;
    -g)
      options_cscc="$options_cscc -g"
      options_mcs="$options_mcs -g"
      options_csc="$options_csc -debug+"
      ;;
    -*)
      echo "csharpcomp: unknown option '$1'" 1>&2
      exit 1
      ;;
    *.resources)
      options_cscc="$options_cscc -fresources="`echo "$1" | sed -e 
"$sed_quote_subst"`
      options_mcs="$options_mcs -resource:"`echo "$1" | sed -e 
"$sed_quote_subst"`
      options_csc="$options_csc -resource:"`echo "$1" | sed -e 
"$sed_quote_subst"`
      ;;
    *.cs)
      sources="$sources "`echo "$1" | sed -e "$sed_quote_subst"`
      ;;
    *)
      echo "csharpcomp: unknown type of argument '$1'" 1>&2
      exit 1
      ;;
  esac
  shift
done

if test -n "@HAVE_CSCC@"; then
  test -z "$CSHARP_VERBOSE" || echo cscc $options_cscc $sources
  exec cscc $options_cscc $sources
else
  if test -n "@HAVE_MCS@"; then
    # mcs prints its errors and warnings to stdout, not stderr. Furthermore it
    # adds a useless line "Compilation succeeded..." at the end. Correct both.
    sed_drop_success_line='${
/^Compilation succeeded/d
}'
    func_tmpdir
    trap 'rm -rf "$tmp"' 1 2 3 15
    test -z "$CSHARP_VERBOSE" || echo mcs $options_mcs $sources
    mcs $options_mcs $sources > "$tmp"/mcs.err
    result=$?
    sed -e "$sed_drop_success_line" < "$tmp"/mcs.err >&2
    rm -rf "$tmp"
    exit $result
  else
    if test -n "@HAVE_CSC@"; then
      test -z "$CSHARP_VERBOSE" || echo csc $options_csc $sources
      exec csc $options_csc $sources
    else
      echo 'C# compiler not found, try installing pnet, then reconfigure' 1>&2
      exit 1
    fi
  fi
fi
===========================================================================

Here is the execution engine wrapper.

====================== build-aux/csharpexec.sh.in ======================
#!/bin/sh
# Execute a C# program.

# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
# Written by Bruno Haible <address@hidden>, 2003.
#
# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# This uses the same choices as csharpexec.c, but instead of relying on the
# environment settings at run time, it uses the environment variables
# present at configuration time.
#
# This is a separate shell script, because the various C# interpreters have
# different command line options.
#
# Usage: /bin/sh csharpexec.sh [OPTION] program.exe [ARGUMENTS]
# Options:
#   -L DIRECTORY      search for C# libraries also in DIRECTORY

sed_quote_subst='s/\([|&;<>()$`"'"'"'*?[#~=%    \\]\)/\\\1/g'
options_ilrun=
libdirs_mono=
prog=
while test $# != 0; do
  case "$1" in
    -L)
      options_ilrun="$options_ilrun -L "`echo "$2" | sed -e "$sed_quote_subst"`
      libdirs_mono="${libdirs_mono:address@hidden@}$2"
      shift
      ;;
    -*)
      echo "csharpexec: unknown option '$1'" 1>&2
      exit 1
      ;;
    *)
      prog="$1"
      break
      ;;
  esac
  shift
done
if test -z "$prog"; then
  echo "csharpexec: no program specified" 1>&2
  exit 1
fi
case "$prog" in
  *.exe) ;;
  *)
    echo "csharpexec: program is not a .exe" 1>&2
    exit 1
    ;;
esac

if test -n "@HAVE_ILRUN@"; then
  test -z "$CSHARP_VERBOSE" || echo ilrun $options_ilrun "$@"
  exec ilrun $options_ilrun "$@"
else
  if test -n "@HAVE_MONO@"; then
    CONF_MONO_PATH='@MONO_PATH@'
    if test -n "$libdirs_mono"; then
      MONO_PATH="$libdirs_mono${CONF_MONO_PATH:address@hidden@$CONF_MONO_PATH}"
    else
      MONO_PATH="$CONF_MONO_PATH"
    fi
    export MONO_PATH
    test -z "$CSHARP_VERBOSE" || echo mono "$@"
    exec mono "$@"
  else
    if test -n "@HAVE_CLIX@"; then
      CONF_CLIX_PATH='@CLIX_PATH@'
      if test -n "$libdirs_mono"; then
        
@address@hidden"$libdirs_mono${CONF_CLIX_PATH:address@hidden@$CONF_CLIX_PATH}"
      else
        @address@hidden"$CONF_CLIX_PATH"
      fi
      export @CLIX_PATH_VAR@
      test -z "$CSHARP_VERBOSE" || echo clix "$@"
      exec clix "$@"
    else
      echo 'C# virtual machine not found, try installing pnet, then 
reconfigure' 1>&2
      exit 1
    fi
  fi
fi
===========================================================================


Proposed actions in Makefile.in
===============================

Let's go back to the sample Makefile.am from above:

  ================================================================
  lib_LIBRARIES = foobar.dll
  foobar_dll_SOURCES = module1.cs module2.cs libres.resources

  bin_PROGRAMS = proggie.exe
  proggie_exe_SOURCES = main1.cs main2.cs mainres.resources
  proggie_exe_LDADD = -lfoobar
  ================================================================

What actions should automake put into the appropriate Makefile.in targets?

0) Generally: A variable CSHARPCOMP should be defined:

      CSHARPCOMP = $(SHELL) $(top_builddir)/csharpcomp.sh

   Also, a variable CSHARPCOMPFLAGS should be defined, with default value
   "-O -g".

      CSHARPCOMPFLAGS = @CSHARPCOMPFLAGS@

1) For the library:
  - Target "all" should depend on foobar.dll.
  - A target foobar.dll should be added:

      foobar.dll : module1.cs module2.cs libres.resources
               $(CSHARPCOMP) $(CSHARPCOMPFLAGS) -o $@ $(srcdir)/module1.cs 
$(srcdir)/module2.cs $(srcdir)/libres.resources

  - Target "clean" should remove foobar.dll.
  - Target "install" should install foobar.dll into $(libdir), using
    $(INSTALL_DATA).
  - Target "uninstall" and "installdirs" accordingly.

2) For the executable.
  - Target "all" should depend on proggie.exe.
  - A target "proggie.exe" should be added:

      proggie.exe : main1.cs main2.cs mainres.resources foobar.dll
               $(CSHARPCOMP) $(CSHARPCOMPFLAGS) -o $@ $(srcdir)/main1.cs 
$(srcdir)/main2.cs $(srcdir)/mainres.resources -lfoobar
  - Target "clean" should remove proggie.exe.
  - Target "install" should install proggie.exe into $(bindir), using
    $(INSTALL_DATA). (Not using $(INSTALL_PROGRAM), because INSTALL_PROGRAM
    sometimes contains an "-s" options, instructing 'install' to invoke
    'strip' - which does not make sense here.)
    Optionally (or always?), on platforms where $EXEEXT is not ".exe",
    also install a script 'foobar' into the same directory, using
    $(INSTALL_SCRIPT), that invokes proggie.exe via the interpreter found
    by AM_CSHARPEXEC_OPTIONAL.

What actions could "automake" perform?
  - If it has rules that need $(CSHARPCOMP) and $(CSHARPCOMPFLAGS), it should
    verify that configure.ac directly or indirectly invokes
    AM_CSHARPCOMP_OPTIONAL.
  - If it has rules that use $(CSHARPEXEC), it should verify that
    configure.ac directly or indirectly invokes AM_CSHARPEXEC_OPTIONAL.
  - If configure.ac directly or indirectly uses AM_CSHARPCOMP_OPTIONAL, it
    installs csharpcomp.sh.in in the aux-dir, and verifies that a
    AC_CONFIG_FILES([build-aux/csharpcomp.sh:csharpcomp.sh]) setting exists.
  - If configure.ac directly or indirectly uses AM_CSHARPEXEC_OPTIONAL, it
    install csharpexec.sh.in in the aux-dir, and verifies that a
    AC_CONFIG_FILES([build-aux/csharpexec.sh:csharpexec.sh]) setting exists.

Bruno





reply via email to

[Prev in Thread] Current Thread [Next in Thread]