#============================================================================
# Rules for compiling applications
# Copyright (C)2003 by Matze Braun <matzebraun@users.sourceforge.net>
#
#    This library is free software; you can redistribute it and/or modify it
#    under the terms of the GNU Library General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or (at your
#    option) any later version.
#
#    This library 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 Library General Public
#    License for more details.
#
#    You should have received a copy of the GNU Library General Public License
#    along with this library; if not, write to the Free Software Foundation,
#    Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#============================================================================

# Use a more sensible and typical mode for executables than Jam's default.
if "$(EXEMODE)" = "711" { EXEMODE = "+x" ; }

##  Application appname : sources [ : options ]
##    Build an application out of sourcefiles. All sourcefiles will be passed
##    to the Objects rule which tries to compile them into object-files. You
##    can create rules for your own filetypes with the UserObject rule. Header
##    files will just be ignored. They are only used for MSVC projectfile
##    generation.
##    Possible options are "noinstall" if you don't want a default install
##    target to be created and "console" if you're building a console
##    application (an application without any graphical output which is
##    intended to be used on commandline)
##    Some notes: You should not add the .exe extension to the appname - jam
##    will do that on win32.
##    Options:
##	console: Create a console application
##	noinstall: Do not set up a default installation targets.
##	independent: The target will not be made a dependency of the apps and
##		     all target.
##	nohelp: Do not invoke Help for this target.
##      notest: Do not set up unit-testing support for this target.
##	nomanifest: (Win32/MSVC) Don't generate manifest for application.
rule Application
{
  # check options
  CheckOptions noinstall console independent nohelp notest nomanifest : $(3) : $(<) ;

  local target = [ ConstructApplicationTarget $(<) : $(3) ] ;
  local sources = [ DoSourceGrist $(>) ] ;
  local objects = [ CompileObjects $(sources) ] ;

  $(<)_TYPE = application ;
  $(<)_OBJECTS = $(objects) ;
  $(<)_SOURCES = $(sources) ;
  $(<)_TARGET = $(target) ;

  # so 'jam foo' works when it's really foo.exe (Windows) or foo.app (MacOS/X)
  if $(target) != $(<)
  {
    Depends $(<) : $(target) ;
    NotFile $(<) ;
  }

  # make dependency on apps target
  if ! [ IsElem independent : $(3) ]
  {
    Depends apps : $(<) ;
  }

  # construct Install target
  if ! [ IsElem noinstall : $(3) ]
  {
    local install_opts ;
    if [ IsElem console : $(3) ]
    {
      install_opts += console ;
    }
    SystemInstallApplication $(target) : : $(install_opts) ;
  }

  # Link
  MakeLocate $(target) : $(LOCATE.TARGETS) ;
  SystemLinkApplication $(<) : $(objects) : $(3) ;

  local cleanextra ;
  if $(LINK.DEBUG.INFO.SEPARATE) = "yes"
  {
    local debugfile = [ SplitDebugInfo $(target) ] ;
    cleanextra += $(debugfile) ;
    if ! [ IsElem noinstall : $(3) ]
    {
      NoCare $(debugfile) ;
      Depends install_bin : [ DoInstall $(debugfile) : $(bindir) : $(INSTALL_DATA) ] ;
    }
  }

  CFlags $(<) : $(APPLICATION.CFLAGS) ;
  LFlags $(<) : $(LINKLIBS) $(APPLICATION.LFLAGS) ;      

  # create target clean rule
  Always $(<)clean ;
  NotFile $(<)clean ;
  Clean $(<)clean : $(objects) $(cleanextra) ;
  Clean clean : $(cleanextra) ;

  if ! [ IsElem nohelp : $(3) ]
  {
    local desc = [ Description $(<) ] ;
    if ! $(desc) { desc = "$(<) application" ; }
    Help $(<) : "Build the $(desc)" ;
  }

  if ! [ IsElem notest : $(options) ]
  {
    # @@@ Disabled for now; see docs/todo_jam.txt
    #UnitTest $(<) ;
  }
}

##  ShellScript scriptname : rule [ : options ]
##    Build a shell script by invoking `rule', the script creation rule, which
##    is passed `scriptname' and `options'.
##    Options:
##	noinstall: Do not set up a default installation target.
##	nohelp: Do not invoke Help for this target.
rule ShellScript
{
  CheckOptions noinstall nohelp : $(3) : $(<) ;

  Always $(<)clean ;
  NotFile $(<)clean ;
  Clean clean : $(<) ;
  Clean $(<)clean : $(<) ;
  Depends apps : $(<) ;
  MakeLocate $(<) : $(LOCATE.TARGETS) ;

  if ! [ IsElem noinstall : $(3) ]
  {
    Depends install_bin : [ DoInstall $(<) : $(bindir) : $(INSTALL_PROGRAM) ] ;
  }

  $(2) $(<) : $(3) ;

  MODE on $(<) = $(EXEMODE) ;
  SUBDIR on $(<) = $(SUBDIR) ;
  Chmod $(<) ;

  if ! [ IsElem nohelp : $(3) ]
  {
    local desc = [ Description $(<) ] ;
    if ! $(desc) { desc = "$(<) script" ; }
    Help $(<) : "Build the $(desc)" ;
  }
}

#----------------------------------------------------------------------------
# private part

# Construct pseudo target apps which is used instead of the pseudo target exe
# in Jambase
Depends exe : apps ;
NotFile apps ;
Help apps : "Build all applications" ;
