mirror of
https://github.com/bulletphysics/bullet3
synced 2025-01-10 17:30:12 +00:00
1559 lines
47 KiB
Plaintext
1559 lines
47 KiB
Plaintext
#==============================================================================
|
|
# Rules for creating MSVC project files.
|
|
# Copyright (C) 2004 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.
|
|
#
|
|
#==============================================================================
|
|
#
|
|
# During a project file synthesis run, the property name 'projgen' in the
|
|
# container 'build' will be given a value describing which type of project
|
|
# files are being generated. For MSVC project files, the value of the 'projgen'
|
|
# property will be "msvc". When project file synthesis supports multiple tool
|
|
# versions, the 'projgen_version' property will have a value indicating the
|
|
# version of the tool for which project files are being created. For instance,
|
|
# when generating MSVC7 project files, 'projgen' will be set to "msvc" and
|
|
# 'projgen_version' will have the value "7".
|
|
#
|
|
# Jamfiles throughout the project, if they need to alter their behavior (for
|
|
# one reason or another), can invoke the Property rule to determine whether
|
|
# project files are being synthesized. For example, to learn if project file
|
|
# synthesis is active:
|
|
#
|
|
# if [ Property build : projgen ] { ... do something ... }
|
|
#
|
|
# To take action if only a particular type of project file is being generated
|
|
# (i.e. "msvc"):
|
|
#
|
|
# if [ Property build : projgen ] = msvc { ... do something ... }
|
|
#
|
|
#==============================================================================
|
|
|
|
MSVCGEN_SUPPORTED_VERSIONS = 6 7 71 8 sn71 xenon8 ;
|
|
MSVCGEN_BUILD_ROOT ?= [ ConcatDirs $(BUILDTOP) out ] ;
|
|
MSVCGEN_BUILD_TEMP ?= [ ConcatDirs $(MSVCGEN_BUILD_ROOT) msvcgen ] ;
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Public rule stubs. May be implemented by msvcgen phase 1 or phase 2 or both.
|
|
|
|
## MsvcGenConfig variable [ : value ]
|
|
## Specify additional configuration information to augment the msvcgen
|
|
## environment. The Jam variable named by 'variable' is set to 'value' for
|
|
## the msvcgen run. If 'value' is omitted, then 'variable' is cleared.
|
|
## Invocations of MsvcGenConfig are cumulative, so variable/value tuples can
|
|
## be provided incrementally. It is legal to use this rule in conjunction
|
|
## with MsvcGenConfigFile; they are not mutually exclusive.
|
|
##
|
|
## The most common reason to invoke this rule is to provide MSVC-specific
|
|
## fallback values for the library checks typically performed by an Autoconf
|
|
## configure script, which the Jamfiles reference via the ExternalLibs rule.
|
|
## Such fallbacks consist of variables named TAG.CFLAGS, TAG.LFLAGS, and
|
|
## TAG.LIBS, where TAG represents the library's identifier exported by the
|
|
## configure script. Because project generation allows for finer-grained
|
|
## control, you can also optionally set the variables TAG.DEFINES,
|
|
## TAG.INCDIRS, and TAG.LIBDIRS. TAG.DEFINES is a set of tokens of the form
|
|
## "key" or "key=value". For instance, to provide MSVC-specific fallback
|
|
## values for the FreeType2 library, which the configure script might
|
|
## identify as FT2, you can define variables named FT2.CFLAGS, FT2.LFLAGS,
|
|
## FT2.LIBS, FT2.DEFINES, FT2.INCDIRS, and FT2.LIBDIRS. The msvcgen process
|
|
## will consult these variables when it encounters invocations of the
|
|
## ExternalLibs rule, and apply the overrides to the generated project files.
|
|
## If yours is a multi-platform project which conditionally defines
|
|
## Application, Plugin, and Library targets based upon the platform, then you
|
|
## should also define whatever additional variables or properties are needed
|
|
## to ensure that your project's Jamfiles invoke the Application, Plugin, and
|
|
## Library rules for modules suitable for Windows, and that they do not
|
|
## invoke those rules for modules specific to other platforms.
|
|
rule MsvcGenConfig { MsvcGenConfig1 $(1) : $(2) ; }
|
|
rule MsvcGenConfig1 { }
|
|
|
|
## MsvcGenConfigFile file
|
|
## Similar to MsvcGenConfig, except that the configuration is provided via a
|
|
## file containing Jam statements. In the common case, the file will contain
|
|
## a series of simple Jam variable assignment statements. May be invoked
|
|
## multiple times to specify additional configuration files. It is legal to
|
|
## use this rule in conjunction with MsvcGenConfig; they are not mutually
|
|
## exclusive.
|
|
rule MsvcGenConfigFile { MsvcGenConfigFile1 $(1) : $(2) ; }
|
|
rule MsvcGenConfigFile1 { }
|
|
|
|
## MsvcGenVariable variable [ : value ]
|
|
## Define a variable for direct interpolation into msvcgen template files.
|
|
## 'variable' is the name of the variable to define. 'value' is the value
|
|
## which should be assigned to 'variable'. If 'value' is omitted, then
|
|
## 'variable' is defined as the null (empty) string. You may invoke this
|
|
## rule multiple times to define any number of interpolation variables. You
|
|
## may also invoke it multiple times for the same variable name to give the
|
|
## variable multiple values. In the template file, reference the variable as
|
|
## `[% variable.0 %]' to retrieve the first element, `[% variable.1 %]' to
|
|
## retrieve the second, and so on. Even if you have only invoked this rule
|
|
## once for a variable, you must still reference it in the template as
|
|
## `[% variable.0 %]'. If the variable has multiple values, then it is common
|
|
## to reference it in the template via a FOREACH loop, as in
|
|
## `[% FOREACH v IN variable %]'.
|
|
rule MsvcGenVariable { MsvcGenVariable1 $(1) : $(2) ; }
|
|
rule MsvcGenVariable1 { }
|
|
|
|
## MsvcGenWorkspace name [ : accepts [ : rejects ]]
|
|
## Specify the name of a workspace which the 'msvcgen' target should create.
|
|
## The generated workspace file name will be prefixed by "wks". By default,
|
|
## a workspace contains all projects resulting from invocations of the
|
|
## Application, Plugin, Library, and CompileGroups rules. It is possible to
|
|
## restrict the projects placed into the workspace by providing the optional
|
|
## 'accepts' and/or 'rejects'. These are lists of Perl regular expressions
|
|
## matched against the project names. (Project names are composed of "app",
|
|
## "plg", "lib", and "grp" prepended to the target name given to the
|
|
## Application, Plugin, Library, and CompileGroups rules, respectively.)
|
|
## Reject patterns take precedence over accept patterns. This rule must be
|
|
## invoked before any invocations of Application, Plugin, Library, or
|
|
## CompileGroups. You may invoke this rule multiple times to produce
|
|
## multiple workspaces, but you must invoke it at least once in order for the
|
|
## 'msvcgen' target to produce any output.
|
|
rule MsvcGenWorkspace { MsvcGenWorkspace1 $(1) : $(2) : $(3) ; }
|
|
rule MsvcGenWorkspace1 { }
|
|
|
|
## MsvcGenSubDir dircomponents [ : version ]
|
|
## Invoke this rule with the location of the project file directory as a
|
|
## whitepace-delimited set of tokens, much as you would the SubDir rule.
|
|
## This information is used in two ways. (1) The directory structure for the
|
|
## generated files will be duplicated under $(MSVCGEN_BUILD_ROOT). For
|
|
## instance, if your project files are at "$(TOP)/proj/msvc", then the
|
|
## generated files will be deposited at "$(MSVCGEN_BUILD_ROOT)/proj/msvc".
|
|
## (2) The depth of the directory indicated by 'dircomponents' will be taken
|
|
## into account when generating references to resources in your project tree.
|
|
## For example, if your project files reside at "$(TOP)/proj/msvc", and you
|
|
## have set "$(TOP)/resources/game.ico" as the application icon with the
|
|
## ApplicationIconDefault or ApplicationIcon rule, then msvcgen will know
|
|
## that game.ico can be found relative to the project file directory via the
|
|
## path "../../resources/game.ico". If 'version' is specified, then
|
|
## 'dircomponents' applies to generated files for that version of MSVC only.
|
|
## If 'version' is not specified, then the path will be composed of
|
|
## 'dircomponents' and the version number. For instance, if 'dircomponents'
|
|
## is "$(TOP)/proj/msvc" and 'version' was not provided, then it will be
|
|
## assumed that MSVC7 project files should reside at $(TOP)/proj/msvc7". You
|
|
## must invoke this rule at least once to ensure that 'msvcgen' targets are
|
|
## made available for user invocation.
|
|
rule MsvcGenSubDir { msvcgen_path_version MsvcGenSubDir1 : $(1) : $(2) ; }
|
|
rule MsvcGenSubDir1 { }
|
|
|
|
## MsvcGenTemplateDir dircomponents
|
|
## Invoke this rule with the location of the msvcgen template directory as a
|
|
## whitepace-delimited set of tokens.
|
|
rule MsvcGenTemplateDir { MsvcGenTemplateDir1 $(1) ; }
|
|
rule MsvcGenTemplateDir1 { }
|
|
|
|
## MsvcExternalLibrary target [ : libs [ : mode ]]
|
|
## Invoke this rule to link 'target' with one or more MSVC-specific external
|
|
## libraries. For example, 'libs' might be "wsock32.lib". 'mode' should be
|
|
## "release" or "debug". If 'mode' is omitted, then 'libs' is used for
|
|
## release and debug.
|
|
rule MsvcExternalLibrary { MsvcExternalLibrary1 $(1) : $(2) : $(3) ; }
|
|
rule MsvcExternalLibrary1 { }
|
|
|
|
## MsvcDefine target [ : key [ : value [ : mode ]]]
|
|
## Invoke this rule to define an MSVC-specific preprocessor macro 'key'
|
|
## having 'value' for 'target'. 'mode' should be "release" or "debug". If
|
|
## 'mode' is omitted, then 'key/value' is used for release and debug.
|
|
rule MsvcDefine { MsvcDefine1 $(1) : $(2) : $(3) : $(4) ; }
|
|
rule MsvcDefine1 { }
|
|
|
|
## MsvcIncDirs target : directories [ : mode ]
|
|
## Invoke this rule to define an MSVC-specific additional include directories.
|
|
## 'mode' should be "release" or "debug". If 'mode' is omitted, then
|
|
## 'directories' is used for release and debug.
|
|
rule MsvcIncDirs { MsvcIncDirs1 $(1) : $(2) : $(3) ; }
|
|
rule MsvcIncDirs1 { }
|
|
|
|
## MsvcCFlags target [ : cflags [ : mode ]]
|
|
## Invoke this rule to set additional MSVC-specific compiler flags for
|
|
## 'target'. 'mode' should be "release" or "debug". If 'mode' is omitted,
|
|
## then 'cflags' is used for release and debug.
|
|
rule MsvcCFlags { MsvcCFlags1 $(1) : $(2) : $(3) ; }
|
|
rule MsvcCFlags1 { }
|
|
|
|
## MsvcLFlags target [ : lflags [ : mode ]]
|
|
## Invoke this rule to set additional MSVC-specific linker flags for
|
|
## 'target'. 'mode' should be "release" or "debug". If 'mode' is omitted,
|
|
## then 'lflags' is used for release and debug.
|
|
rule MsvcLFlags { MsvcLFlags1 $(1) : $(2) : $(3) ; }
|
|
rule MsvcLFlags1 { }
|
|
|
|
## MsvcGenName target : name
|
|
## Assign an MSVC project name to 'target'. Normally, the project name is
|
|
## 'target' with a prefix of "app", "grp", "lib", "plg", or "wks", depending
|
|
## upon the target's type. The MsvcGenName rule allows you to override the
|
|
## default name. This rule must be invoked prior to the Application,
|
|
## Library, Plugin, or MsvcGenWorkspace rule for 'target' in order for 'name'
|
|
## to be accepted. As an alternative to invoking this rule, if you wish to
|
|
## change the default prefixes used by all targets you can use the MsvcConfig
|
|
## rule to set the MSVC.PREFIX.appcon, MSVC.PREFIX.appgui, MSVC.PREFIX.group,
|
|
## MSVC.PREFIX.library, MSVC.PREFIX.plugin, and MSVC.PREFIX.workspace
|
|
## variables to whatever values you like.
|
|
rule MsvcGenName { MsvcGenName1 $(1) : $(2) ; }
|
|
rule MsvcGenName1 { }
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Private utility rules. Common to all phases.
|
|
|
|
## msvcgen_path_version rule : dircomponents [ : version ]
|
|
## If 'version' is provided, invoke 'rule' once with 'dircomponents' and
|
|
## 'version' as arguments. If 'version' is not provided, invoke 'rule' once
|
|
## per supported MSVC version with 'dircomponents' augmented so that
|
|
## 'version' is appended to the very last element of 'dircomponents'. For
|
|
## example, if 'version' is omitted, and 'dircomponents' is "TOP proj msvc",
|
|
## then 'rule' will be invoked as "rule TOP proj msvc6 : 6", then "rule TOP
|
|
## proj msvc7 : 7", etc.
|
|
rule msvcgen_path_version
|
|
{
|
|
local subrule = $(1) ;
|
|
local path = $(2) ;
|
|
local version = $(3) ;
|
|
if $(version)
|
|
{
|
|
msvcgen_version_check $(version) ;
|
|
$(subrule) $(path) : $(version) ;
|
|
}
|
|
else
|
|
{
|
|
local v ;
|
|
for v in $(MSVCGEN_SUPPORTED_VERSIONS)
|
|
{
|
|
local p = [ FReverse $(path) ] ;
|
|
$(subrule) [ FReverse $(p[1])$(v) $(p[2-]) ] : $(v) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
rule msvcgen_resolve_dir
|
|
{ return $($(<[1])) $(<[2-]) ; }
|
|
rule msvcgen_target_dir
|
|
{ return [ ConcatDirs $(MSVCGEN_BUILD_ROOT) $(<[2-]) ] ; }
|
|
rule msvcgen_build_dir
|
|
{ return [ ConcatDirs $(MSVCGEN_BUILD_TEMP) build$(<) ] ; }
|
|
rule msvcgen_work_dir
|
|
{ return [ ConcatDirs $(MSVCGEN_BUILD_TEMP) temp$(<) ] ; }
|
|
rule msvcgen_template_dir
|
|
{ return [ ConcatDirs [ msvcgen_resolve_dir $(<) ] ] ; }
|
|
rule msvcgen_version_check
|
|
{
|
|
if $(<) != common && ! [ IsElem $(<) : $(MSVCGEN_SUPPORTED_VERSIONS) ]
|
|
{
|
|
exit "Error: `$(<)' is not a supported msvcgen version number; valid "
|
|
"numbers are:" $(MSVCGEN_SUPPORTED_VERSIONS) ;
|
|
}
|
|
}
|
|
|
|
rule MsvcRmTemps
|
|
{
|
|
if $(MSVCGEN_KEEPTEMPS) != yes
|
|
{
|
|
RmTemps $(<) : $(>) ;
|
|
}
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Phase 1
|
|
|
|
if ! $(DO_MSVCGEN)
|
|
{
|
|
JAM ?= jam ;
|
|
MSVCGEN_JAMOPTIONS ?= ;
|
|
MSVCGEN_TTREEOPTIONS ?= ;
|
|
MSVCGEN_SILENT ?= no ;
|
|
MSVCGEN_VERBOSE ?= no ;
|
|
MSVCGEN_KEEPTEMPS ?= no ;
|
|
if $(MSVCGEN_SILENT) = yes
|
|
{
|
|
MSVCGEN_JAMOPTIONS += -d0 ;
|
|
}
|
|
else
|
|
{
|
|
MSVCGEN_TTREEOPTIONS += "--verbose" ;
|
|
if $(MSVCGEN_VERBOSE) = yes
|
|
{
|
|
if $(JAMVERSION) <= 2.4
|
|
{
|
|
MSVCGEN_JAMOPTIONS += -d+2 ;
|
|
}
|
|
else
|
|
{
|
|
MSVCGEN_JAMOPTIONS += -d5 ;
|
|
}
|
|
}
|
|
}
|
|
if $(MSVCGEN_KEEPTEMPS) = yes
|
|
{
|
|
MSVCGEN_JAMOPTIONS += "-sMSVCGEN_KEEPTEMPS=yes" ;
|
|
}
|
|
|
|
## MsvcGenConfigFile file
|
|
## (See documentation above.)
|
|
rule MsvcGenConfigFile1
|
|
{
|
|
MSVCGEN_CONFIG_FILES += $(<) ;
|
|
}
|
|
|
|
## MsvcGenSubDir dircomponents [ : version ]
|
|
## (See documentation above.)
|
|
rule MsvcGenSubDir1
|
|
{
|
|
local path = $(1) ;
|
|
local version = $(2) ;
|
|
if ! [ Property msvcgen : pathset$(version) ]
|
|
{
|
|
SetProperty msvcgen : pathset$(version) ;
|
|
MsvcGenTarget $(path) : $(version) ;
|
|
}
|
|
else
|
|
{
|
|
Echo "Warning: MsvcGenSubDir already invoked for version $(version)" ;
|
|
}
|
|
}
|
|
|
|
## MsvcGenTarget dircomponents : version
|
|
## Create pseudo-targets for building and removing project files for the
|
|
## specified version of MSVC. 'dircomponents' is interpreted as described
|
|
## for the MsvcGenSubDir rule. Also populates the list MSVCGEN_TARGETS with
|
|
## names of the targets. Clients which need to perform some pre-processing
|
|
## prior to the actual msvcgen run may set the targets in this list to depend
|
|
## upon client-supplied targets.
|
|
rule MsvcGenTarget
|
|
{
|
|
local path = $(1) ;
|
|
local version = $(2) ;
|
|
if $(version) = common
|
|
{
|
|
CleanDir msvccommonclean : [ msvcgen_target_dir $(path) ] ;
|
|
Depends msvcclean : msvccommonclean ;
|
|
}
|
|
else
|
|
{
|
|
MsvcGenUmbrella ;
|
|
Always msvc$(version)gen ;
|
|
NotFile msvc$(version)gen ;
|
|
MSVC_VERSION on msvc$(version)gen = $(version) ;
|
|
MsvcGen msvc$(version)gen ;
|
|
Depends msvcgen : msvc$(version)gen ;
|
|
Help msvc$(version)gen : "Create MSVC$(version) project files" ;
|
|
MSVCGEN_TARGETS += msvc$(version)gen ;
|
|
local commonworkdir = [ msvcgen_work_dir common ] ;
|
|
CleanDir msvc$(version)clean :
|
|
[ msvcgen_target_dir $(path) ]
|
|
[ msvcgen_build_dir $(version) ]
|
|
[ msvcgen_work_dir $(version) ]
|
|
$(commonworkdir) ;
|
|
Depends msvcclean : msvc$(version)clean ;
|
|
Help msvc$(version)clean : "Remove built MSVC$(version) project files" ;
|
|
}
|
|
}
|
|
|
|
actions MsvcGen bind MSVCGEN_CONFIG_FILES
|
|
{
|
|
$(JAM) $(MSVCGEN_JAMOPTIONS) \
|
|
-sDO_MSVCGEN=yes \
|
|
-sMSVC_VERSION=$(MSVC_VERSION) \
|
|
-sMSVCGEN_TTREEOPTIONS='$(MSVCGEN_TTREEOPTIONS)' \
|
|
-sMSVCGEN_CONFIG_FILES='$(MSVCGEN_CONFIG_FILES)' \
|
|
-sTARGET.OS=WIN32 \
|
|
msvcgen
|
|
}
|
|
|
|
## MsvcGenUmbrella
|
|
## Create pseudo-targets for building and removing project files for all
|
|
## version of MSVC.
|
|
rule MsvcGenUmbrella
|
|
{
|
|
if ! [ Property msvcgen : umbrella ]
|
|
{
|
|
SetProperty msvcgen : umbrella ;
|
|
|
|
Always msvcgen ;
|
|
NotFile msvcgen ;
|
|
Help msvcgen : "Create MSVC project files (all versions)" ;
|
|
|
|
Always msvcclean ;
|
|
NotFile msvcclean ;
|
|
Help msvcclean : "Remove built MSVC project files (all versions)" ;
|
|
CleanDir msvcclean : $(MSVCGEN_BUILD_TEMP) ;
|
|
Depends clean : msvcclean ;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Phase 2
|
|
|
|
if $(MSVCGEN_CONFIG_FILES)
|
|
{
|
|
local f ;
|
|
for f in $(MSVCGEN_CONFIG_FILES)
|
|
{
|
|
include $(f) ;
|
|
}
|
|
}
|
|
|
|
if $(TTREE)
|
|
{
|
|
PERL ?= perl ;
|
|
RUN_TTREE ?= $(PERL) "\"$(TTREE)\"" ;
|
|
}
|
|
else
|
|
{
|
|
TTREE ?= ttree ;
|
|
RUN_TTREE ?= $(TTREE) ;
|
|
}
|
|
|
|
# Implementation note: The --strip-root directives are order-sensitive when the
|
|
# build directory is the same as the source directory, in which case TOP is "."
|
|
# and MSVCGEN_BUILD_ROOT is "./out". If TOP incorrectly appeared first, then
|
|
# it would invalidate the following --strip-root option since TOP is a prefix
|
|
# of MSVCGEN_BUILD_ROOT.
|
|
MSVCGEN_STRIP_ROOT = $(MSVCGEN_BUILD_ROOT)/ $(TOP)/ ;
|
|
|
|
# When generating the icon file .rc, we compose a 'sed' expression out of
|
|
# MSVCGEN_BUILD_ROOT in order to ensure that the referenced icon paths are
|
|
# correct. However, we must take care to protect characters in
|
|
# MSVCGEN_BUILD_ROOT which have special meaning to 'sed'. For instance, in
|
|
# MSVCGEN_BUILD_ROOT, if $(TOP)/ is "./", then we want it to match a literal
|
|
# period followed by a slash, not 'any character' followed by a slash, so it
|
|
# must be transformed to "\./". (Presently we take the simple-minded approach
|
|
# of protecting only "." since it arises frequently.)
|
|
MSVCGEN_SED_PROTECT = "$(SED) 's:\\.:\\\\\\.:g'" ;
|
|
|
|
MSVC_PLATFORM_SUFFIX = ;
|
|
MSVC_VERSION ?= 7 ;
|
|
if $(MSVC_VERSION) = 6
|
|
{
|
|
SUFPRJ = dsp ;
|
|
SUFWSP = dsw ;
|
|
MSVC_SUFLIB = lii6iiib ;
|
|
MSVC_SUFEXE = exe ;
|
|
MSVC_FORCE_CRLF = yes ;
|
|
MSVC_TEMPLATE_SUFFIX = 6 ;
|
|
}
|
|
else if $(MSVC_VERSION) = 7 || $(MSVC_VERSION) = 71 || $(MSVC_VERSION) = 8 || $(MSVC_VERSION) = sn71 || $(MSVC_VERSION) = xenon8
|
|
{
|
|
SUFPRJ = vcproj ;
|
|
SUFWSP = sln ;
|
|
MSVC_SUFLIB = liiixxiib ;
|
|
MSVC_SUFEXE = exe ;
|
|
|
|
|
|
MSVC_FORCE_CRLF = no ;
|
|
MSVC_TEMPLATE_SUFFIX = 7 ;
|
|
if $(MSVC_VERSION) = 7
|
|
{
|
|
MSVC_FORMATVERSION_PRJ = 7.00 ;
|
|
MSVC_FORMATVERSION_WSP = 7.00 ;
|
|
}
|
|
else if $(MSVC_VERSION) = 71
|
|
{
|
|
MSVC_FORMATVERSION_PRJ = 7.10 ;
|
|
MSVC_FORMATVERSION_WSP = 8.00 ;
|
|
}
|
|
else if $(MSVC_VERSION) = 8
|
|
{
|
|
MSVC_FORMATVERSION_PRJ = 8.00 ;
|
|
MSVC_FORMATVERSION_WSP = 9.00 ;
|
|
}
|
|
else if $(MSVC_VERSION) = sn71
|
|
{
|
|
MSVC_FORMATVERSION_PRJ = 7.10 ;
|
|
MSVC_FORMATVERSION_WSP = 8.00 ;
|
|
MSVC_TEMPLATE_SUFFIX = sn71 ;
|
|
MSVC_SUFLIB = a ;
|
|
MSVC_SUFEXE = elf ;
|
|
}
|
|
else if $(MSVC_VERSION) = xenon8
|
|
{
|
|
MSVC_FORMATVERSION_PRJ = 8.00 ;
|
|
MSVC_FORMATVERSION_WSP = 9.00 ;
|
|
MSVC_TEMPLATE_SUFFIX = xenon8 ;
|
|
MSVC_PLATFORM_SUFFIX = _xenon ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
exit "No msvcgen support for MSVC version $(MSVC_VERSION) yet!" ;
|
|
}
|
|
|
|
MSVC.TSUFPRJ = tproj ;
|
|
MSVC.TSUFWKP = twks ;
|
|
|
|
MSVC.DEPEND ?= ;
|
|
MSVC.DEPEND_DEBUG ?= ;
|
|
MSVC.LIBRARY ?= ;
|
|
MSVC.LIBRARY_DEBUG ?= ;
|
|
MSVC.LFLAGS ?= ;
|
|
MSVC.LFLAGS_DEBUG ?= ;
|
|
MSVC.LIBRARY_DELAY ?= ;
|
|
MSVC.CFLAGS ?= ;
|
|
MSVC.CFLAGS_DEBUG ?= ;
|
|
MSVC.DEFINES ?= ;
|
|
MSVC.DEFINES_DEBUG ?= ;
|
|
MSVC.DEPEND.appgui ?= ;
|
|
MSVC.DEPEND_DEBUG.appgui ?= ;
|
|
MSVC.LIBRARY.appgui ?= ;
|
|
MSVC.LIBRARY_DEBUG.appgui ?= ;
|
|
MSVC.LFLAGS.appgui ?= ;
|
|
MSVC.LFLAGS_DEBUG.appgui ?= ;
|
|
MSVC.CFLAGS.appgui ?= ;
|
|
MSVC.CFLAGS_DEBUG.appgui ?= ;
|
|
MSVC.DEFINES.appgui ?= ;
|
|
MSVC.DEFINES_DEBUG.appgui ?= ;
|
|
MSVC.DEPEND.appcon ?= ;
|
|
MSVC.DEPEND_DEBUG.appcon ?= ;
|
|
MSVC.LIBRARY.appcon ?= ;
|
|
MSVC.LIBRARY_DEBUG.appcon ?= ;
|
|
MSVC.LFLAGS.appcon ?= ;
|
|
MSVC.LFLAGS_DEBUG.appcon ?= ;
|
|
MSVC.CFLAGS.appcon ?= ;
|
|
MSVC.CFLAGS_DEBUG.appcon ?= ;
|
|
MSVC.DEFINES.appcon ?= ;
|
|
MSVC.DEFINES_DEBUG.appcon ?= ;
|
|
MSVC.DEPEND.plugin ?= ;
|
|
MSVC.DEPEND_DEBUG.plugin ?= ;
|
|
MSVC.LIBRARY.plugin ?= ;
|
|
MSVC.LIBRARY_DEBUG.plugin ?= ;
|
|
MSVC.LIBRARY_DELAY.plugin ?= ;
|
|
MSVC.LFLAGS.plugin ?= ;
|
|
MSVC.LFLAGS_DEBUG.plugin ?= ;
|
|
MSVC.CFLAGS.plugin ?= ;
|
|
MSVC.CFLAGS_DEBUG.plugin ?= ;
|
|
MSVC.DEFINES.plugin ?= ;
|
|
MSVC.DEFINES_DEBUG.plugin ?= ;
|
|
MSVC.DEPEND.library ?= ;
|
|
MSVC.DEPEND_DEBUG.library ?= ;
|
|
MSVC.LIBRARY.library ?= ;
|
|
MSVC.LIBRARY_DEBUG.library ?= ;
|
|
MSVC.LFLAGS.library ?= ;
|
|
MSVC.LFLAGS_DEBUG.library ?= ;
|
|
MSVC.CFLAGS.library ?= ;
|
|
MSVC.CFLAGS_DEBUG.library ?= ;
|
|
MSVC.DEFINES.library ?= ;
|
|
MSVC.DEFINES_DEBUG.library ?= ;
|
|
|
|
MSVC.PREFIX.appgui ?= app ;
|
|
MSVC.PREFIX.appcon ?= app ;
|
|
MSVC.PREFIX.plugin ?= plg ;
|
|
MSVC.PREFIX.library ?= lib ;
|
|
MSVC.PREFIX.group ?= grp ;
|
|
MSVC.PREFIX.workspace ?= wks ;
|
|
|
|
SetProperty build : projgen : msvc ;
|
|
SetProperty build : projgen_version : $(MSVC_VERSION) ;
|
|
|
|
# MsvcAddPrefix name : type
|
|
rule MsvcAddPrefix
|
|
{
|
|
local name = $(1) ;
|
|
local type = $(2) ;
|
|
local prefix = $(MSVC.PREFIX.$(type)) ;
|
|
if $(prefix) { name = "$(prefix)$(name)" ; }
|
|
return $(name) ;
|
|
}
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Override some rules
|
|
|
|
actions GenerateWin32ManifestRc
|
|
{
|
|
cat > $(<) << __EOF__
|
|
// This file is generated automatically.
|
|
|
|
#if !defined(PROJECTGEN_VERSION) || (PROJECTGEN_VERSION != 8)
|
|
1 24 "$(MANIFEST_NAME)"
|
|
#endif
|
|
__EOF__
|
|
}
|
|
|
|
## MsvcGenConfig variable [ : value ]
|
|
## (See documentation above.)
|
|
rule MsvcGenConfig1
|
|
{
|
|
$(<) = $(>) ;
|
|
}
|
|
|
|
## MsvcGenVariable variable [ : value ]
|
|
## (See documentation above.)
|
|
rule MsvcGenVariable1
|
|
{
|
|
MSVCGEN_VARIABLES += "$(<)|$(>)" ;
|
|
}
|
|
|
|
## MsvcGenWorkspace name [ : accepts [ : rejects ]]
|
|
## (See documentation above.)
|
|
rule MsvcGenWorkspace1
|
|
{
|
|
local name = $(1) ;
|
|
local accepts = $(2) ;
|
|
local rejects = $(3) ;
|
|
local builddir = [ msvcgen_build_dir $(MSVC_VERSION) ] ;
|
|
local workdir = [ msvcgen_work_dir $(MSVC_VERSION) ] ;
|
|
local wksname = $(MSVC.NAME_OVERRIDE.$(name)) ;
|
|
if ! $(wksname) { wksname = [ MsvcAddPrefix $(name) : workspace ] ; }
|
|
|
|
MSVC.WORKSPACES += $(name) ;
|
|
|
|
local respdir = $(workdir) ;
|
|
local respfile = $(wksname:G=msvcresp:S=.resp) ;
|
|
Always $(respfile) ;
|
|
$(name)_WKS_RESPFILE = $(respfile) ;
|
|
$(name)_WKS_RESPDIR = $(respdir) ;
|
|
|
|
# Boilerplate.
|
|
ResponseFile $(respfile) :
|
|
"key|value"
|
|
"accept|$(accepts)"
|
|
"reject|$(rejects)"
|
|
"formatversion|$(MSVC_FORMATVERSION_WSP)"
|
|
$(MSVCGEN_VARIABLES)
|
|
: notfile : $(respdir) ;
|
|
MsvcRmTemps msvcgen : $(respfile) ;
|
|
|
|
local buildfile = $(wksname:G=msvcworkspace:S=.$(MSVC.TSUFWKP)) ;
|
|
Always $(buildfile) ;
|
|
MakeLocate $(buildfile) : $(builddir) ;
|
|
Includes $(buildfile) : $(respfile) ;
|
|
MSVC_BUILD_TYPE on $(buildfile) = workspace ;
|
|
MsvcBuildFile $(buildfile) : $(respfile) ;
|
|
Depends msvcgenrun : $(buildfile) ;
|
|
MsvcRmTemps msvcgen : $(buildfile) ;
|
|
}
|
|
|
|
## MsvcGenSubDir dircomponents [ : version ]
|
|
## (See documentation above.)
|
|
rule MsvcGenSubDir1
|
|
{
|
|
local path = $(1) ;
|
|
local version = $(2) ;
|
|
|
|
local relpath ;
|
|
if ! $(path[2])
|
|
{
|
|
relpath = $(DOT) ;
|
|
}
|
|
else
|
|
{
|
|
local i ;
|
|
for i in $(path[2-])
|
|
{
|
|
relpath += $(DOTDOT) ;
|
|
}
|
|
}
|
|
|
|
SetProperty msvcgen : outdir$(version) : [ msvcgen_target_dir $(path) ] ;
|
|
SetProperty msvcgen : relpath$(version) : $(relpath) ;
|
|
|
|
MSVCGEN_OUTDIR_$(version) = [ Property msvcgen : outdir$(version) ] ;
|
|
}
|
|
|
|
## MsvcGenTemplateDir dircomponents
|
|
## (See documentation above.)
|
|
rule MsvcGenTemplateDir1
|
|
{
|
|
SetProperty msvcgen : templatedir : [ msvcgen_template_dir $(<) ] ;
|
|
|
|
MSVCGEN_TEMPLATEDIR = [ Property msvcgen : templatedir ] ;
|
|
}
|
|
|
|
## MsvcGenName target : name
|
|
## (See documentation above.)
|
|
rule MsvcGenName1
|
|
{
|
|
MSVC.NAME_OVERRIDE.$(<) = $(>) ;
|
|
}
|
|
|
|
## MsvcProject target : type : target-with-ext : sources : options
|
|
## Create a project file for 'target', which is the project's raw name.
|
|
## 'sources' is a list of files comprising the target.
|
|
rule MsvcProject
|
|
{
|
|
local rawname = $(1) ;
|
|
local type = $(2) ;
|
|
local decorated = $(3) ;
|
|
local sources = $(4) ;
|
|
local options = $(5) ;
|
|
local relpath = [ Property msvcgen : relpath$(MSVC_VERSION) ] ;
|
|
local outdir = [ Property msvcgen : outdir$(MSVC_VERSION) ] ;
|
|
local outdircommon = [ Property msvcgen : outdircommon ] ;
|
|
if "$(outdircommon)" = ""
|
|
{
|
|
outdircommon = $(outdir) ;
|
|
}
|
|
local builddir = [ msvcgen_build_dir $(MSVC_VERSION) ] ;
|
|
local workdir = [ msvcgen_work_dir $(MSVC_VERSION) ] ;
|
|
local workdircommon = [ msvcgen_work_dir common ] ;
|
|
|
|
local msvcname = $(MSVC.NAME_OVERRIDE.$(rawname)) ;
|
|
if ! $(msvcname) { msvcname = [ MsvcAddPrefix $(rawname) : $(type) ] ; }
|
|
$(rawname)_MSVCNAME = $(msvcname) ;
|
|
|
|
local respdir = $(workdir) ;
|
|
local respfile = $(msvcname:G=msvcresp:S=.resp) ;
|
|
Always $(respfile) ;
|
|
$(rawname)_PRJ_RESPFILE = $(respfile) ;
|
|
$(rawname)_PRJ_RESPDIR = $(respdir) ;
|
|
|
|
# Boilerplate.
|
|
ResponseFile $(respfile) :
|
|
"key|value"
|
|
"formatversion|$(MSVC_FORMATVERSION_PRJ)"
|
|
"projtype|$(type)"
|
|
"project|$(msvcname)"
|
|
"rawtarget|$(rawname)"
|
|
"target|$(decorated)"
|
|
"sourceroot|$(relpath:J=/)"
|
|
"buildroot|$(relpath:J=/)"
|
|
"striproot|$(MSVCGEN_STRIP_ROOT)"
|
|
"define|$(MSVC.DEFINES)"
|
|
"define|$(MSVC.DEFINES.$(type))"
|
|
"definedebug|$(MSVC.DEFINES_DEBUG)"
|
|
"definedebug|$(MSVC.DEFINES_DEBUG.$(type))"
|
|
"cflags|$(MSVC.CFLAGS)"
|
|
"cflags|$(MSVC.CFLAGS.$(type))"
|
|
"cflagsdebug|$(MSVC.CFLAGS_DEBUG)"
|
|
"cflagsdebug|$(MSVC.CFLAGS_DEBUG.$(type))"
|
|
"lflags|$(MSVC.LFLAGS)"
|
|
"lflags|$(MSVC.LFLAGS.$(type))"
|
|
"lflagsdebug|$(MSVC.LFLAGS_DEBUG)"
|
|
"lflagsdebug|$(MSVC.LFLAGS_DEBUG.$(type))"
|
|
"library|$(MSVC.LIBRARY)"
|
|
"library|$(MSVC.LIBRARY.$(type))"
|
|
"librarydebug|$(MSVC.LIBRARY_DEBUG)"
|
|
"librarydebug|$(MSVC.LIBRARY_DEBUG.$(type))"
|
|
"librarydelay|$(MSVC.LIBRARY_DELAY)"
|
|
"librarydelay|$(MSVC.LIBRARY_DELAY.$(type))"
|
|
"msvcversion|$(MSVC_VERSION)"
|
|
"static|$($(rawname)_STATIC)"
|
|
"platformsuffix|$(MSVC_PLATFORM_SUFFIX)"
|
|
$(MSVCGEN_VARIABLES)
|
|
: notfile : $(respdir) ;
|
|
MsvcRmTemps msvcgen : $(respfile) ;
|
|
|
|
# Only include source and headers files for now. In the future, we also
|
|
# want to include .cfg files and any other textual resources which which the
|
|
# user might care to read/view in the MSVC IDE.
|
|
local i ;
|
|
for i in $(sources)
|
|
{
|
|
if [ IsElem $(i:S) : .h .hpp .hxx .H .c .cc .cpp .cxx .C .m .mm .M ]
|
|
{
|
|
local fileinproj ;
|
|
if $($(rawname)_STATIC) = "yes"
|
|
{
|
|
fileinproj = $(i) ;
|
|
}
|
|
else
|
|
{
|
|
fileinproj = $(i:R=$(SEARCH_SOURCE)) ;
|
|
}
|
|
ResponseFile $(respfile) : "file|$(fileinproj)" : notfile :
|
|
$(respdir) ;
|
|
}
|
|
}
|
|
|
|
# Add resource file.
|
|
if [ IsElem $(type) : plugin appgui appcon ]
|
|
{
|
|
local resource = $(msvcname:S=.rc) ;
|
|
Depends msvcgen : $(resource) ;
|
|
MakeLocate $(resource) : $(outdircommon) ;
|
|
SEARCH on $(resource) = $(outdircommon) ;
|
|
NAME on $(resource) = $(rawname) ;
|
|
$(rawname)_RCNAME = $(resource) ;
|
|
ResponseFile $(respfile) : "file|$(resource:R=$(outdircommon))" : notfile :
|
|
$(respdir) ;
|
|
|
|
local versionrc = $(resource:S=.vrctmp) ;
|
|
MakeLocate $(versionrc) : $(workdircommon) ;
|
|
MakeVersionRc $(versionrc) : $(rawname) ;
|
|
Depends $(versionrc) : $(TOP)/Jamconfig ;
|
|
Depends $(versionrc) : $(SUBDIR)/Jamfile ;
|
|
Win32Resource $(rawname) : $(versionrc) ;
|
|
MsvcRmTemps $(resource) : $(versionrc) ;
|
|
|
|
if $(type) = "plugin"
|
|
{
|
|
local metarc = $(resource:S=.mrctmp) ;
|
|
MakeLocate $(metarc) : $(workdircommon) ;
|
|
SEARCH on $(metarc) = $(SEARCH_SOURCE) ;
|
|
Depends $(metarc) : $($(rawname)_METAFILE) ;
|
|
GenerateWin32MetadataRc $(metarc) : $($(rawname)_METAFILE) ;
|
|
|
|
Win32Resource $(rawname) : $(metarc) ;
|
|
MsvcRmTemps $(resource) : $(metarc) ;
|
|
ResponseFile $(respfile) :
|
|
"file|$($(rawname)_METAFILE:R=$(SEARCH_SOURCE))" : notfile :
|
|
$(respdir) ;
|
|
}
|
|
|
|
if [ IsElem $(type) : appgui appcon ]
|
|
{
|
|
if ! [ IsElem nomanifest : $(options) ]
|
|
{
|
|
local manifest = $(msvcname:S=.manifest) ;
|
|
MakeLocate $(manifest) : $(outdircommon) ;
|
|
MakeManifestFile $(manifest) : $(rawname) ;
|
|
Depends $(manifest) : $(TOP)/Jamconfig ;
|
|
Depends $(manifest) : $(SUBDIR)/Jamfile ;
|
|
Depends msvcgen : $(manifest) ;
|
|
|
|
local manifestrc = $(resource:S=.mfrctmp) ;
|
|
MakeLocate $(manifestrc) : $(workdircommon) ;
|
|
MANIFEST_NAME on $(manifestrc) = $(manifest) ;
|
|
GenerateWin32ManifestRc $(manifestrc) ;
|
|
Depends $(manifestrc) : $(manifest) ;
|
|
if $(MSVC_VERSION) = 8
|
|
{
|
|
# VC8: Manifest appears in project along other files, a special build
|
|
# tool cares about the embedding into a resource. (The resource goop
|
|
# still has to be generated since it is shared with other VCs.)
|
|
ResponseFile $(respfile) : "file|$(manifest:R=$(outdircommon))" : notfile :
|
|
$(respdir) ;
|
|
}
|
|
|
|
Win32Resource $(rawname) : $(manifestrc) ;
|
|
MsvcRmTemps $(resource) : $(manifestrc) ;
|
|
}
|
|
|
|
local icon = [ ApplicationIcon win32 : $(rawname) ] ;
|
|
if ! $(icon)
|
|
{
|
|
local apptype = gui ;
|
|
if $(type) = "appcon" { apptype = console ; }
|
|
icon = [ ApplicationIconDefault win32 : $(apptype) ] ;
|
|
}
|
|
if $(icon)
|
|
{
|
|
local iconrc = $(resource:S=.iconrctmp) ;
|
|
# RELPATH includes trailing slash (hence the "" in ConcatDirs).
|
|
RELPATH on $(iconrc) =
|
|
[ ConcatDirs [ Property msvcgen : relpath$(MSVC_VERSION) ] "" ] ;
|
|
MakeLocate $(iconrc) : $(workdircommon) ;
|
|
Depends $(iconrc) : $(icon) ;
|
|
Depends $(iconrc) : $(SUBDIR)/Jamfile ;
|
|
GenerateIconRc $(iconrc) : $(icon) ;
|
|
Win32Resource $(rawname) : $(iconrc) ;
|
|
MsvcRmTemps $(resource) : $(iconrc) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
local inckeys = "include" includedebug ;
|
|
local incdirs = $(MSVC.INCDIRS_LITERAL) $(MSVC.INCDIRS_LITERAL.$(rawname)) ;
|
|
ResponseFile $(respfile) : "$(inckeys)|$(incdirs)" : notfile : $(respdir) ;
|
|
|
|
local incdir ;
|
|
for incdir in $(MSVC.INCDIRS) $(MSVC.INCDIRS.$(rawname))
|
|
{
|
|
if $(incdir) = "."
|
|
{
|
|
incdir = [ ConcatDirs $(relpath) ] ;
|
|
}
|
|
else
|
|
{
|
|
incdir = [ ConcatDirs $(relpath) $(incdir) ] ;
|
|
}
|
|
ResponseFile $(respfile) : "$(inckeys)|$(incdir)" : notfile : $(respdir) ;
|
|
}
|
|
|
|
if ! [ Property msvcgen : templatedir ]
|
|
{
|
|
exit "Error: You must invoke MsvcGenTemplateDir for project generation." ;
|
|
}
|
|
|
|
local buildfile = $(msvcname:G=msvcproject:S=.$(MSVC.TSUFPRJ)) ;
|
|
Always $(buildfile) ;
|
|
MakeLocate $(buildfile) : $(builddir) ;
|
|
Includes $(buildfile) : $(respfile) ;
|
|
MSVC_BUILD_TYPE on $(buildfile) = project ;
|
|
MsvcBuildFile $(buildfile) : $(respfile) ;
|
|
Depends msvcgenrun : $(buildfile) ;
|
|
MsvcRmTemps msvcgen : $(buildfile) ;
|
|
|
|
if ! $(MSVC.WORKSPACES)
|
|
{
|
|
exit "You must specify at least one workspace via MsvcGenWorkspace" ;
|
|
}
|
|
|
|
local w ;
|
|
for w in $(MSVC.WORKSPACES)
|
|
{
|
|
ResponseFile $($(w)_WKS_RESPFILE) : "project|$(msvcname)" : notfile :
|
|
$($(w)_WKS_RESPDIR) ;
|
|
}
|
|
|
|
Clean msvcclean : $(target) ;
|
|
}
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
# Ensure that the pseudo-groups exist with which the overridden Application,
|
|
# Plugin, and Library rules will register their targets. We have to do this
|
|
# here rather than at the top-level (outside of any rule invocation) because we
|
|
# need to give the client time to invoke MsvcGenWorkspace first to set up the
|
|
# workspaces into which these groups will be inserted. If we tried registering
|
|
# theses pseudo-groups at the top-level, registration would occur before the
|
|
# client has had a chance to invoke MsvcGenWorkspace, thus these pseudo-groups
|
|
# would not inhabit any workspaces.
|
|
rule RegisterWellKnownCompileGroup1
|
|
{
|
|
local group = $(1) ;
|
|
if $(MSVCGEN.WELL_KNOWN_GROUP_REGISTERED.$(group)) != yes
|
|
{
|
|
MSVCGEN.WELL_KNOWN_GROUP_REGISTERED.$(group) = yes ;
|
|
RegisterCompileGroups $(group) ;
|
|
}
|
|
}
|
|
|
|
rule RegisterWellKnownCompileGroup
|
|
{
|
|
RegisterWellKnownCompileGroup1 all ;
|
|
RegisterWellKnownCompileGroup1 $(1) ;
|
|
}
|
|
|
|
rule LinkStaticPlugins
|
|
{
|
|
local package target plugins optplugins ;
|
|
# Fetch the parameters
|
|
target = $(1) ;
|
|
plugins = $(2) ;
|
|
optplugins = $(3) ;
|
|
package = $(4) ;
|
|
|
|
if $(package)
|
|
{
|
|
# External static plugins.
|
|
# First include static plugin info
|
|
if ! $(HAVE_STATICDEPS.$(package))
|
|
{
|
|
include $($(package).STATICDEPS) ;
|
|
HAVE_STATICDEPS.$(package) = yes ;
|
|
}
|
|
local lflags.debug lflags.release p mode ;
|
|
# Collect optional plugins
|
|
for p in $(optplugins)
|
|
{
|
|
if [ IsElem $(p) : $(STATICPLUGINS.AVAILABLE) ]
|
|
{
|
|
plugins += $(p) ;
|
|
}
|
|
}
|
|
# Grab flags
|
|
for p in $(plugins)
|
|
{
|
|
NotFile $(p) ;
|
|
for mode in debug release
|
|
{
|
|
MsvcCFlags $(target) : $(STATICPLUGIN.$(p).CFLAGS.$(mode)) : $(mode) ;
|
|
lflags.$(mode) += $(STATICPLUGIN.$(p).LFLAGS.$(mode)) ;
|
|
}
|
|
}
|
|
for mode in debug release
|
|
{
|
|
MsvcLFlags $(target) :
|
|
[ Reverse [ RemoveDups [ Reverse $(lflags.$(mode)) ] ] ] : $(mode) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# link with static plugins
|
|
LinkWith $(target) : $(STATICPLUGINS.LIBRARY) ;
|
|
|
|
# Local static plugins
|
|
local libs p ;
|
|
# Collect optional plugins
|
|
for p in $(optplugins)
|
|
{
|
|
if $($(p)_TYPE)
|
|
{
|
|
plugins += $(p) ;
|
|
}
|
|
}
|
|
# Grab flags
|
|
for p in $(plugins)
|
|
{
|
|
libs += $($(p).NEEDLIBS) ;
|
|
|
|
ExternalLibs $(target) : $($(p).EXTERNALLIBS) ;
|
|
for mode in debug release
|
|
{
|
|
MsvcExternalLibrary $(target) : $($(p)_$(mode)_EXTERNALLIBS) : $(mode) ;
|
|
MsvcExternalLibrary $(target) : $($(p)_$(mode)_EXTERNALLIBS) : $(mode) ;
|
|
}
|
|
}
|
|
LinkWith $(target) : $(libs) ;
|
|
}
|
|
|
|
# Generate static plugin instantiation
|
|
local outdir = [ Property msvcgen : outdircommon ] ;
|
|
if "$(outdir)" = ""
|
|
{
|
|
outdir = [ Property msvcgen : outdir$(MSVC_VERSION) ] ;
|
|
}
|
|
local staticuse_out ;
|
|
if $(package)
|
|
{
|
|
# @@@ Prefix hardcoded
|
|
staticuse_out = $(MSVC.PREFIX.appgui)$(<)_staticuse_$(package).cpp ;
|
|
}
|
|
else
|
|
{
|
|
staticuse_out =
|
|
$(MSVC.PREFIX.appgui)$(<)_staticuse.cpp ; # @@@ Prefix hardcoded
|
|
}
|
|
MakeLocate $(staticuse_out) : $(outdir) ;
|
|
SEARCH on $(staticuse_out) = $(outdir) ;
|
|
|
|
GenerateStaticPluginInstantiation $(staticuse_out) : $(plugins) ;
|
|
Depends msvcgen : $(staticuse_out) ;
|
|
|
|
# Add usefile to project
|
|
ResponseFile $($(target)_PRJ_RESPFILE) :
|
|
"file|$(staticuse_out:R=$(outdir))" : notfile :
|
|
$($(target)_PRJ_RESPDIR) ;
|
|
Depends $(target) : $(staticuse_out) ;
|
|
}
|
|
|
|
rule Application
|
|
{
|
|
RegisterWellKnownCompileGroup apps ;
|
|
|
|
local projtype ;
|
|
if [ IsElem console : $(3) ]
|
|
{
|
|
projtype = appcon ;
|
|
}
|
|
else
|
|
{
|
|
projtype = appgui ;
|
|
}
|
|
MsvcProject $(<) : $(projtype) : $(<:S=.$(MSVC_SUFEXE)) : $(>) : $(3) ;
|
|
|
|
CompileGroups $(<) : all apps ;
|
|
}
|
|
|
|
rule Plugin
|
|
{
|
|
RegisterWellKnownCompileGroup plugins ;
|
|
|
|
$(<)_TYPE = plugin ;
|
|
|
|
local metafile ;
|
|
metafile = [ FAppendSuffix $(<) : $(SUFMETA) ] ;
|
|
SEARCH on $(metafile) = $(SEARCH_SOURCE) ;
|
|
$(<)_METAFILE = $(metafile) ;
|
|
MsvcProject $(<) : plugin : $(<:S=$(MSVCGEN.PLUGIN_EXT.$(<):E=.dll)) : $(>) ;
|
|
CompileGroups $(<) : all plugins ;
|
|
|
|
STATICPLUGINS.SOURCES.$(<) += $(>:R=$(SEARCH_SOURCE)) ;
|
|
STATICPLUGINS.SUBTARGETS += $(<) ;
|
|
|
|
# Generate static variant of plugin
|
|
# Static registry
|
|
local outdir = [ Property msvcgen : outdircommon ] ;
|
|
local staticreg_out = $(MSVC.PREFIX.library)$(<)_staticreg.cpp ;
|
|
MakeLocate $(staticreg_out) : $(outdir) ;
|
|
SEARCH on $(staticreg_out) = $(outdir) ;
|
|
GenerateStaticPluginRegistration $(staticreg_out) : $(metafile) ;
|
|
Depends msvcgen : $(staticreg_out) ;
|
|
STATICPLUGINS.SOURCES.$(<) += $(outdir)/$(staticreg_out) ;
|
|
}
|
|
|
|
rule Library
|
|
{
|
|
RegisterWellKnownCompileGroup libs ;
|
|
$(<)_TYPE = library ;
|
|
MsvcProject $(<) : library : $(<:S=.$(MSVC_SUFLIB)) : $(>) ;
|
|
CompileGroups $(<) : all libs ;
|
|
}
|
|
|
|
rule StaticPluginLibrary
|
|
{
|
|
local name = $(<) ;
|
|
local rejects = $(>) ;
|
|
local t ;
|
|
|
|
local targets = $(STATICPLUGINS.SUBTARGETS) ;
|
|
if $(rejects)
|
|
{
|
|
targets = [ Filter $(targets) : $(rejects) ] ;
|
|
}
|
|
local sources ;
|
|
for t in $(targets)
|
|
{
|
|
sources += $(STATICPLUGINS.SOURCES.$(t)) ;
|
|
}
|
|
|
|
$(name)_STATIC = "yes" ;
|
|
# Set up library
|
|
Library $(name) : $(sources) ;
|
|
MsvcDefine $(name) : CS_STATIC_LINKED ;
|
|
_MsvcDefine $(name) : $(STATICPLUGINS.MSVC_DEFINES) ;
|
|
|
|
# Write out needed CFLAGS, LFLAGS
|
|
local outdir = [ Property msvcgen : outdircommon ] ;
|
|
if $(outdir) = ""
|
|
{
|
|
outdir = [ Property msvcgen : outdir$(MSVC_VERSION) ] ;
|
|
}
|
|
STATICPLUGINS.DEPENDENCIES = $(name)_msvc.jam ;
|
|
MakeLocate $(STATICPLUGINS.DEPENDENCIES) : $(outdir) ;
|
|
SEARCH on $(STATICPLUGINS.DEPENDENCIES) = $(outdir) ;
|
|
for t in $(targets)
|
|
{
|
|
NotFile $(t) ;
|
|
WriteDependencies $(STATICPLUGINS.DEPENDENCIES) : $(t) : $(name) ;
|
|
}
|
|
Always $(STATICPLUGINS.DEPENDENCIES) ;
|
|
Depends msvcgen : $(STATICPLUGINS.DEPENDENCIES) ;
|
|
|
|
STATICPLUGINS.LIBRARY = $(name) ;
|
|
}
|
|
|
|
# Write out CFLAGS, LFLAGS needed by a plugin
|
|
rule WriteDependencies
|
|
{
|
|
local cflags.debug cflags.release ;
|
|
local lflags.debug lflags.release ;
|
|
local depfile = $(<) ;
|
|
local plugin = $(>) ;
|
|
local libname = $(3) ;
|
|
local depfile_gristed = $(depfile:G=$(plugin)) ;
|
|
MakeLocate $(depfile_gristed) : [ on $(depfile) GetVar LOCATE ] ;
|
|
|
|
# "Artificially" insert static library itself
|
|
lflags.debug += $(MSVC.PREFIX.library)$(libname)_d.$(MSVC_SUFLIB) ;
|
|
lflags.release += $(MSVC.PREFIX.library)$(libname).$(MSVC_SUFLIB) ;
|
|
# Collect other libs
|
|
local libs = [ ResolveLibs $($(plugin).NEEDLIBS) ] ;
|
|
lflags.debug += $(MSVC.PREFIX.library)$(libs)_d.$(MSVC_SUFLIB) ;
|
|
lflags.release += $(MSVC.PREFIX.library)$(libs).$(MSVC_SUFLIB) ;
|
|
|
|
# Defines
|
|
local l ;
|
|
for l in $($(plugin).EXTERNALLIBS)
|
|
{
|
|
if $($(l).DEFINES.DEBUG)
|
|
{
|
|
cflags.debug += "\"/D $($(l).DEFINES.DEBUG)\"" ;
|
|
cflags.release += "\"/D $($(l).DEFINES)\"" ;
|
|
}
|
|
else
|
|
{
|
|
cflags.debug += "\"/D $($(l).DEFINES)\"" ;
|
|
cflags.release += "\"/D $($(l).DEFINES)\"" ;
|
|
}
|
|
}
|
|
# Link flags
|
|
local mode ;
|
|
for mode in debug release
|
|
{
|
|
lflags.$(mode) += $($(plugin).LFLAGS.$(mode)) ;
|
|
lflags.$(mode) += $($(plugin)_$(mode)_EXTERNALLIBS) ;
|
|
}
|
|
CFLAGS.DEBUG on $(depfile_gristed) = "$(cflags.debug)" ;
|
|
CFLAGS.RELEASE on $(depfile_gristed) = "$(cflags.release)" ;
|
|
lflags.debug = [ RemoveDups $(lflags.debug) ] ;
|
|
LFLAGS.DEBUG on $(depfile_gristed) = "$(lflags.debug)" ;
|
|
lflags.release = [ RemoveDups $(lflags.release) ] ;
|
|
LFLAGS.RELEASE on $(depfile_gristed) = "$(lflags.release)" ;
|
|
LIBNAME on $(depfile_gristed) = $(libname) ;
|
|
|
|
if $($(depfile).FIRSTTIME) != "yes"
|
|
{
|
|
WriteDepFlags1 $(depfile_gristed) : $(plugin) ;
|
|
$(depfile).FIRSTTIME = "yes" ;
|
|
}
|
|
else
|
|
{
|
|
WriteDepFlags2 $(depfile_gristed) : $(plugin) ;
|
|
}
|
|
Depends $(depfile) : $(depfile_gristed) ;
|
|
Always $(depfile_gristed) ;
|
|
}
|
|
|
|
actions WriteDepFlags1
|
|
{
|
|
cat << EOT > $(<)
|
|
# This file is automatically generated to be used together with $(LIBNAME)
|
|
# and must be integrated by setting the correct values for the
|
|
# HAVE_STATICDEPS.<package> and <package>.STATICDEPS via MsvcGenConfig.
|
|
# Furthermore, this file might require manual updates from the master copy
|
|
# (usually found in the package's source repository) every now and then.
|
|
STATICPLUGINS.AVAILABLE += $(>) ;
|
|
STATICPLUGIN.$(>).CFLAGS.debug = $(CFLAGS.DEBUG) ;
|
|
STATICPLUGIN.$(>).CFLAGS.release = $(CFLAGS.RELEASE) ;
|
|
STATICPLUGIN.$(>).LFLAGS.debug = $(LFLAGS.DEBUG) ;
|
|
STATICPLUGIN.$(>).LFLAGS.release = $(LFLAGS.RELEASE) ;
|
|
EOT
|
|
}
|
|
|
|
actions WriteDepFlags2
|
|
{
|
|
cat << EOT >> $(<)
|
|
STATICPLUGINS.AVAILABLE += $(>) ;
|
|
STATICPLUGIN.$(>).CFLAGS.debug = $(CFLAGS.DEBUG) ;
|
|
STATICPLUGIN.$(>).CFLAGS.release = $(CFLAGS.RELEASE) ;
|
|
STATICPLUGIN.$(>).LFLAGS.debug = $(LFLAGS.DEBUG) ;
|
|
STATICPLUGIN.$(>).LFLAGS.release = $(LFLAGS.RELEASE) ;
|
|
EOT
|
|
}
|
|
|
|
rule RegisterCompileGroups
|
|
{
|
|
local i ;
|
|
for i in $(<)_$(MSVC.WORKSPACES)
|
|
{
|
|
MsvcProject $(i) : group ;
|
|
}
|
|
}
|
|
|
|
rule CompileGroups
|
|
{
|
|
local w ;
|
|
for w in $(MSVC.WORKSPACES)
|
|
{
|
|
local i ;
|
|
for i in $(>)_$(w)
|
|
{
|
|
local m = $($(<)_MSVCNAME) ;
|
|
if ! $(m) { m = $($(<)_$(w)_MSVCNAME) ; } # Might be a "group".
|
|
if $(m)
|
|
{
|
|
ResponseFile $($(w)_WKS_RESPFILE) : "$($(i)_MSVCNAME)|$(m)" :
|
|
notfile : $($(w)_WKS_RESPDIR) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
rule LinkWith
|
|
{
|
|
local libs = [ ResolveLibs $(>) ] ;
|
|
ExternalLibs $(<) : $($(>).EXTERNALLIBS) ;
|
|
local w ;
|
|
for w in $(MSVC.WORKSPACES)
|
|
{
|
|
local l ;
|
|
for l in $(libs)_MSVCNAME
|
|
{
|
|
if $($(l))
|
|
{
|
|
ResponseFile $($(w)_WKS_RESPFILE) : "$($(<)_MSVCNAME)|$($(l))" :
|
|
notfile : $($(w)_WKS_RESPDIR) ;
|
|
}
|
|
}
|
|
}
|
|
$(<).NEEDLIBS = $(libs) ;
|
|
}
|
|
|
|
rule MsvcClassifyMode
|
|
{
|
|
local c ;
|
|
switch $(<)
|
|
{
|
|
case release : c = "" ;
|
|
case debug : c = debug ;
|
|
case * : c = "" debug ;
|
|
}
|
|
return $(c) ;
|
|
}
|
|
|
|
# _MsvcRespEmit target : items : tag [ : mode [ : options ]]
|
|
# Emit `items' to the response file for `target' using the response file tag
|
|
# `tag'. `mode' is either "release", "debug", or empty, in which case it
|
|
# applies to release and debug modes. If options contains "ignoremode", then
|
|
# `mode' is not consulted.
|
|
rule _MsvcRespEmit
|
|
{
|
|
local target = $(1) ;
|
|
local items = $(2) ;
|
|
local tag = $(3) ;
|
|
local mode = $(4) ;
|
|
local options = $(5) ;
|
|
local modes = "" ;
|
|
|
|
CheckOptions ignoremode : $(options) : $(target) ;
|
|
if ! [ IsElem ignoremode ] { modes = [ MsvcClassifyMode $(mode) ] ; }
|
|
|
|
ResponseFile $($(target)_PRJ_RESPFILE) : "$(tag)$(modes)|$(items)" :
|
|
notfile : $($(target)_PRJ_RESPDIR) ;
|
|
}
|
|
|
|
# MsvcExternalLibrary target [ : libs [ : mode ]]
|
|
# (See documentation above.)
|
|
rule MsvcExternalLibrary1
|
|
{
|
|
_MsvcRespEmit $(1) : $(2) : library : $(3) ;
|
|
local mode = $(3) ;
|
|
mode ?= debug release ;
|
|
$(1)_$(mode)_EXTERNALLIBS += $(2) ;
|
|
}
|
|
|
|
# MsvcDefine target [ : key [ : value [ : mode ]]]
|
|
# (See documentation above.)
|
|
rule MsvcDefine1
|
|
{
|
|
local target = $(1) ;
|
|
local key = $(2) ;
|
|
local value = $(3) ;
|
|
local mode = $(4) ;
|
|
if $(key)
|
|
{
|
|
local def ;
|
|
if $(value)
|
|
{
|
|
def = "$(key)=$(value)" ;
|
|
}
|
|
else
|
|
{
|
|
def = $(key) ;
|
|
}
|
|
_MsvcRespEmit $(target) : $(def) : define : $(mode) ;
|
|
STATICPLUGINS.MSVC_DEFINES += $(def) ;
|
|
}
|
|
}
|
|
|
|
# MsvcIncDirs target : directory [ : mode ]
|
|
# (See documentation above.)
|
|
rule MsvcIncDirs1
|
|
{
|
|
_MsvcIncDirs $(1) : $(2) : $(3) ;
|
|
}
|
|
|
|
# _MsvcDefine target : tuples [ : mode ]
|
|
# Similar to MsvcDefine, but works with a list of `key=value' tuples. Also
|
|
# understands `key' with no value.
|
|
rule _MsvcDefine
|
|
{
|
|
_MsvcRespEmit $(1) : $(2) : define : $(3) ;
|
|
}
|
|
|
|
# MsvcCFLags target [ : cflags [ : mode ]]
|
|
# (See documentation above.)
|
|
rule MsvcCFlags1
|
|
{
|
|
_MsvcRespEmit $(1) : $(2) : cflags : $(3) ;
|
|
}
|
|
|
|
# MsvcLFlags target [ : lflags [ : mode ]]
|
|
# (See documentation above.)
|
|
rule MsvcLFlags1
|
|
{
|
|
local modes = [ MsvcClassifyMode $(3) ] ;
|
|
$(target).LFLAGS.$(modes) += $(2) ;
|
|
_MsvcRespEmit $(1) : $(2) : lflags : $(3) ;
|
|
}
|
|
|
|
# _MsvcIncDirs target : incdirs [ : mode ]
|
|
# Helper for ExternalLibs which processes the contents of TAG.INCDIRS for
|
|
# an external library.
|
|
rule _MsvcIncDirs
|
|
{
|
|
_MsvcRespEmit $(1) : $(2) : include : $(3) ;
|
|
}
|
|
|
|
# _MsvcLibDirs target : libdirs [ : mode ]
|
|
# Helper for ExternalLibs which processes the contents of TAG.LIBDIRS for
|
|
# an external library.
|
|
rule _MsvcLibDirs
|
|
{
|
|
_MsvcRespEmit $(1) : $(2) : libdir : $(3) ;
|
|
}
|
|
|
|
# _ExternalLibsHelperMsvc target : libtag : subrule : attribute
|
|
rule _ExternalLibsHelperMsvc
|
|
{
|
|
local target = $(1) ;
|
|
local lib = $(2) ;
|
|
local rulename = $(3) ;
|
|
local attrib = $(4) ;
|
|
|
|
if $($(lib).$(attrib).DEBUG.$(MSVC_VERSION))
|
|
{
|
|
$(rulename) $(target) : $($(lib).$(attrib).DEBUG.$(MSVC_VERSION)) : debug ;
|
|
}
|
|
else if $($(lib).$(attrib).DEBUG)
|
|
{
|
|
$(rulename) $(target) : $($(lib).$(attrib).DEBUG) : debug ;
|
|
}
|
|
else
|
|
{
|
|
$(rulename) $(target) : $($(lib).$(attrib)) : debug ;
|
|
}
|
|
if $($(lib).$(attrib).$(MSVC_VERSION))
|
|
{
|
|
$(rulename) $(target) : $($(lib).$(attrib).$(MSVC_VERSION)) : release ;
|
|
}
|
|
else
|
|
{
|
|
$(rulename) $(target) : $($(lib).$(attrib)) : release ;
|
|
}
|
|
}
|
|
|
|
rule ExternalLibs
|
|
{
|
|
local i ;
|
|
for i in $(>)
|
|
{
|
|
_ExternalLibsHelperMsvc $(<) : $(i) : MsvcCFlags : CFLAGS ;
|
|
_ExternalLibsHelperMsvc $(<) : $(i) : MsvcLFlags : LFLAGS ;
|
|
_ExternalLibsHelperMsvc $(<) : $(i) : MsvcExternalLibrary : LIBS ;
|
|
_ExternalLibsHelperMsvc $(<) : $(i) : _MsvcDefine : DEFINES ;
|
|
_ExternalLibsHelperMsvc $(<) : $(i) : _MsvcIncDirs : INCDIRS ;
|
|
_ExternalLibsHelperMsvc $(<) : $(i) : _MsvcLibDirs : LIBDIRS ;
|
|
|
|
$(<).EXTERNALLIBS += $(i) ;
|
|
}
|
|
}
|
|
|
|
rule IncludeDir
|
|
{
|
|
local dir = $(1) ;
|
|
local target = $(2) ;
|
|
local options = $(3) ;
|
|
|
|
if ! [ IsElem transient : $(options) ]
|
|
{
|
|
local tag = "INCDIRS" ;
|
|
if [ IsElem literal : $(options) ] { tag = "INCDIRS_LITERAL" ; }
|
|
|
|
if $(dir)
|
|
{
|
|
dir = [ ConcatDirs $(dir) ] ;
|
|
}
|
|
else
|
|
{
|
|
dir = "." ;
|
|
}
|
|
|
|
if $(target)
|
|
{
|
|
MSVC.$(tag).$(target) += $(dir) ;
|
|
}
|
|
else
|
|
{
|
|
MSVC.$(tag) += $(dir) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Normal invocations of these two rules are made using Unix-style flags;
|
|
# possibly determined by an Autoconf configuration script. Such flags are
|
|
# unsuitable for MSVC, so we ignore them.
|
|
rule CFlags { }
|
|
rule LFlags { }
|
|
|
|
rule Win32Resource
|
|
{
|
|
Depends $(<) : $($(<)_RCNAME) ;
|
|
Depends $($(<)_RCNAME) : $(>) ;
|
|
MergeResources $($(<)_RCNAME) : $(>) ;
|
|
}
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
actions MsvcBuildFile
|
|
{
|
|
cat > $(<) <<EOF
|
|
[% INCLUDE '$(MSVC_BUILD_TYPE)$(MSVC_TEMPLATE_SUFFIX).tlib' respfile='$(>)' -%]
|
|
EOF
|
|
}
|
|
|
|
actions together MergeResources
|
|
{
|
|
cat $(>) > $(<)
|
|
}
|
|
|
|
actions GenerateIconRc
|
|
{
|
|
sedexpr=`echo 's^$(MSVCGEN_STRIP_ROOT)^^;' | $(MSVCGEN_SED_PROTECT)`
|
|
icon=`echo "$(>)" | sed "$sedexpr"`
|
|
echo "1 ICON \"$(RELPATH)$icon\"" > $(<)
|
|
}
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
rule MsvcTTreeRc
|
|
{
|
|
local target = $(<:G=ttreerc$(MSVC_VERSION)) ;
|
|
local builddir = [ msvcgen_build_dir $(MSVC_VERSION) ] ;
|
|
local workdir = [ msvcgen_work_dir $(MSVC_VERSION) ] ;
|
|
|
|
WORKDIR on $(target) = $(workdir) ;
|
|
BUILDDIR on $(target) = $(builddir) ;
|
|
|
|
MakeLocate $(target) : $(workdir) ;
|
|
MsvcTTreeRc1 $(target) ;
|
|
Always $(target) ;
|
|
Depends msvcgenrun : $(target) ;
|
|
MsvcRmTemps msvcgen : $(target) ;
|
|
|
|
return $(target) ;
|
|
}
|
|
|
|
actions MsvcTTreeRc1
|
|
{
|
|
cat > $(<) <<EOF
|
|
lib = $(MSVCGEN_TEMPLATEDIR)
|
|
lib = $(WORKDIR)
|
|
src = $(BUILDDIR)
|
|
dest = $(MSVCGEN_OUTDIR_$(MSVC_VERSION))
|
|
suffix $(MSVC.TSUFPRJ)=$(SUFPRJ)
|
|
suffix $(MSVC.TSUFWKP)=$(SUFWSP)
|
|
EOF
|
|
}
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
rule MsvcTTree
|
|
{
|
|
NotFile $(<) ;
|
|
Always $(<) ;
|
|
}
|
|
|
|
if $(MSVC_FORCE_CRLF) = yes
|
|
{
|
|
actions MsvcTTree
|
|
{
|
|
$(RUN_TTREE) -f \$(>) $(MSVCGEN_TTREEOPTIONS) --load_perl --all
|
|
$(PERL) -pi.bak \
|
|
-e 'if ($ARGV ne $prev) { $prev = $ARGV; binmode(ARGVOUT) }' \
|
|
-e 's:(?<!\015)\012:\015\012:g' \
|
|
$(MSVCGEN_OUTDIR_$(MSVC_VERSION))/*.$(SUFPRJ) \
|
|
$(MSVCGEN_OUTDIR_$(MSVC_VERSION))/*.$(SUFWSP)
|
|
$(RM) $(MSVCGEN_OUTDIR_$(MSVC_VERSION))/*.bak
|
|
}
|
|
}
|
|
else
|
|
{
|
|
actions MsvcTTree
|
|
{
|
|
$(RUN_TTREE) -f \$(>) $(MSVCGEN_TTREEOPTIONS) --load_perl --all
|
|
}
|
|
}
|
|
|
|
MsvcTTree msvcgenrun : [ MsvcTTreeRc ttree.rc ] ;
|
|
|
|
NotFile msvcgen ;
|
|
Always msvcgen ;
|
|
Depends msvcgen : msvcgenrun ;
|
|
}
|