bullet3/mk/jam/macosx.jam
res2002 ec56a978f7 Regenerated configure & VC projects.
Misc property fixes.
2006-06-17 18:23:38 +00:00

355 lines
12 KiB
Plaintext

#==============================================================================
# Jam configuration and actions for MacOS/X
# Copyright (C) 2003-2005 by Eric Sunshine <sunshine@sunshineco.com>
#
# 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.
#
#==============================================================================
SHELL ?= "/bin/sh" ;
MACOSX_ENVIRONMENT = "export MACOSX_DEPLOYMENT_TARGET=10.2" ;
PLUGIN.LFLAGS += "-bundle" ;
# We use the ugly -Wl form, which does not contain embedded whitespace (unlike
# "-framework AppKit"), to help external projects which use the result of
# "cs-config --libs" in conjunction with GNU libtool, since libtool likes to
# re-arrange arguments, not realizing that "-framwork" and "AppKit" need to
# stay together.
LINKLIBS += "-Wl,-framework,AppKit" "-Wl,-framework,Foundation" ;
# Jambase in Jam 2.4 has a bug where it incorrectly defines RANLIB as "" for
# MacOS/X, and this bogus value will override a RANLIB set via ?= in Jamconfig,
# by a configure script, thus we must give RANLIB an appropriate value here if
# we find that it has the bogus value. Jam 2.5 does not contain this bug.
# Furthermore, MacOS/X Panther expects us to use the -s option with ranlib.
if ! $(RANLIB) { RANLIB = "ranlib" ; }
RANLIB += "-s" ;
# Experience seems to indicate that library scanning misbehaves on MacOS/X with
# Jam 2.4, consequently we disable it.
NOARSCAN = true ;
#------------------------------------------------------------------------------
# Public rules.
#------------------------------------------------------------------------------
# ConstructApplicationTarget target : options
# Constructs the application target name.
rule ConstructApplicationTarget
{
return $(<) ;
}
# ConstructStaticLibraryTarget target : options
# Constructs the static library target name.
rule ConstructStaticLibraryTarget
{
return lib$(<)$(SUFLIB) ;
}
# ConstructSharedLibraryTarget target : options
# Constructs the shared library target name.
rule ConstructSharedLibraryTarget
{
return lib$(<).$(PACKAGE_VERSION).dylib ;
}
# ConstructSharedLibraryLinkLib target : options
# Constructs the name of a shared library against which some other target
# links.
rule ConstructSharedLibraryLinkLib
{
return lib$(<).$(PACKAGE_VERSION).dylib ;
}
# ConstructPluginTarget target : options
# Constructs the plugin target name.
rule ConstructPluginTarget
{
return $(<).csbundle ;
}
# SystemLinkApplication target : objects : options
# Apply appropriate rule to link the application based upon the options.
rule SystemLinkApplication
{
local target = $($(<)_TARGET) ;
Depends $(target) : $(>) ;
if [ IsElem console : $(3) ]
{
LinkApplicationConsole $(target) : $(>) ;
Clean clean : $(target) ;
Clean $(<)clean : $(target) ;
}
else
{
CreateApplicationWrapper $(target) : $(>) ;
CleanDir clean : [ Wrapper $(<) : app ] ;
CleanDir $(<)clean : [ Wrapper $(<) : app ] ;
}
}
# SystemInstallApplication target : subdirs : options
# Apply appropriate rule to install the application based upon the options.
rule SystemInstallApplication
{
if [ IsElem console : $(3) ]
{
Depends install_bin :
[ DoInstall $(<) : $(bindir) $(2) : $(INSTALL_PROGRAM) ] ;
}
else
{
InstallApplicationGUI $(<) : $(bindir) $(2) ;
}
}
# SystemInstallPlugin target : subdirs : options
# Apply appropriate rule to install the plugin based upon the options.
rule SystemInstallPlugin
{
Depends install_plugin :
[ DoInstall $(<) : $(plugindir) $(2) : $(INSTALL_PROGRAM) ] ;
}
# SystemLinkPlugin target : objects : options
# Link a plugin module and handle meta-data appropriately.
rule SystemLinkPlugin
{
local target = $($(<)_TARGET) ;
Depends $(target) : $(>) ;
LinkPlugin $(target) : $(>) ;
PluginMetaData $(<) : $($(<)_METAFILE) : $(3) ;
Clean clean : $(target) ;
Clean $(<)clean : $(target) ;
}
# LinkPlugin plugin : objects
# Link a plugin module from a set of object files.
actions LinkPlugin bind NEEDLIBS bind EXTRAOBJECTS
{
$(MACOSX_ENVIRONMENT)
$(CMD.LINK) -bundle -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LINKLIBS)
}
# LinkApplicationConsole exe : objects
# Link a console (non-GUI) appliation from a set of object files.
actions LinkApplicationConsole bind NEEDLIBS bind EXTRAOBJECTS
{
$(MACOSX_ENVIRONMENT)
$(CMD.LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LINKLIBS)
}
# CreateApplicationWrapper basename : objects
# Create a complete, though minimal, application wrapper given a set of
# object files. The rules ApplicationIconDefault and ApplicationIcon
# control the icon associated with the application wrapper.
rule CreateApplicationWrapper
{
WrapFile $(<) : $(<) : Contents MacOS : AppExe : $(>) ;
WrapFile $(<) : PkgInfo : Contents : AppPkgInfo : $(>) ;
WrapFile $(<) : version.plist : Contents : AppVersionPlist : $(>) ;
WrapFile $(<) : Info.plist : Contents : AppInfoPlist : $(>) ;
WrapFile $(<) : InfoPlist.strings : Contents Resources English.lproj :
AppInfoPlistStrings : $(>) ;
local icon = [ ApplicationIcon macosx : $(<) ] ;
if ! $(icon)
{
local apptype = gui ;
if [ IsElem console : $(>) ] { apptype = console ; }
icon = [ ApplicationIconDefault macosx : $(apptype) ] ;
}
if $(icon)
{
$(<)_APPICON = $(icon) ;
AppIcon $(<) : $(icon) ;
}
}
# Wrapper basename : suffix [ : pathcomponents ]
# Returns wrapper name in the directory specified by pathcomponents for
# the given basename. If pathcomponents is omitted, LOCATE.TARGETS is
# used.
rule Wrapper
{
local dir ;
if $(3) { dir = [ FDirName $(3) ] ; }
else { dir = $(LOCATE.TARGETS) ; }
return [ FDirName $(dir) $(1).$(2) ] ;
}
# WrapFile basename : file : pathcomponents : rule [ : objects : [ suffix ] ]
# Generate a file within a wrapper. pathcomponents is a list of names
# which compose the relative path within the wrapper where file should be
# placed. pathcomponents may be the empty list if the file should reside
# at the top-level of the wrapper. rule is rule/action which should be
# invoked to generate file. rule is invoked with arguments
# <basename.suffix/pathcomponents/file>, <objects>, and <basename>.
# objects is an optional list of files from which file should be built. It
# may be omitted if file does not depend upon any other files. suffix is
# the extension of the wrapper (not of file). If suffix is omitted, "app"
# is assumed.
#
# Implementation note: If basename and file are the same, then we do not
# grist file. (Obviously, we also do not want to set the file dependent
# upon itself.) The reason we do not grist file in this case is that the
# LinkWith, and LFlags rules associate the variables NEEDLIBS and
# LINKLIBS with the ungristed name, therefore in order to get access to
# these variables at AppExe action time, we must use the same (ungristed)
# name. It is otherwise impossible to gain access to those variables.
# This is an unfortunate hack which pollutes the otherwise general-purpose
# WrapFile rule.
rule WrapFile
{
local suffix ;
if $(6) { suffix = $(6) ; } else { suffix = app ; }
local target = $(2) ;
if $(target) != $(1)
{
target = $(target:G=$(1)) ;
Depends $(1) : $(target) ;
}
local dir = [ FDirName [ Wrapper $(1) : $(suffix) ] $(3) ] ;
MakeLocate $(target) : $(dir) ;
if $(5) { Depends $(target) : $(5) ; }
BASENAME on $(target) = $(1) ;
$(4) $(target) : $(5) : $(1) ;
Clean clean : [ FDirName $(dir) $(target) ] ;
Clean $(1)clean : [ FDirName $(dir) $(target) ] ;
}
# LinkApplication exe : objects
actions AppExe bind NEEDLIBS bind EXTRAOBJECTS
{
$(MACOSX_ENVIRONMENT)
$(CMD.LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LINKLIBS)
}
# AppPkgInfo file
actions AppPkgInfo
{
echo 'APPL????' > $(<) ;
}
# AppInfoPlistStrings file
actions AppInfoPlistStrings
{
cat << EOT > $(<)
CFBundleName = "$(BASENAME)";
CFBundleShortVersionString = "$(PACKAGE_VERSION)";
CFBundleGetInfoString = "$(BASENAME), $(PACKAGE_VERSION)";
EOT
}
# AppVersionPlist file
actions AppVersionPlist
{
cat << EOT > $(<)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>CFBundleShortVersionString</key>
<string>$(PACKAGE_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(PACKAGE_VERSION)</string>
<key>ProjectName</key>
<string>$(BASENAME)</string>
</dict>
</plist>
EOT
}
# AppInfoPlist filename : placeholder : basename
# Implementation Note: $(BASENAME)_APPICON might be empty in the actions of
# this rule, if the client did not specify a default icon or a
# target-specific icon, in which case we need to omit both the
# CFBundleIconFile key and value. To accomplish this, the key and value
# are placed on a single line with no intervening whitespace. When Jam
# interpolates a variable, if the variable is empty, it removes all
# adjacent text (the key and value, in this case) which is just what we
# desire.
actions AppInfoPlist
{
cat << EOT > $(<)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleName</key>
<string>$(BASENAME)</string>
<key>CFBundleExecutable</key>
<string>$(BASENAME)</string>
<key>CFBundleIconFile</key><string>$($(BASENAME)_APPICON)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0</string>
<key>CFBundleShortVersionString</key>
<string>$(PACKAGE_VERSION)</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
EOT
}
# AppIcon <basename> : <icon>
# Copy an icon into the wrapper. It is assumed that some other agent has
# already set SEARCH on the icon, if necessary.
rule AppIcon
{
local icon = $(>:G=$(<)) ;
Depends $(<) : $(icon) ;
Depends $(icon) : $(>) ;
MakeLocate $(icon) :
[ FDirName [ Wrapper $(<) : app ] Contents Resources ] ;
Copy $(icon) : $(>) ;
Clean clean : $(icon) ;
Clean $(<)clean : $(icon) ;
}
# InstallApplicationGUI app : installdirs
# Install a GUI application. Unlike applications on other platforms which
# exist as a single executable file, on MacOS/X, an application is wrapped
# in a directory hierarchy, thus a deep copy is needed (i.e. the typical
# Install rule does not work).
rule InstallApplicationGUI
{
local wrapper = $(<).app ;
Depends $(wrapper) : $(<) ;
SEARCH on $(wrapper) = $(LOCATE.TARGETS) ;
# Yuck! Internal knowledge of how DoInstall composes 'dir' and 'target'.
local dir = [ ConcatDirs $(DESTDIR) $(2) ] ;
local target = $(wrapper:BSR=$(dir):G=install) ;
InstallApplicationWrapperPrepare $(target) ;
Depends install_bin :
[ DoInstall $(wrapper) : $(2) : "$(DEEPCOPY)" ] ;
}
actions InstallApplicationWrapperPrepare
{
$(DELTREE) $(<) ;
}