# p4/Jamrules # # This Jamrules describes how to build most of Perforce, exclusive of # windows only products. # # This file is organized into sections: # # Section 1. Global variable settings. # Section 2. Library names. # Section 3. Per-build type variable settings. # Section 4. Per-platform variable settings. # Section 5. Perforce-special rules and actions. # Section 6. Perforce-special Windows rules. # Section 7. QT build rules and actions. # Section 8. Lua build rules and actions. # Section 9. Per-platform actions. # Section 10. Useful miscellanea # ################################################# # # Section 1. Global variable settings. # ################################################# if $(JAMBASEDATE) < 2002.05.09 { Exit Jamrules requires Jambase 2002.05.09 ($(JAMBASEDATE)) ; } # Variables you shouldn't set: # # OS - operating system ("FreeBSD") # OSPLAT - OS platform ("sparc") # # Variables you can set: # # OSVER - version of OS ("102" for MACOSX) # TYPE - controls compile flags (see below) # BUILD - subdirectory for special named builds ("nightly") # For convenience of historical compatibility, the OSPLAT value # "AMD64" will be changed to "X86_64", which is the canonical name # we are now using for that platform. Please get into the habit of # using it directly, as this may go away someday. if $(OSPLAT) = AMD64 { OSPLAT = X86_64 ; } # This is jam idiomatic, but the result is that # P4BIN is set to ../p4-bin (relative to P4) SubDir AllP4 p4 ; # where we are SubDir AllP4 p4-bin ; # where we want to be SubDir P4BIN ; # name is that SubDir AllP4 p4 ; # back to where we started EXEC_LIB_TOKENS = P4BIN lib.$(OS:L)$(OSVER:EL)$(OSPLAT:EL) ; EXEC_LIB ?= [ FSubDirPath $(EXEC_LIB_TOKENS) ] ; EXEC_LIBEXEC_TOKENS = P4BIN libexec.$(OS:L)$(OSVER:EL)$(OSPLAT:EL) ; EXEC_LIBEXEC ?= [ FSubDirPath $(EXEC_LIBEXEC_TOKENS) ] ; # Build dir: p4-bin/bin.xxx[/build][/type] EXEC_TOKENS = P4BIN bin.$(OS:L)$(OSVER:EL)$(OSPLAT:EL) $(BUILD) $(TYPE:L) ; EXEC ?= [ FSubDirPath $(EXEC_TOKENS) ] ; ALL_LOCATE_TARGET = $(EXEC) ; # version file # Ident'ed executables depend on this SEARCH on Version Jamrules = $(P4) ; include Version ; STRIP = strip ; COMPRESS = gzip -9 ; # symbolic flags with no user/group/other specifier will default to # ANDing with the user's umask. # Thus, if the user's umask is 022, # files will be -rw-r--r-- and executables will be -rwxr-xr-x # If a user's umask is 002, # files will be -rw-rw-r-- and executables will be -rwxrwxr-x # and so on. if $(UNIX) { FILEMODE = "+r,go-w" ; EXEMODE = "+rx,go-w" ; } # can be overridden on jam cmdline with -sSMARTHEAP=no # Smartheap is currently only used on NT and Linux. SMARTHEAP ?= yes ; DEFINES += OS_$(OS) OS_$(OS)$(OSVER) OS_$(OS)$(OSPLAT) OS_$(OS)$(OSVER)$(OSPLAT) ; HDRS += [ FSubDirPath P4 msgs ] [ FSubDirPath P4 support ] [ FSubDirPath P4 sys ] ; # Which Zeroconf implementation to select. Default is # Apple's bonjour. ZEROCONF = bonjour ; # For production builds we customize the names of our Qt shared # libaries on some platforms to avoid naming/version conflicts with # system libraries on numerous platforms. The main exception is # OSX, where it isn't needed. # # Developers don't necessarily bother to add this infix to their # builds, but these variables allow one to use them if desired even # for non-production builds. if $(PRODUCTION) && $(OS) != MACOSX { QT_LIBINFIX ?= P4 ; } # Point to the root of the boost hierarchy. c.f. BoostHdrs rule. BOOSTDIR ?= [ FDirName $(AllP4) .. import boost 1.37 ] ; ################################################# # # Section 2. Library names. # ################################################# rule SetLibName { $(1) = $(2:S=$(SUFLIB)) ; LOCATE on $($(1)) = $(EXEC) ; } SetLibName CLIENTLIB : libclient ; SetLibName DMLIB : libdm ; SetLibName FTPLIB : libp4ftp ; SetLibName LBRLIB : liblbr ; SetLibName P4EXPLIB : libp4exp ; SetLibName P4TD : libp4thumb ; SetLibName P4LIB : libp4 ; SetLibName P4SCCLIB : libp4scc ; SetLibName P4WINLIB : libp4win ; SetLibName P4WINCMNLIB : libp4wcmn ; SetLibName P4WINDIFFLIB : libp4wdf ; SetLibName P4WINMRGLIB : libp4wmrg ; SetLibName PLUGINLIB : libplugin ; SetLibName PROXYLIB : libproxy ; SetLibName QTADMINAPPLIB : libqtadminapp ; SetLibName QTADMINLIB : libqtadmin ; SetLibName QTCMDLIB : libqtcmd ; SetLibName QTCORELIB : libqtcore ; SetLibName QTP4APILIB : libqtp4api ; SetLibName QTIMGMAXLIB : libqtmaxfmt ; SetLibName QTIMGMAYALIB : libqtmayafmt ; SetLibName QTIMGPHOTOLIB : libqtphotofmt ; SetLibName QTIMGTGALIB : libqttgafmt ; SetLibName QTMERGELIB : libqtmerge ; SetLibName QTMERGEAPPLIB : libqtmergeapp ; SetLibName QTPLATLIB : libqtplat ; SetLibName QTPREFLIB : libqtpref ; SetLibName QTUTILLIB : libqtutil ; SetLibName QTREELIB : libqtree ; SetLibName QTZEROCONFLIB : libqtzeroconf ; SetLibName RPCLIB : librpc ; SetLibName SANDSTORM : libstorm ; SetLibName P4ALIB : libp4a ; SetLibName P4V : libp4v ; SetLibName P4VTEST : libp4vtest ; SetLibName SCCDLLLIB : p4scc2 ; SetLibName SERVERLIB : libserver ; SetLibName SUPPORTLIB : libsupp ; SetLibName WEBGIZMOLIB : libp4web ; SetLibName ZEROCONFLIB : libzeroconf ; ################################################# # # Section 3. Per-build type variable settings. # ################################################# TYPE ?= opt ; switch $(TYPE) { # These are official builds # # dyn: windows guis must be dynamic # opt: our standard, optimized build # pic: for API and some client applications case dyn : OPTIM = -O2 ; case opt : OPTIM = -O2 ; case pic : OPTIM = -O2 -fPIC ; # These are for internal testing/playing # # g/dyng/optg: debugging # pg: profiled executable on unix # fast: a fast compile (no optimization) # lower: case insensitive on UNIX # lpg: lower profiled case g : OPTIM = -g ; case dyng : OPTIM = -g ; case picg : OPTIM = -g -fPIC ; case gpic : OPTIM = -g -fPIC ; # mistake in convention; avoid using case fast : OPTIM = ; case lower : OPTIM = -DCASE_INSENSITIVE -O2 ; case lpg : OPTIM = -DCASE_INSENSITIVE -O2 -pg ; LINKFLAGS = -pg ; case optg : OPTIM = -O2 -g ; case pg : OPTIM = -pg -O ; LINKFLAGS = -pg ; case sym : OPTIM = -opt off -sym full ; LINKFLAGS = -sym full ; case FSgSSP : OPTIM = -g -D_FORTIFY_SOURCE=2 -fstack-protector-all ; case *vsdebug : # special-target builds; see NT section case * : Echo "Warning -- unknown compilation TYPE" $(TYPE) ; } # TYPE_DEBUG for all debug builds. # TYPE_DYNAMIC for all dynamic builds. # TYPE_PIC for all position-independent code gen switch $(TYPE) { case *dyn* : TYPE_DYNAMIC ?= true ; } switch $(TYPE) { case *g* : TYPE_DEBUG ?= true ; } switch $(TYPE) { case *pic* : TYPE_PIC ?= true ; } # Some things don't get built dynamically/statically. if ! $(TYPE_DYNAMIC) || $(OS) != NT { BUILD_P4D = true ; } ################################################# # # Section 4. Per-platform variable settings. # ################################################# # Flags for Perforce # # CASE_INSENSITIVE -- case folding server # ENUM_INT -- force enums to int sized for watcom # USE_CRLF -- ascii opened as binary needs special handling # USE_CR -- special CR <-> LF translation for mac # USE_EBCDIC -- ascii <-> ebcdic translation in rpc GENFLAGS = CCFLAGS C++FLAGS ; switch $(OS)$(OSVER) $(OS) { case AIX53 : C++ = g++ ; CC = gcc ; LINK = gcc ; C++FLAGS += -DBSD -Dunix -D_LARGE_FILES=1 ; LINKLIBS += -lsupc++ ; switch $(OSPLAT) { case PPC64 : $(GENFLAGS) += -maix64 ; LINKFLAGS += -maix64 ; AR = ar -X 64 -ru ; STRIP = strip -X 64 ; } case AS400 : CC = icc ; C++ = icc ; LINK = icc ; OPTIM = -O4 ; $(GENFLAGS) += -DUSE_EBCDIC ; LINKFLAGS += -qDUPPROC ; AR = qar -cru ; STRIP = ; ZEROCONF = none ; # This QSYS library must be pre-created before building QSYSLIB = p4 ; case CYGWIN : CC = gcc ; C++ = gcc ; LINK = g++ ; C++FLAGS += -DUSE_CRLF ; STRIP = ; case DARWIN : CC = cc ; C++ = cc ; C++FLAGS += -DCASE_INSENSITIVE ; case DARWIN60cs : #case-sensitive CC = cc ; C++ = cc ; LINK = g++ ; case DARWIN8* : CC = gcc ; C++ = g++ ; LINK = g++ ; MACOSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk ; MACOSX_SDK_FLAGS ?= -isysroot $(MACOSX_SDK) -mmacosx-version-min=10.4 ; $(GENFLAGS) += $(MACOSX_SDK_FLAGS) ; LINKFLAGS += $(MACOSX_SDK_FLAGS) ; LINKLIBS += -weak_framework CoreFoundation ; switch $(OSVER:U) { case *CS : case * : $(GENFLAGS) += -DCASE_INSENSITIVE ; } # OSPLAT=U : universal binary # Can't include x64 on darwin8 because CoreServices # doesn't include x64 symbols there. switch $(OSPLAT) { case PPC : _arch = -arch ppc ; case X86 : _arch = -arch i386 ; case U : _arch = -arch ppc -arch i386 ; NOARSCAN = true ; # can't scan "fat" archives } $(GENFLAGS) += $(_arch) -DOS_DARWIN80 ; LINKFLAGS += $(_arch) ; case DARWIN9* : CC = gcc ; C++ = g++ ; LINK = g++ ; # Use 10.5 SDK, but maintain ABI compatibility with 10.4. MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk ; MACOSX_SDK_FLAGS ?= -isysroot $(MACOSX_SDK) -mmacosx-version-min=10.4 ; $(GENFLAGS) += $(MACOSX_SDK_FLAGS) ; LINKFLAGS += $(MACOSX_SDK_FLAGS) ; LINKLIBS += -weak_framework CoreFoundation ; switch $(OSVER:U) { case *CS : case * : $(GENFLAGS) += -DCASE_INSENSITIVE ; } # OSPLAT=U : universal binary switch $(OSPLAT) { case PPC : _arch = -arch ppc ; case X86 : _arch = -arch i386 ; case X86_64 : _arch = -arch x86_64 ; case U : _arch = -arch ppc -arch i386 -arch x86_64 ; NOARSCAN = true ; # can't scan "fat" archives } $(GENFLAGS) += $(_arch) -DOS_DARWIN90 ; LINKFLAGS += $(_arch) ; case DARWIN10* : CC = gcc ; C++ = g++ ; LINK = g++ ; # Use 10.6 SDK, but maintain ABI compatibility with 10.4. MACOSX_SDK ?= /Developer/SDKs/MacOSX10.6.sdk ; MACOSX_SDK_FLAGS ?= -isysroot $(MACOSX_SDK) -mmacosx-version-min=10.4 ; $(GENFLAGS) += $(MACOSX_SDK_FLAGS) ; LINKFLAGS += $(MACOSX_SDK_FLAGS) ; LINKLIBS += -weak_framework CoreFoundation ; switch $(OSVER:U) { case *CS : case * : $(GENFLAGS) += -DCASE_INSENSITIVE ; } # OSPLAT=U : universal binary # There is no ppc support in osx 10.6 / darwin 10 switch $(OSPLAT) { case X86 : _arch = -arch i386 ; case X86_64 : _arch = -arch x86_64 ; case U : _arch = -arch i386 -arch x86_64 ; NOARSCAN = true ; # can't scan "fat" archives } $(GENFLAGS) += $(_arch) -DOS_DARWIN10 -DOS_DARWIN100 ; LINKFLAGS += $(_arch) ; case FREEBSD : Exit Set OSVER to 4, 5, or 6 for FreeBSD ; case FREEBSD4 : CC = gcc ; C++ = g++ ; LINK = gcc ; switch $(OSCOMP) { case GCC3 : LINKLIBS += -lsupc++ ; } if $(OSPLAT) != AXP { LINKFLAGS += -static ; } $(GENFLAGS) += -pipe ; ZEROCONF = avahi ; case FREEBSD[56789]* : CC = gcc ; C++ = g++ ; LINK = gcc ; # supc++ library on freebsd5.x and later is missing some # modules (this is a bug), so we can't use it. # Since every major version of the OS requires relinking # anyway, there's no harm in linking stdc++ dynamically. LINKLIBS += -lstdc++ ; _mflags = ; switch $(OSPLAT) { case X86 : _mflags = -m32 ; case X86_64 : _mflags = -m64 ; } $(GENFLAGS) += $(_mflags) -pipe ; LINKFLAGS += $(_mflags) ; QTOPENGL ?= no ; ZEROCONF = avahi ; case HPUX11 : switch $(OSPLAT:E)-$(OSCOMP:E) { # On IA64, hpux supports both 64-bit and 32-bit executables. # We build 64-bit for the benefit of p4d, and client apps are built # the same way for the sake of simplicity. case IA64-GCC : CC = gcc ; C++ = gcc ; $(GENFLAGS) += -mlp64 ; LINK = gcc ; LINKFLAGS += -mlp64 ; LINKLIBS += -lsupc++ -lunwind ; case IA64-* : # unbundled vendor compiler CC = aCC ; C++ = aCC ; OPTIM = +O1 ; if $(TYPE_PIC) { OPTIM += +Z ; } CCFLAGS += -Ae ; # treat .c files as C89, not C++ C++FLAGS += -Wc,-ansi_for_scope,on ; $(GENFLAGS) += +DD64 +noeh -z ; # Suppress compiler warnings: # 2611: overloaded virtual function "x" is only partially overridden in class "y" # 2997: function "x::fn is hidden by y::fn" -- virtual function override intended? # 2177: label "x" was declared but never referenced $(GENFLAGS) += +W2611,2997,2177 ; LINK = aCC ; # The +hideallsymbols linker option will generate a # lot of harmless warnings about being unable to hide # symbols that are undefined and need resolving # from the (dynamically linked) system libraries, # but see //depot/main/p4-doc/code/PORTING for rationale. LINKFLAGS += +DD64 +Oprocelim -z -Wl,+hideallsymbols,+stripunwind ; case PA11-* : # unbundled vendor compiler CC = aCC ; C++ = aCC ; LINK = aCC ; OPTIM = +O1 ; CCFLAGS += -Ae ; # treat .c files as C89, not C++ $(GENFLAGS) += -D_LARGEFILE64_SOURCE +DA1.1 ; case *-* : # assumed PA20 (32-bit) with unbundled vendor compiler CC = aCC ; C++ = aCC ; LINK = aCC ; OPTIM = +O1 ; CCFLAGS += -Ae ; # treat .c files as C89, not C++ $(GENFLAGS) += -D_LARGEFILE64_SOURCE ; } case IPHONE30 : # This is distinct from the MACOSX or DARWIN platforms # because the SDKs used are not compatible, and because # someday the iPhone may target both armv6 and i386. PLATFORM_ROOT ?= /Developer/Platforms/iPhoneOS.platform ; COMPILER_DIR ?= $(PLATFORM_ROOT)/Developer/usr/bin ; SDK_VERSION ?= iPhoneOS3.0.sdk ; IPHONE_SDK ?= $(PLATFORM_ROOT)/Developer/SDKs/$(SDK_VERSION) ; CC = $(COMPILER_DIR)/gcc ; C++ = $(COMPILER_DIR)/g++ ; LINK = $(COMPILER_DIR)/g++ ; RANLIB = $(COMPILER_DIR)/ranlib ; $(GENFLAGS) += -DCASE_INSENSITIVE -DOS_DARWIN -fpascal-strings -isysroot$(IPHONE_SDK) ; LINKFLAGS += -Wl,-syslibroot,$(IPHONE_SDK) ; # OSPLAT=U : universal binary (don't use this right now) switch $(OSPLAT) { case ARMV6 : _arch = -arch armv6 ; case ARMV7 : _arch = -arch armv7 ; case U : _arch = -arch armv6 -arch armv7 ; NOARSCAN = true ; # can't scan "fat" archives } $(GENFLAGS) += $(_arch) -DCASE_INSENSITIVE ; LINKFLAGS += $(_arch) ; case IRIX65 : CC = cc -OPT:Olimit 5000 -64 -mips3 ; C++ = CC -woff 3439,1174,1178,1681,1682 -OPT:Olimit 5000 -64 -mips3 ; LINK = CC -64 ; if $(TYPE_PIC) { OPTIM = -O2 -KPIC ; } case LINUX : Exit Set OSVER to 24 or 26 ; case LINUX2[46] : # If cross compiling on one platform for another, set # CROSS_COMPILE to the prefix of the cross tools. For # example, to build for ARM using an X86 host, set # CROSS_COMPILE="arm-none-linux-gnueabi-" and OSPLAT="ARM". CC = $(CROSS_COMPILE:E)gcc ; C++ = $(CROSS_COMPILE:E)g++ ; LINK = $(CROSS_COMPILE:E)gcc ; STRIP = $(CROSS_COMPILE:E)strip ; RANLIB = $(CROSS_COMPILE:E)ranlib ; LINKLIBS += -lsupc++ # Assumes gcc 3.x or later -ldl ; # for zeroconf # be explicit about submodel since we may be compiling x86 code on # an x86/x86_64 biarch system, and the default may be uncertain. _mflags = ; switch $(OSPLAT) { case X86 : _mflags = -m32 ; case X86_64 : _mflags = -m64 ; case ARM* : _mflags = -march=armv4t ; } if $(SMARTHEAP) = yes { $(GENFLAGS) += -DUSE_SMARTHEAP ; if $(TYPE_PIC) { $(GENFLAGS) += -DSHMEM_DEBUG ; } } $(GENFLAGS) += $(_mflags) -D_GNU_SOURCE ; LINKFLAGS += $(_mflags) ; QTOPENGL ?= no ; ZEROCONF = avahi ; case MACOSX : Exit Set OSVER to 104, 105, or 106 for MACOSX ; case MACOSX104 : # assumes using gcc 4.0.1 or newer CC = gcc ; C++ = g++ ; LINK = g++ ; MACOSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk ; MACOSX_SDK_FLAGS ?= -isysroot $(MACOSX_SDK) -mmacosx-version-min=10.4 ; $(GENFLAGS) += $(MACOSX_SDK_FLAGS) ; LINKFLAGS += $(MACOSX_SDK_FLAGS) ; # The -fvisibility-inlines-hidden option is a C++-only # option, needed because Qt4 is built with it and all # statically-compiled objects need to use it consistently. C++FLAGS += -fvisibility-inlines-hidden ; $(GENFLAGS) += -DCASE_INSENSITIVE -fpascal-strings ; # This looks like a flag but it is really a library macro # and causes link problems if it's at the front of the link # command, so we make it a LIB. LINKLIBS += -framework ApplicationServices -framework Foundation -framework CoreServices ; # OSPLAT=U : universal binary (no x86_64 for 10.4) switch $(OSPLAT) { case PPC : _arch = -arch ppc ; case X86 : _arch = -arch i386 ; case X86_64 : _arch = -arch x86_64 ; case U : _arch = -arch ppc -arch i386 ; NOARSCAN = true ; # can't scan "fat" archives } $(GENFLAGS) += $(_arch) ; LINKFLAGS += $(_arch) ; # This adds $(QTDIR)/lib as a frameworks directory, in case # Qt is built as frameworks. On the mac, it can be built # either as frameworks, regular unix-style shared # libraries, or unix-style static libaries. $(GENFLAGS) += -F$(QTDIR)/lib ; case MACOSX105 : # assumes using gcc 4.0.1 or newer CC = gcc ; # C++ = /Xcode4/usr/bin/clang -x c++ ; C++ = g++ ; LINK = g++ ; # Use the 10.5 SDK, but maintain ABI compatibility with 10.4. MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk ; MACOSX_SDK_FLAGS ?= -isysroot $(MACOSX_SDK) -mmacosx-version-min=10.4 ; $(GENFLAGS) += $(MACOSX_SDK_FLAGS) ; LINKFLAGS += $(MACOSX_SDK_FLAGS) ; # The -fvisibility-inlines-hidden option is a C++-only # option, needed because Qt4 is built with it and all # statically-compiled objects need to use it consistently. C++FLAGS += -fvisibility-inlines-hidden ; $(GENFLAGS) += -DCASE_INSENSITIVE -fpascal-strings ; # This looks like a flag but it is really a library macro # and causes link problems if it's at the front of the link LINKLIBS += -framework ApplicationServices -framework Foundation -framework CoreServices ; # OSPLAT=U : universal binary # # Omitting x86_64 from U until B&R's Qt builds include it. switch $(OSPLAT) { case PPC : _arch = -arch ppc ; case X86 : _arch = -arch i386 ; case X86_64 : _arch = -arch x86_64 ; case U : _arch = -arch ppc -arch i386 ; NOARSCAN = true ; # can't scan "fat" archives } $(GENFLAGS) += $(_arch) -DCASE_INSENSITIVE ; LINKFLAGS += $(_arch) ; # This adds $(QTDIR)/lib as a frameworks directory, in case # Qt is built as frameworks. On the mac, it can be built # either as frameworks, regular unix-style shared # libraries, or unix-style static libaries. $(GENFLAGS) += -F$(QTDIR)/lib ; case MACOSX106 : # assumes using gcc 4.0.1 or newer CC = gcc ; C++ = g++ ; LINK = g++ ; # Use the 10.6 SDK, but maintain ABI compatibility with 10.4. MACOSX_SDK ?= /Developer/SDKs/MacOSX10.6.sdk ; MACOSX_SDK_FLAGS ?= -isysroot $(MACOSX_SDK) -mmacosx-version-min=10.4 ; $(GENFLAGS) += $(MACOSX_SDK_FLAGS) ; LINKFLAGS += $(MACOSX_SDK_FLAGS) ; # The -fvisibility-inlines-hidden option is a C++-only # option, needed because Qt4 is built with it and all # statically-compiled objects need to use it consistently. C++FLAGS += -fvisibility-inlines-hidden ; $(GENFLAGS) += -DCASE_INSENSITIVE -fpascal-strings ; # This looks like a flag but it is really a library macro # and causes link problems if it's at the front of the link LINKLIBS += -framework ApplicationServices -framework Foundation -framework CoreServices ; # OSPLAT=U : universal binary # # Omitting x86_64 from U until B&R's Qt builds include it. # No PPC support in OSX 10.6. switch $(OSPLAT) { case X86 : _arch = -arch i386 ; case X86_64 : _arch = -arch x86_64 ; case U : _arch = -arch i386 ; } $(GENFLAGS) += $(_arch) -DCASE_INSENSITIVE ; LINKFLAGS += $(_arch) ; # This adds $(QTDIR)/lib as a frameworks directory, in case # Qt is built as frameworks. On the mac, it can be built # either as frameworks, regular unix-style shared # libraries, or unix-style static libaries. $(GENFLAGS) += -F$(QTDIR)/lib ; case MVS : # Set the following variables in your shell before # invoking jam # # _C89_CLIB_PREFIX="SYS1.CBC" # _C89_PLIB_PREFIX="SYS1.CEE" # _C89_SLIB_PREFIX="SYS1" # # _CC_CLIB_PREFIX="SYS1.CBC" # _CC_PLIB_PREFIX="SYS1.CEE" # _CC_SLIB_PREFIX="SYS1" # # _CXX_CLIB_PREFIX="SYS1.CBC" # _CXX_PLIB_PREFIX="SYS1.CEE" # _CXX_SLIB_PREFIX="SYS1" # # Note: some might not be required if all the aliases have # been set correctly # EBCDIC ?= yes ; CC = cc ; C++ = c++ -+ ; $(GENFLAGS) += -D_OE_SOCKETS -DNO_LONG_LONG ; if $(EBCDIC) != no { $(GENFLAGS) += -DUSE_EBCDIC ; } if $(ASCII) = yes { $(GENFLAGS) += -DNO_EBCDIC_FILES ; } LINK = c++ ; OPTIM = -O ; ZEROCONF = none ; case NETBSD* : OSCOMPDIR ?= /usr/pkg/gcc34/bin/ ; CC = $(OSCOMPDIR:E)gcc ; C++ = $(OSCOMPDIR:E)g++ ; LINK = $(OSCOMPDIR:E)gcc ; LINKLIBS += -lsupc++ ; $(GENFLAGS) += -pipe -Dunix ; # NetBSD gcc choked on -O2 -fPIC if $(TYPE_PIC) { OPTIM = -O1 -fPIC ; } case VMS* : # use C++ compiler: we're cheap CC = cxx ; C++ = cxx ; DEFINES += NO_MEMCPY ; STRIP = ; OPTIM = ; ZEROCONF = none ; case NT* : local _Z = /Zi ; # flag to put debug syms in .pdb file # Visual Studio 8 and earlier choke when writing .pdb files # to a networked drive; this variable provides a way to # override the pdb filename. Visual Studio 9 # (VS2008) and later apparently are ok. PDBFILENAME ?= $(EXEC)\\ ; if $(JAMFAST) { if $(PRODUCTION) { Exit Do not use JAMFAST with PRODUCTION, since JAMFAST embeds debug symbols directly in object files. ; } # Put debug syms directly in object files. # If running jam with -j2 or greater, using a .pdb database # for the debug symbols may cause locking failures from # parallel compilation processes trying to access it. _Z = /Z7 ; } switch $(BUILD) { # When we do API builds, we set BUILD=vs2003, vs2005, etc. # These builds should have neither /Zi nor /Z7 symbol # instrumentation, because we don't want to ship debug # symbols to our customers, either embedded in the # .obj/.lib files or in the .pdb database which the linker # would want provided. case vs2* : _Z = ; } BINDIR = e:\\perforce ; JAMSHELL ?= $(P4)\\Jamsh.bat $(OSPLAT) % "!" ; C++FLAGS += /DCASE_INSENSITIVE /DUSE_CRLF /wd4996 ; if $(SMARTHEAP) = yes { $(GENFLAGS) += /DUSE_SMARTHEAP ; if $(TYPE_PIC) { $(GENFLAGS) += /DSHMEM_DEBUG ; } } # Use setargv.obj to get wildcard expansion. # This is coupled with our own modified wildcard expander used by # setargv.obj in VS8 or later, per job030753. LINKLIBS = setargv.obj advapi32.lib oldnames.lib kernel32.lib ws2_32.lib ; if $(MSVSVER) >= 8 && ! $(TYPE_DYNAMIC) # 2008-10-17: static only for now { local _dyn ; if $(TYPE_DYNAMIC) = true { _dyn = -dyn ; } LINKLIBS += $(EXEC_LIB)/wild-vs$(MSVSVER)$(_dyn:E).obj ; } if $(OSPLAT) = IA64 { # When using the windows 2003 SDK on IA64, the /GS flag is # enabled by default but even if you disable it for our own # builds, the libraries provided with the SDK itself were build # with /GS, so there's no way to avoid having to link against # this library. # # See http://support.microsoft.com/?id=894573 LINKLIBS += bufferoverflowU.lib ; } # The "rc" tool needs MS headers: RCSTDHDRS = $(MSVCNT:J=" ")\\include $(MSVCNT:J=" ")\\atlmfc\\include ; STRIP = ; # Now, unset STDHDRS so Jam doesn't scan system headers (takes # too long when using compiler on networked machine): STDHDRS = ; if $(BCCROOT) { # Jeff Anton compiles with borland. OPTIM = -O2 ; RCFLAGS = /d NDEBUG /r ; AR = tlib /C /P128 ; LINKLIBS = $(BCCROOT)/lib/wildargs.obj ; } else if $(TYPE) = g { # Debugging build OPTIM = $(_Z) /Gm ; RCFLAGS = /d DEBUG /r ; LINKFLAGS += /DEBUG ; if $(CRT) = dyn { $(GENFLAGS) += /MDd ; } else { $(GENFLAGS) += /MTd ; } } else if $(TYPE) = dyn { # Dynamic link version, for qt products OPTIM = $(_Z) /O2 ; RCFLAGS = /d NDEBUG /r ; $(GENFLAGS) += /MD ; LINKFLAGS += /MAP /DEBUG /OPT:REF /OPT:ICF ; } else if $(TYPE) = dyng { # Dynamic Debugging build if $(JAMFAST) { OPTIM = $(_Z) ; } else { OPTIM = $(_Z) /Gm ; } RCFLAGS = /d DEBUG /r ; $(GENFLAGS) += /MDd ; LINKFLAGS += /DEBUG /NODEFAULTLIB:msvcrt.lib /fixed:no ; } else if $(TYPE) = vsdebug { # Static link with Visual Studio debug libraries. # This does not enable debugging our own code, just sets # linker dependencies for VS libraries. # This is intended for customer use. OPTIM = /O2 ; RCFLAGS = /d NDEBUG /r ; $(GENFLAGS) += /MTd ; } else if $(TYPE) = dyn_vsdebug { # Dynamic link with Visual Studio debug libraries. # This does not enable debugging our own code, just sets # linker dependencies for VS libraries. # This is intended for customer use. OPTIM = /O2 ; RCFLAGS = /d NDEBUG /r ; $(GENFLAGS) += /MDd ; } else if $(OSVER) = 98 { # Dynamic link version for win98 version of p4win # Goes into bin.win98 -- oddity. EXEC = [ FSubDirPath P4BIN bin.win98 ] ; ALL_LOCATE_TARGET = $(EXEC) ; OPTIM = /O2 ; if $(TYPE_DEBUG) = true { OPTIM += $(_Z) ; } RCFLAGS = /d NDEBUG /r ; $(GENFLAGS) += /MD ; LINKFLAGS = /MAP ; } else { # Static link version, for command line products OPTIM = /O2 $(_Z) ; RCFLAGS = /d NDEBUG /r ; if $(CRT) = dyn { $(GENFLAGS) += /MD ; } else { $(GENFLAGS) += /MT ; } LINKFLAGS += /MAP /DEBUG /OPT:REF /OPT:ICF ; } if $(OSPLAT) = X64 { # 64 bit windows needs increased stack size, so # we're doubling the stack from 2mb to 4mb. # See job31737. LINKFLAGS on p4d.exe = $(LINKFLAGS) /STACK:4194304 ; } case QNXNTO* : CC = cc ; C++ = cc ; LINKLIBS += -lsocket ; case SCO* : C++ = gcc ; CC = gcc ; LINK = gcc ; LINKLIBS += -lsocket ; case SOLARIS* : switch $(OSCOMP) { case SUNC11 : # Sun Studio 11 # Recommended jam flags: -sOSCOMP=SUNC11 -sBUILD=suncc # Add -sTYPE=pic for api. CC = CC ; C++ = CC ; LINK = CC ; OPTIM = -xO3 ; if $(TYPE_PIC) { OPTIM += -KPIC ; } switch $(OSPLAT) { case *64 : $(GENFLAGS) += -xarch=generic64 ; LINKFLAGS += -xarch=generic64 ; } case SUNC12 : # Sun Studio 12 # Recommended jam flags: -sOSCOMP=SUNC12 -sBUILD=suncc # Add -sTYPE=pic for api. CC = CC ; C++ = CC ; LINK = CC ; OPTIM = -xO3 ; if $(TYPE_PIC) { OPTIM += -KPIC ; } switch $(OSPLAT) { case *64 : $(GENFLAGS) += -m64 ; LINKFLAGS += -m64 ; } case * : # GCC CC = gcc ; C++ = g++ ; LINK = gcc ; switch $(OSPLAT) { case *64 : # X86_64 or SPARC64 LINKFLAGS += -m64 ; $(GENFLAGS) += -m64 ; } # supc++ needed for all apps since we use gcc >= 3.2. LINKLIBS += -lsupc++ ; } $(GENFLAGS) += -I/opt/lude/include -Dsolaris -D_LARGEFILE64_SOURCE # NO_VIZ disables the use of the `hidden' symbol # visibility attribute used by gcc in zlib/zutil.h. # Solaris 10 x86 still uses a gcc 3.x compiler which # does not properly support this attribute. -DNO_VIZ ; LINKLIBS += -lsocket -lnsl ; AR = /usr/ccs/bin/ar ru ; STRIP = /usr/ccs/bin/strip ; QTOPENGL ?= no ; case * : Exit Don't know "$(OS)$(OSVER) or " $(OS) ; } # Set build flags for chosen Zeroconf implementation if $(ZEROCONF) = bonjour { DEFINES += USE_BONJOUR ; } if $(ZEROCONF) = avahi { DEFINES += USE_AVAHI ; } if $(UNIX) { # Don't fail if directory already exists. MKDIR = mkdir -p ; } ################################################# # # Section 5. Perforce-special rules and actions. # ################################################# # # Special Rules # # FRemoveAny x : y ; - return new array of x minus any values in y # FRegexpQuote list ; - quote regexp metacharacters into literals # FDirEntries path : pat ; - return a list of files matching pat in path # DefineVar src : var ; - define a var for src compilation # Ident exe ; - define bits for program ident string # ListAC ??? ; # P4ClientHdrs ; - add all p4 client headers for building Web, ftp # P4Library lib : src ; - Library of P4 client libs # P4DLibrary lib : src ; - Library of P4D server libs # Strip exe ; - strip executable of symbols after building # CopyRec target : dstdir : srcdir : excludes ; - recursively copy srcdir into dstdir # # And build packaging rules # # P4APIMakeDir apiname : files ; build api dist structure # P4Api apiname : files ; make archive files of api dist structure # MkDistArchive file : directory ; calls appropriate action based on file extension # MakeP4ObjCdist file ; Create Objective C API package # MakeP4DTGdist file ; Create p4dtg package # MakeP4ThumbDist file ; Create p4thumb package # MakeP4Vdist ; create p4v.tgz on unix systems or P4V.dmg on macosx rule FRemoveAny { # Usage: y = [ FRemoveAny $(x) : v1 v2 ... ] ; # returns new array with any occurence of v1, v2, etc from $(x) elided local _new ; local _elt ; for _elt in $(1) { if ! ( $(_elt) in $(2) ) { _new += $(_elt) ; } } return $(_new) ; } rule FRegexpQuote { # FRegexpQuote list ; # Quote any egrep(1) regexp metacharacters in elements of # list such that they will only match a literal expression. # Returns the quoted list. local result ; local p ; for p in $(<) { local q ; while (1) { local r = [ Match ^([^][()*+.?\\]*)([][()*+.?\\])(.*) : $(p) ] ; q += $(r[1]) ; if $(r[2]) = "" { q += $(p) ; break ; } q += \\$(r[2]) ; p = $(r[3]) ; } result += $(q:J=) ; } return $(result) ; } rule FDirEntries { # Usage: files = [ FDirEntries path to directory : pat ] ; # Returns list of entries in directory which match pat (default '*') local dir = [ FDirName $(<) ] ; local pat = $(>) ; if ! $(pat) { pat = "*" ; } local ents = [ Glob $(dir) : $(pat) ] ; # => d/. d/.. d/a d/b # We need to quote windows directories because they use # backslashes, and those are regexp metacharacters. # Safer on unix too. local re = [ FRegexpQuote $(dir)$(SLASH) ] ; ents = [ Match $(re)(.*) : $(ents) ] ; # => . .. a b return [ FRemoveAny $(ents) : $(DOT) $(DOTDOT) ] ; # return minus . and .. } rule DefineVar { # Usage: DefineVar foo.cc : VARNAME # Defines it if set if $($(>)) { ObjectDefines $(<) : [ Fconcat $(>)= [ FQuote \"$($(>))\" ] ] ; } } rule Ident { # Set up special defines local osid = $(OS)$(OSVER:E)$(OSPLAT:E) ; rule Fconcat { return $(<:J) ; } ObjectDefines $(<) : [ Fconcat ID_OS= [ FQuote $(osid[1]:U) ] ] [ Fconcat ID_REL= [ FQuote $(RELEASE:J=.) ] ] [ Fconcat ID_PATCH= [ FQuote $(PATCHLEVEL)$(SPECIAL:E) ] ] [ Fconcat ID_Y= [ FQuote $(SUPPDATE[1]) ] ] [ Fconcat ID_M= [ FQuote $(SUPPDATE[2]) ] ] [ Fconcat ID_D= [ FQuote $(SUPPDATE[3]) ] ] ; # Source file includes Version Includes [ FGristSourceFiles $(<) ] : Version ; } rule ListAC { # Special jam trickery to display AC numbers with "jam AC" NOTFILE $(<) ; ALWAYS $(<) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; Depends $(<) : $(>) ; } actions ListAC { $(AWK) 'BEGIN {L=0; FS=","} /AC_/ {print L, $1; L++}' $(>) } rule MacRes { local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; Depends $(_t) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; } rule MacCreatorCode { switch $(<) { case p4v : return P4VC ; case p4merge : return P4MG ; case * : return ttxt ; } } rule P4ClientHdrs { # P4ClientHdrs ; - add p4 client headers for building Web, ftp SubDirHdrs $(P4) client ; SubDirHdrs $(P4) diff ; SubDirHdrs $(P4) i18n ; SubDirHdrs $(P4) middle ; SubDirHdrs $(P4) net ; SubDirHdrs $(P4) web ; } rule BoostHdrs { # Include boost without jam-crawling its maze of headers. # Don't use SubDirHdrs: Jam locks up if it tries to crawl boost. SubDirC++Flags -I$(BOOSTDIR) -I$(BOOSTDIR)/tr1 -I$(BOOSTDIR)/boost/tr1 ; } rule P4Library { Library $(<) : $(>) ; } rule P4DLibrary { if $(BUILD_P4D) { Library $(<) : $(>) ; } } rule P4Main { Main $(<) : $(>) ; Strip $(<) ; if $(BINDIR) { InstallBin $(BINDIR) : $(<) ; } } rule P4DMain { if $(BUILD_P4D) { P4Main $(<) : $(>) ; } else { P4NoBuild $(<) : BUILD_P4D ; } } rule P4NoBuild { NotFile $(>) ; } actions quietly P4NoBuild { echo Set $(>) to force build of $(<). } rule LinkLibraries { # NB this is superfluous in jam 2.6 # make library dependencies of target # set NEEDLIBS variable used by 'actions Main' local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; local _s = [ FAppendSuffix $(>) : $(SUFLIB) ] ; Depends $(_t) : $(_s) ; NEEDLIBS on $(_t) += $(_s) ; } rule Strip { on $(<) if $(STRIP) && ! $(TYPE_DEBUG) { Strip1 $(<:S=$(SUFEXE)) ; } } actions Strip1 { $(STRIP) $(<) } # CopyRec target : dstdir : srcdir : excludes ; # Recursively copies the contents of srcdir into dstdir # target is a non-file token to use for dependency generation # excludes are directory or file names not to copy. rule CopyRec { local target = $(1) ; local dst = [ FDirName $(2) ] ; local src = [ FDirName $(3) ] ; local excludes = $(4) ; local filepat = $(5) ; # Avoid duplicate recursion/dependencies if we've seen this # target already. if $($(dst)-CopyRec-seen) { return ; } $(dst)-CopyRec-seen = 1 ; NotFile $(target) ; # ents will be empty if src is not a directory local ents = [ Glob $(src) : * ] ; # => src/. src/.. src/a src/b if $(ents) { Depends $(target) : $(dst:G=dir) ; MkDir $(dst:G=dir) ; ents = [ FDirEntries $(src) ] ; local sub ; for sub in $(ents) { if $(sub) in $(excludes) { continue ; } CopyRec $(target) : $(dst) $(sub) : $(src) $(sub) : $(excludes) : $(filepat) ; } } else { if $(filepat) { local dir = $(src:P) ; local matches = [ Glob $(dir) : $(filepat) ] ; if ! $(src) in $(matches) { return ; } } local pdst = $(dst:PG=dir) ; Depends $(target) : $(dst) ; Depends $(dst) : $(pdst) ; MkDir $(pdst) ; if $(UNIX) { # For a recursive copy on unix we want to try to preserve # file timestamps and permissions (e.g. they might be # executables plain files). local CHMOD = ; CP on $(dst) = $(CP) -p ; File $(dst) : $(src) ; } else { File $(dst) : $(src) ; } } } rule P4APIDirName { # P4APIDirName apiname ; # # The API should be copied into a temp subdirectory by P4APIMakeDir # and the API files copied into it. # # This rule computes the name of that directory, and the name of # the tar/zip file that it should be packed into, and returns a # list of those two names. # # This is a subroutine for clarity purposes, and is use both by # P4APIMakeDir and the DTG sdk builds to compute P4DIR. local _sep = "." ; # directory name field separator if $(VMS) { _sep = "_" ; } # _dirname - apiname-releaseinfo # on nt: apiname-releaseinfo-build_type local _dirname = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; _dirname = $(<)-$(_dirname:J=$(_sep)) ; local _arcname = $(<) ; if $(NT) { local _ntsuffix ; switch $(TYPE) { case dyn* : _ntsuffix = $(BUILD) $(TYPE) ; case opt : _ntsuffix = $(BUILD) static ; case * : _ntsuffix = $(BUILD) static $(TYPE) ; } _dirname = $(_dirname)-$(_ntsuffix:J=_) ; _arcname = $(<)_$(_ntsuffix:J=_) ; } return $(_dirname) $(_arcname) ; } rule P4APIMakeDir { # P4APIMakeDir apiname : files ; # # Builds a temp subdirectory $(EXEC)/apiname-releaseinfo # and copies the API files into it. # # Returns a list consisting of the api directory name # (usually api-releaseinfo, but possibly # api-releasinfo_build_type on NT), and the archive file # name (minus final suffix) into which the directory should # be stored. # # This is a subroutine for clarity purposes and probably # shouldn't be used directly except by the P4API rule. local _dirname_data = [ P4APIDirName $(<) ] ; local _dirname = $(_dirname_data[1]) ; local _arcname = $(_dirname_data[2]) ; local _cpflags ; if $(UNIX) { _cpflags = -p ; # to preserve times with cp -p } NotFile api ; Depends all : api ; MakeLocate $(_dirname) : $(EXEC) ; Depends api : $(_dirname) ; # SEARCH_SOURCE -- where api files are found (all over) local SEARCH_SOURCE = $(HDRS) $(SUBDIRHDRS) $(SUBDIR) $(P4) ; # for each target file, copy to named temp directory # create mini structure (include/p4, lib, sample directories) local _f ; for _f in $(>) { local _d _t ; # Note that for .h and .cc files we use different # grist $(x:G=alt), to distinguish these targets from # the ones used in compiles. We don't want #include # processing on these. switch $(_f) { case *.h : _d = include p4 ; _f = $(_f:G=alt) ; case *.a : _d = lib ; case *.lib : _d = lib ; case *.olb : _d = lib ; # VMS library archive case *.cc : _d = sample ; _f = $(_f:G=alt) ; case * : _d = sample ; } _t = $(_f:G=$(<)) ; # target switch $(_t:G=) { case Jamfile.api : _t = $(_t:S=) ; # remove .api suffix in target } _d = [ FDirName $(EXEC) $(_dirname) $(_d) ] ; # directory CP on $(_t) = $(CP) $(_cpflags) ; MakeLocate $(_t) : $(_d) ; File $(_t) : $(_f) ; Depends api : $(_t) ; Clean clean : $(_t) ; } return $(_dirname) $(_arcname) ; } rule P4Api { # P4Api apiname : files ; # # Builds a temporary subdirectory $(EXEC)/apiname-releaseinfo # and makes a tarball apiname.tar of that stuff. # _dirname - apiname-releaseinfo # on nt: apiname-releaseinfo-build_type local _apidata = [ P4APIMakeDir $(<) : $(>) ] ; local _dirname = $(_apidata[1]) ; local _arcname = $(_apidata[2]) ; local _tar = $(_arcname:S=.tar) ; local _tgz = $(_arcname:S=.tgz) ; local _zip = $(_arcname:S=.zip) ; local _bck = $(_arcname:S=.bck) ; local _targets = $(_tar) $(_tgz) $(_zip) ; if $(NT) { # This allows one to still be able to run the # command "jam p4api.tar" and have it work, even # though the actual file name will vary. Depends $(<:S=.tar) : $(_tar) ; Depends $(<:S=.tgz) : $(_tgz) ; Depends $(<:S=.zip) : $(_zip) ; } else if $(VMS) { _targets += $(_bck) ; } LOCATE on $(_targets) = $(EXEC) ; Depends $(_targets) : api ; MkTarArchive $(_tar) : $(_dirname) ; MkComressedTarArchive $(_tgz) : $(_dirname) ; MkZipArchive $(_zip) : $(_dirname) ; if $(VMS) { MkBckArchive $(_bck) : $(_dirname) ; } } rule MkDistArchive { local _trg ; for _trg in $(<) { switch $(_trg:S) { case .tar : MkTarArchive $(_trg) : $(>) ; case .tgz : MkComressedTarArchive $(_trg) : $(>) ; case .tar.gz : MkComressedTarArchive $(_trg) : $(>) ; case .zip : MkZipArchive $(_trg) : $(>) ; case .bck : MkBckArchive $(_trg) : $(>) ; case * : exit "Don't know how to make $(_trg)" ; } } } # Args: [bin.dir] name : files ... ; # # Will create targets name.tgz and name.zip # which unpack into a single directory named "name-<version>" # containing all of the remaining files. # # The tar files will go in the normal bin.<os><osver><osplat>/$BUILD # directory unless the first parameter lists the target directory # (relative to p4-bin). A common use case would be bin.tools. # # Will not preserve directory hierarchy of files listed in 2nd # parameter, so avoid duplicate names. rule MakeFlatFilesDist { local bindir = bin.$(OS:L)$(OSVER:EL)$(OSPLAT:EL) ; local pkg = $(1[1]) ; if $(1[2]) { bindir = $(1[1]) ; pkg = $(1[2]) ; } local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = $(pkg)-$(release_info:J=.) ; local exec_dir = [ FSubDirPath P4BIN $(bindir) $(BUILD) ] ; local dest_dir = [ FDirName $(exec_dir) $(dirname) ] ; local dist = $(pkg)-dist ; local _cpflags ; if $(UNIX) { _cpflags = -p ; # to preserve times with cp -p } Depends $(dist) : $(dest_dir) ; MkDir $(dest_dir) ; local _src ; for _src in $(2) { local _dst = $(_src:D=$(dest_dir):G=) ; SEARCH_SOURCE on $(_src) = $(exec_dir) $(SUBDIR) $(AllP4) ; CP on $(_dst) = $(CP) $(_cpflags) ; Depends $(dist) : $(_dst) ; Depends $(_dst) : $(dest_dir) ; File $(_dst) : $(_src) ; } local _ext ; for _ext in tgz zip { local archive = $(pkg).$(_ext) ; LOCATE on $(archive) = $(exec_dir) ; Depends all : $(archive) ; Depends $(archive) : $(dist) ; MkDistArchive $(archive) : $(dest_dir) ; } } rule MakeBrowseDist { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = browse-$(release_info:J=.) ; local exec_dir = [ FSubDirPath P4BIN bin.tools $(BUILD) ] ; local _f ; if ! $(browse-dist-dir-DONE) { browse-dist-dir-DONE = true ; MakeLocate $(dirname) : $(exec_dir) ; Depends browse-dist : $(dirname) ; local topdir = $(exec_dir) $(dirname) ; # Copy browse benchmarks scripts, documentation, etc., # excluding all Jamfile and Jamrules files. CopyRec browse-dist : $(topdir) : $(AllP4) p4-tools benchmarks browse : Jamfile Jamrules ; # Change permissions on the browse private key so that # it can be successfully used with the user's SSH daemon. _f = [ FDirName $(topdir) browse ] ; MODE on $(_f) = 400 ; Chmod $(_f) ; # Change permissions on the browse JavaScript so that the configuration # defined within can be edited by the user, and change the line-endings # so that it can be easily edited using most Windows utilities. _f = [ FDirName $(topdir) browse.js ] ; MODE on $(_f) = 644 ; Chmod $(_f) ; Unix2Dos $(_f) ; # Change permissions on the browse Bourne shell script so that # the configuration defined within can be edited by the user. _f = [ FDirName $(topdir) browse.sh ] ; MODE on $(_f) = 755 ; Chmod $(_f) ; # Copy browsechild binaries for all platforms on which it was built. for _f in [ FDirEntries $(P4BIN) : bin.* ] { local bindir = [ FDirName $(P4BIN) $(_f) ] ; local prog = [ FDirEntries $(bindir) : browsechild browsechild.exe ] ; local _g ; for _g in $(prog) { CopyRec browse-dist : $(topdir) $(_f) $(_g) : $(bindir) $(_g) ; } } } LOCATE on $(<) = $(exec_dir) ; Depends $(<) : browse-dist ; Depends all : $(<) ; MkDistArchive $(<) : $(dirname) ; } rule MakeP4ObjCdist { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4objc-$(release_info:J=.) ; local exec_dir = [ FSubDirPath P4BIN bin.tools $(BUILD) ] ; MakeLocate $(dirname) : $(exec_dir) ; Depends p4objc-dist : $(dirname) ; local topdir = $(exec_dir) $(dirname) ; CopyRec p4objc-dist : $(topdir) LICENSE.txt : $(AllP4) p4-objc LICENSE.txt ; CopyRec p4objc-dist : $(topdir) api : $(AllP4) p4-objc api ; CopyRec p4objc-dist : $(topdir) doc : $(AllP4) p4-objc doc ; # When we copy images from the sample, we want to exclude # the ones that we override from the watermarked images # directory. So exclude those (and the watermark images # directory itself), then copy the watermarked ones in. local watermark_dir = $(AllP4) p4-objc sample resources images_watermarked ; local watermark_excludes = [ FDirEntries $(watermark_dir) ] ; local all_excludes = build ._build images_watermarked $(watermark_excludes) ; CopyRec p4objc-dist : $(topdir) sample : $(AllP4) p4-objc sample : $(all_excludes) ; # Now copy in the watermarked images local _ent ; for _ent in $(watermark_excludes) { CopyRec p4objc-dist : $(topdir) sample resources images $(_ent) : $(watermark_dir) $(_ent) ; } LOCATE on $(<) = $(exec_dir) ; Depends $(<) : p4objc-dist ; Depends all : $(<) ; MkDistArchive $(<) : $(dirname) ; } rule MakeP4ScoutDist { local kind = $(<) ; local appdir = <$(kind)>P4Scout.app ; local zipfiles = $(kind)-$(appdir:G=).zip $(kind)-$(appdir:G=).dSYM.zip ; local srcdir = $(AllP4) p4-objc sample ; SCOUTSRCDIR on $(appdir) = [ FDirName $(srcdir) ] ; Depends p4scout-dist : p4scout-dist-$(kind) ; Depends p4scout-dist-$(kind) : $(appdir) ; Depends $(appdir) : p4api.tgz ; LOCATE on $(zipfiles) = $(EXEC) ; Depends $(zipfiles) : $(appdir) ; on $(appdir) NOTFILE $(kind) ; P4Scout_xcodebuild $(appdir) : $(kind) ; } rule MakeP4PHPdist { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4php-$(release_info:J=.) ; local exec_dir = [ FSubDirPath P4BIN bin.tools $(BUILD) ] ; local topdir = $(exec_dir) $(dirname) ; MakeLocate $(dirname) : $(exec_dir) ; Depends p4php-dist : $(dirname) ; local excludes = docs [ FDirEntries $(AllP4) p4-php : Jam* *~ ] ; CopyRec p4php-dist : $(topdir) : $(AllP4) p4-php : $(excludes) ; CopyRec p4php-dist : $(topdir) RELNOTES.txt : $(AllP4) p4-doc user p4phpnotes.txt ; CopyRec p4php-dist : $(topdir) Version : $(AllP4) p4 Version ; LOCATE on $(<) = $(exec_dir) ; Depends $(<) : p4php-dist ; Depends all : $(<) ; MkDistArchive $(<) : $(dirname) ; } rule MakeP4DTGdist { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4dtg-$(release_info:J=.) ; local topdir = $(EXEC) $(dirname) ; local bugz_docdir = $(EXEC) $(dirname) doc bugz3mysql5 ; local mysql_docdir = $(EXEC) $(dirname) doc mysql5 ; local jira_docdir = $(EXEC) $(dirname) doc jira ; local redmine_docdir = $(EXEC) $(dirname) doc redminesql5 ; local jira_jardir = $(EXEC) $(dirname) jira ; MakeLocate $(dirname) : $(EXEC) ; Depends p4dtg-dist : $(dirname) ; CopyRec p4dtg-dist : $(topdir) p4dtg-config : p4dtg-config ; CopyRec p4dtg-dist : $(topdir) p4dtg-test : p4dtg-test ; CopyRec p4dtg-dist : $(topdir) p4dtg-repl : p4dtg-repl ; CopyRec p4dtg-dist : $(topdir) plugins p4jobdt.so : p4jobdt.so ; CopyRec p4dtg-dist : $(topdir) plugins mysql5.so : mysql5.so ; CopyRec p4dtg-dist : $(topdir) plugins bugz3mysql5.so : bugz3mysql5.so ; CopyRec p4dtg-dist : $(topdir) plugins redminemysql5.so : redminemysql5.so ; CopyRec p4dtg-dist : $(topdir) plugins jiradtg.so : jiradtg.so ; CopyRec p4dtg-dist : $(topdir) p4dtg-config.png : $(P4DTG) src p4dtg-config p4dtg-config.png ; CopyRec p4dtg-dist : $(topdir) p4dtgnotes.txt : $(AllP4) p4-doc user p4dtgnotes.txt ; CopyRec p4dtg-dist : $(topdir) p4dtg.pdf : $(AllP4) p4-doc manuals p4dtg p4dtg.pdf ; CopyRec p4dtg-dist : $(topdir) help : $(AllP4) p4-doc help p4dtg ; CopyRec p4dtg-dist : $(bugz_docdir) patch.bugzilla-3 : $(P4DTG) sdk bugz patch.bugzilla-3 ; CopyRec p4dtg-dist : $(bugz_docdir) patch.bugzilla-3.4 : $(P4DTG) sdk bugz patch.bugzilla-3.4 ; CopyRec p4dtg-dist : $(bugz_docdir) patch.bugzilla-3.6.2 : $(P4DTG) sdk bugz patch.bugzilla-3.6.2 ; CopyRec p4dtg-dist : $(bugz_docdir) README.txt : $(P4DTG) sdk bugz README.txt ; CopyRec p4dtg-dist : $(bugz_docdir) README.p4dti.txt : $(P4DTG) sdk bugz README.p4dti.txt ; CopyRec p4dtg-dist : $(bugz_docdir) mk_dtgdtissue.pl : $(P4DTG) sdk bugz mk_dtgdtissue.pl ; CopyRec p4dtg-dist : $(bugz_docdir) dti_to_dtg.pl : $(P4DTG) sdk bugz dti_to_dtg.pl ; CopyRec p4dtg-dist : $(bugz_docdir) changeid.pl : $(P4DTG) sdk bugz changeid.pl ; CopyRec p4dtg-dist : $(bugz_docdir) jobspec.txt : $(P4DTG) sdk bugz jobspec.txt ; CopyRec p4dtg-dist : $(mysql_docdir) README.txt : $(P4DTG) sdk mysql README.txt ; CopyRec p4dtg-dist : $(mysql_docdir) import.pl : $(P4DTG) sdk mysql import.pl ; CopyRec p4dtg-dist : $(redmine_docdir) README.txt : $(P4DTG) sdk redmine README.txt ; CopyRec p4dtg-dist : $(redmine_docdir) jobspec.txt : $(P4DTG) sdk redmine jobspec.txt ; CopyRec p4dtg-dist : $(jira_docdir) README.txt : $(P4DTG) sdk jira README.txt ; CopyRec p4dtg-dist : $(jira_docdir) jobspec.txt : $(P4DTG) sdk jira jobspec.txt ; CopyRec p4dtg-dist : $(jira_jardir) jira-dts.jar : $(P4DTG) sdk jira jiradts dist jira-dts.jar ; CopyRec p4dtg-dist : $(jira_jardir) jira-soapclient-4.1.1-1.jar : $(P4DTG) sdk jira jiradts lib jira-soapclient-4.1.1-1.jar ; local axis_files = axis.jar axis.LICENSE commons-discovery-0.2.jar commons-discovery-0.2.LICENSE commons-logging-1.0.4.jar commons-logging-1.0.4.LICENSE jaxrpc.jar saaj.jar wsdl4j-1.5.1.jar wsdl4j-1.5.1-sources.jar wsdl4j-1.5.1.LICENSE ; local _a ; for _a in $(axis_files) { CopyRec p4dtg-dist : $(jira_jardir) $(_a) : $(AllP4) .. import axis axis-1_4 lib $(_a) ; } local empty_dirs = config repl ; local _d ; for _d in $(empty_dirs) { _d = [ FDirName $(topdir) $(_d) ] ; MkDir $(_d:G=dir) ; Depends p4dtg-dist : $(_d:G=dir) ; } local _strip_bin = p4dtg-config p4dtg-repl p4dtg-test ; local _strip_lib = bugz3mysql5.so p4jobdt.so mysql5.so redminemysql5.so jiradtg.so ; local _f ; for _f in $(_strip_bin) { _f = [ FDirName $(topdir) $(_f) ] ; Strip $(_f) ; } for _f in $(_strip_lib) { _f = [ FDirName $(topdir) plugins $(_f) ] ; STRIP on $(_f) = $(STRIP) -x ; Strip1 $(_f) ; } LOCATE on $(<) = $(EXEC) ; Depends $(<) : p4dtg-dist ; Depends all : $(<) ; MkDistArchive $(<) : $(dirname) ; } rule MakeP4ThumbDist { local topdir ; if $(OS) = NT { # Hopefully this is temporary, to be replaced with a proper installer. topdir = p4thumb ; local bindir = $(EXEC) $(topdir) ; local libdir = $(EXEC) $(topdir) ; local rscdir = $(EXEC) $(topdir) ; MakeLocate $(topdir) : $(EXEC) ; Depends p4thumb-dist : $(topdir) ; CopyRec p4thumb-dist : $(bindir) p4thumb.exe : p4thumb.exe ; CopyRec p4thumb-dist : $(bindir) vcredist_x86.exe : $(EXEC_LIB) vcredist_x86.exe ; CopyRec p4thumb-dist : $(bindir) assistant.exe : $(EXEC_LIB) assistant.exe ; CopyRec p4thumb-dist : $(libdir) plugins : $(EXEC_LIB) qt4 plugins : : *.dll ; CopyRec p4thumb-dist : $(rscdir) p4thumbnotes.txt : $(AllP4) p4-doc user p4thumbnotes.txt ; CopyRec p4thumb-dist : $(rscdir) translations : $(EXEC_LIB) qt4 translations ; for _f in p4thumb_$(QtLanguages).qm { CopyRec p4thumb-dist : $(rscdir) translations $(_f) : $(_f) ; } local Qtdlls = [ FDirEntries $(EXEC_LIB) : *4.dll ] ; local _dll ; for _dll in $(Qtdlls) { CopyRec p4thumb-dist : $(libdir) $(_dll) : $(EXEC_LIB) $(_dll) ; } MakeQtConf p4thumb-dist : $(bindir) ; } else { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; topdir = p4thumb-$(release_info:J=.) ; local bindir = $(EXEC) $(topdir) bin ; local libdir = $(EXEC) $(topdir) lib p4v ; local rscdir = $(EXEC) $(topdir) lib p4v P4VResources ; MakeLocate $(topdir) : $(EXEC) ; Depends p4thumb-dist : $(topdir) ; CopyRec p4thumb-dist : $(bindir) p4thumb.bin : p4thumb ; CopyRec p4thumb-dist : $(bindir) p4thumb : $(AllP4) p4-qt apps p4v p4vwrapper.sh ; CopyRec p4thumb-dist : $(libdir) qt4 : $(EXEC_LIB) qt4 ; CopyRec p4thumb-dist : $(rscdir) translations : $(EXEC_LIB) qt4 translations ; for _f in p4thumb_$(QtLanguages).qm { CopyRec p4thumb-dist : $(rscdir) translations $(_f) : $(_f) ; } MakeQtConf p4thumb-dist : $(bindir) ; STRIP on [ FDirName $(bindir) p4thumb.bin ] = $(STRIP) -x ; Strip1 [ FDirName $(bindir) p4thumb.bin ] ; } LOCATE on $(<) = $(EXEC) ; Depends $(<) : p4thumb-dist ; Depends all : $(<) ; MkDistArchive $(<) : $(topdir) ; } rule MakeP4Vdist { if $(OS) = MACOSX { MakeP4Vdist_macosx $(<) ; } else if $(UNIX) { MakeP4Vdist_unix $(<) ; } # TODO: Add switch for NT to build installer } rule MakeP4Vdist_unix { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local topdir = p4v-$(release_info:J=.) ; local bindir = $(EXEC) $(topdir) bin ; local libdir = $(EXEC) $(topdir) lib p4v ; local rscdir = $(EXEC) $(topdir) lib p4v P4VResources ; local helpsrc = $(AllP4) p4-doc help ; local _f ; MakeLocate $(topdir) : $(EXEC) ; Depends p4v-dist : $(topdir) ; ## Copy in the qt-based commands with shell wrapper local qtcmd = p4v p4merge p4admin ; for _f in $(qtcmd) { CopyRec p4v-dist : $(bindir) $(_f).bin : $(_f) ; CopyRec p4v-dist : $(bindir) $(_f) : $(AllP4) p4-qt apps p4v p4vwrapper.sh ; # Make sure they're all at least stripped of local symbols _f = [ FDirName $(bindir) $(_f).bin ] ; STRIP on $(_f) = $(STRIP) -x ; Strip1 $(_f) ; } ## Offline broker and server components. local p4ddir = $(EXEC) ; if $(TYPE_DYNAMIC) { p4ddir += .. ; } CopyRec p4v-dist : $(rscdir) p4d : $(p4ddir) p4d ; CopyRec p4v-dist : $(rscdir) p4ob : p4ob ; _f = [ FDirName $(rscdir) p4ob ] ; STRIP on $(_f) = $(STRIP) -x ; Strip1 $(_f) ; ## Assistant executable CopyRec p4v-dist : $(bindir) assistant : $(EXEC_LIB) assistant_dyn ; # Libraries, plugins, qt standard translation catalogs CopyRec p4v-dist : $(libdir) qt4 lib : $(EXEC_LIB) qt4 lib ; CopyRec p4v-dist : $(libdir) qt4 plugins : $(EXEC_LIB) qt4 plugins ; CopyRec p4v-dist : $(rscdir) translations : $(EXEC_LIB) qt4 translations ; ## Image resources CopyRec p4v-dist : $(rscdir) images.rcc : images.rcc ; # job034811 - people use these for shortcut icons CopyRec p4v-dist : $(rscdir) icons : $(helpsrc) icons ; ## Documentation for _f in $(QtLanguages) { # FIXME (noahf): This is almost ready but needs some runtime (nfs locking) debugging # For now we are just copying pre-built collections below. #QtHelpGen : $(helpsrc) p4v-html-pure $(_f) p4vhelp_$(_f).qhp ; #QtHelpCollectionGen : $(helpsrc) p4v-html-pure $(_f) p4vhelp_$(_f).qhcp ; # #QtHelpGen : $(helpsrc) p4merge $(_f) p4mergehelp_$(_f).qhp ; #QtHelpCollectionGen : $(helpsrc) p4merge $(_f) p4mergehelp_$(_f).qhcp ; # #QtHelpGen : $(helpsrc) p4admin-html-pure $(_f) p4adminhelp_$(_f).qhp ; #QtHelpCollectionGen : $(helpsrc) p4admin-html-pure $(_f) p4adminhelp_$(_f).qhcp ; CopyRec p4v-dist : $(rscdir) p4vhelp p4vhelp_$(_f).qhc : $(helpsrc) p4v-html-pure $(_f) p4vhelp_$(_f).qhc ; CopyRec p4v-dist : $(rscdir) p4vhelp p4vhelp_$(_f).qch : $(helpsrc) p4v-html-pure $(_f) p4vhelp_$(_f).qch ; CopyRec p4v-dist : $(rscdir) p4mergehelp p4mergehelp_$(_f).qhc : $(helpsrc) p4merge $(_f) p4mergehelp_$(_f).qhc ; CopyRec p4v-dist : $(rscdir) p4mergehelp p4mergehelp_$(_f).qch : $(helpsrc) p4merge $(_f) p4mergehelp_$(_f).qch ; CopyRec p4v-dist : $(rscdir) p4adminhelp p4adminhelp_$(_f).qhc : $(helpsrc) p4admin-html-pure $(_f) p4adminhelp_$(_f).qhc ; CopyRec p4v-dist : $(rscdir) p4adminhelp p4adminhelp_$(_f).qch : $(helpsrc) p4admin-html-pure $(_f) p4adminhelp_$(_f).qch ; } CopyRec p4v-dist : $(rscdir) p4vhelp p4v-gs.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs.pdf ; CopyRec p4v-dist : $(rscdir) p4vhelp p4v-gs_ja.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs_ja.pdf ; ## Translation files for _f in $(qtcmd)_$(QtLanguages).qm { CopyRec p4v-dist : $(rscdir) translations $(_f) : $(_f) ; } CopyRec p4v-dist : $(rscdir) translations msg_ja.txt : $(AllP4) p4-offline translations msg_ja.txt ; ## Example files local examples = basic_p4vdefaults.xml basic_p4vfeatures.xml p4vdefaults.xml p4vfeatures.xml ; for _f in $(examples) { CopyRec p4v-dist : $(rscdir) examples $(_f) : $(AllP4) p4-qt doc $(_f) ; } MakeQtConf p4v-dist : $(bindir) ; LOCATE on $(<) = $(EXEC) ; Depends $(<) : p4v-dist ; Depends all : $(<) ; MkDistArchive $(<) : $(topdir) ; } rule MakeP4Vdist_macosx { local apps = p4v p4merge p4admin ; local Contents Resources ; local _f ; LOCATE on $(<) = $(EXEC) ; Depends $(<) : p4v-dist ; Depends p4v-dist : $(apps) ; # For each app, do the following: # * Copy in frameworks and plugins # * Copy in common image resources. # * Generate qt.conf # * Fix dylib references in exe and install VersionCheck wrapper local app ; for app in $(apps) { Contents = $(EXEC) $(app).app Contents ; Resources = $(Contents) Resources ; CopyRec p4v-dist : $(Contents) Frameworks : $(EXEC_LIB) Frameworks ; CopyRec p4v-dist : $(Contents) PlugIns : $(EXEC_LIB) PlugIns ; CopyRec p4v-dist : $(Resources) translations : $(EXEC_LIB) translations ; CopyRec p4v-dist : $(Resources) images.rcc : images.rcc ; CopyRec p4v-dist : $(Resources) empty.lproj : /dev/null ; # Translation files for _f in $(app)_$(QtLanguages).qm { CopyRec p4v-dist : $(Resources) translations $(_f) : $(_f) ; } MakeQtConf p4v-dist : $(Resources) ; local _real = [ FDirName $(Contents) MacOS $(app) ] ; # Must use the same grist here as in QtMacPackage. _real = $(_real:G=$(app)) ; _real = $(_real).real ; Depends p4v-dist : $(_real) ; Depends $(_real) : $(app) ; MacP4VdyldFixup $(_real) : $(app) ; } # # app-specific prep for p4v.app # Resources = $(EXEC) p4v.app Contents Resources ; MacP4Vassistant p4v-dist : $(Resources) : $(AllP4) p4-qt apps p4v img p4v_help.icns ; for _f in $(QtLanguages) { CopyRec p4v-dist : $(Resources) Help p4vhelp_$(_f).qhc : $(AllP4) p4-doc help p4v-html-pure $(_f) p4vhelp_$(_f).qhc ; CopyRec p4v-dist : $(Resources) Help p4vhelp_$(_f).qch : $(AllP4) p4-doc help p4v-html-pure $(_f) p4vhelp_$(_f).qch ; } CopyRec p4v-dist : $(Resources) Help p4v-gs.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs.pdf ; CopyRec p4v-dist : $(Resources) Help p4v-gs_ja.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs_ja.pdf ; # Offline broker and p4d components CopyRec p4v-dist : $(Resources) p4d : [ MakeP4Vdist_macosx_compute_p4d_directory ] p4d ; CopyRec p4v-dist : $(Resources) p4ob : p4ob ; CopyRec p4v-dist : $(Resources) translations msg_ja.txt : $(AllP4) p4-offline translations msg_ja.txt ; local examples = basic_p4vdefaults.xml basic_p4vfeatures.xml p4vdefaults.xml p4vfeatures.xml ; for _f in $(examples) { CopyRec p4v-dist : $(Resources) examples $(_f) : $(AllP4) p4-qt doc $(_f) ; } # # app-specific prep for p4merge.app # Resources = $(EXEC) p4merge.app Contents Resources ; MacP4Vassistant p4v-dist : $(Resources) : $(AllP4) p4-qt apps p4merge img p4_merge_help.icns ; for _f in $(QtLanguages) { CopyRec p4v-dist : $(Resources) Help p4mergehelp_$(_f).qhc : $(AllP4) p4-doc help p4merge $(_f) p4mergehelp_$(_f).qhc ; CopyRec p4v-dist : $(Resources) Help p4mergehelp_$(_f).qch : $(AllP4) p4-doc help p4merge $(_f) p4mergehelp_$(_f).qch ; } CopyRec p4v-dist : $(Resources) launchp4merge : p4merge_mac_shim ; # # app-specific prep for p4admin.app # Resources = $(EXEC) p4admin.app Contents Resources ; # TODO: p4admin assistant may need its own icon; check with dev MacP4Vassistant p4v-dist : $(Resources) : $(AllP4) p4-qt apps p4v img p4v_help.icns ; for _f in $(QtLanguages) { CopyRec p4v-dist : $(Resources) Help p4adminhelp_$(_f).qhc : $(AllP4) p4-doc help p4admin-html-pure $(_f) p4adminhelp_$(_f).qhc ; CopyRec p4v-dist : $(Resources) Help p4adminhelp_$(_f).qch : $(AllP4) p4-doc help p4admin-html-pure $(_f) p4adminhelp_$(_f).qch ; } buildDMG $(<) : $(EXEC:G=dir)/$(apps:S=.app) ; } rule MakeP4Vdist_macosx_compute_p4d_directory { # Finding the server executable for the offline component of p4v on # the mac is slightly nasty because we build with OS=MACOSX for the # Qt components, and OS=DARWIN for the server component. # # Furthermore, we have to keep a map of the corresponding OSVER # numbers between OSX and Darwin. And, we want to use the nightly # builds of the server if we are making a nightly build. local _darwin_osver ; switch $(OSVER) { case 104 : _darwin_osver = 80 ; case 105 : _darwin_osver = 90 ; } local _platform = darwin $(_darwin_osver) $(OSPLAT:L) ; local _path = $(AllP4) p4-bin bin.$(_platform:J="") $(BUILD) ; return $(_path) ; } rule MacP4Vassistant { # Install the assistant into app's resources directory. # The assistant comes straight from the TrollTech distribution for # now, though someday we may make our own branded version. local target = $(1) ; local Resources = [ FDirName $(2) ] ; local icons = [ FDirName $(3) ] ; local assistant_tar = assistant_dyn.tar ; LOCATE on $(assistant_tar) = $(EXEC_LIB) ; local dst = <$(Resources)>Assistant.app ; MakeLocate $(dst) : $(Resources) ; Depends $(target) : $(dst) ; ASSISTANT_ICONS on $(dst) = $(icons) ; MacP4Vassistant_install $(dst) : $(assistant_tar) ; local asst_Resources = $(Resources) Assistant.app Contents Resources ; MakeQtConf $(dst) : $(asst_Resources) ; CopyRec $(target) : $(asst_Resources) translations : $(EXEC_LIB) translations ; } # Untar the assistant tar file and copy our custom icon into the assistant. actions MacP4Vassistant_install { tar -xpvf $(>) -C $(<:P) cp $(ASSISTANT_ICONS) $(<)/Contents/Resources/assistant.icns } # The copying of SystemVersionCheck ideally should be a separate # rule/action, but it's difficult to get Jam to replace one file # with another except incidentally, and here we are kind of moving # (and modifying) the original target, so here is as good a place # as any to do it. actions MacP4VdyldFixup { $(CP) -p "$(>)" "$(<)" || exit 1 otool -X -L "$(<)" \ | sed -n \ -e '/@executable_path/d' \ -e 's/ *(compat.*//' \ -e 's/^[ ]*//' \ -e '/^\//!p' \ | while read dep ; do toprel=`echo "$dep" \ | sed -e 's=.*/\([^/]*.framework/\)=\1=' \ -e 's=^/.*/=='` new=@executable_path/../Frameworks/$toprel install_name_tool -change "$dep" "$new" "$(<)" done $(CP) $(EXEC_LIBEXEC)/SystemVersionCheck "$(>)" } actions buildDMG { $(AllP4)/tools/scripts/buildDMG.pl \ -debug \ -compressionLevel 9 \ -buildDir $(EXEC) \ -dmgName $(<:B) \ -volName $(<:B) \ $(>) } rule MakeQtConf { local target = $(1) ; local dir = [ FDirName $(2:G=) ] ; local qtconf = <$(dir)>qt.conf ; MakeLocate $(qtconf) : $(dir) ; Depends $(target) : $(qtconf) ; MakeQtConf1 $(qtconf) ; MODE on $(qtconf) = $(FILEMODE) ; Chmod $(qtconf) ; } actions MkTarArchive { tar -cf $(<) -C $(>:P) $(>:BE)$(>:SE) } actions MkZipArchive { cd $(<:P) zip -9 -r -q $(<:BE)$(<:SE) $(>:BE)$(>:SE) } actions MkComressedTarArchive { tar -cf - -C $(>:P) $(>:BE)$(>:SE) | $(COMPRESS) > $(<) } actions Unix2Dos { unix2dos -q $(<) ; } rule LinkSmartHeap { if $(SMARTHEAP) = yes { local _64 = "" ; local d = "" ; if $(OSPLAT) = X86_64 || $(OSPLAT) = X64 { _64 = 64 ; } if $(TYPE_DEBUG) { d = d ; } switch $(OS)-$(OSVER:E)-$(OSPLAT:E)-$(OSCOMP:E) { case NT-*-X*-* : SMARTHPLIB ?= $(EXEC_LIB)\\shlSMP$(_64)Mt$(d).lib ; local e = [ FAppendSuffix $(<) : $(SUFEXE) ] ; LINKLIBS on $(e) = $(SMARTHPLIB) $(LINKLIBS) ; case LINUX-*-X86*-* : SMARTHPLIB ?= $(EXEC_LIB)/libsmartheapC$(d)$(_64).a $(EXEC_LIB)/libsmartheap$(d)$(_64).a ; # Per-target LINKLIBS need to incorporate global libs # too (e.g. libsupc++), but they should come after the # smartheap libs. LINKLIBS on $(<) = $(SMARTHPLIB) $(LINKLIBS) ; # Ignore a couple of duplicate symbol definitions in # exception handler code between some of the smartheap 9.01 # objects and libsupc++ (or static libstdc++). # # We aren't using exception handlers anyway, but there is # no other way to work around this problem at link time # without upgrading to gcc 4.1 for our builds; we're still # using gcc 3.4.5. LINKFLAGS on $(<) = $(LINKFLAGS) -Wl,-z,muldefs ; } } } ################################################# # # Section 5. Perforce-special Windows rules. # ################################################# # # Special p4-win/scc/p4-exp rules: # # P4EXPDefines - set C++ flags for P4-EXP # P4EXPDOTH file : file ; - wrapper for p4exp.h dependencies # P4EXPDOTHDEPENDS files : file ; - wrapper for files dependant on p4exp.h # P4EXPMIDL file : file ; - set up files for MIDL compiling # EXPMIDL file : file ; - compile .idl file # EXP64MIDL file : file ; - compile .idl file for 64 bit Windows # P4EXPLinkage exe : libs ; - set up link flags windows exe # # P4SccDefines - set C++ flags for (old) p4scc.dll # # P4WinDefines - set C++ flags for p4-win/gui # P4WinDiffDefines - set C++ flags for p4-win/diff, merge # # WinDefines opts : defines ; - set C++ flags for p4-win # WinDllDeffile exe : file ; - set /def: file for link # WinDllLinkage exe : libs ; - set up link flags windows DLL # WinDllNoMain exe ; - setup exe with no main # WinLinkage exe : libs ; - set up link flags windows exe # WinRes exe : *.rc : flags ; - compile .rc->.res, link against exe # WinResIdent *.rc ; - set special defines for build identification # rule P4RPTCLILinkage { local _lf = /subsystem:console ; switch $(TYPE_DEBUG) { case true : _lf += /DEBUG ; case * : _lf += /MAP ; } _lf += /INCREMENTAL:NO ; _lf += /NODEFAULTLIB:"libcmt" ; _lf += /NODEFAULTLIB:"libc" ; switch $(OSPLAT) { case X86 : _lf += /MACHINE:x86 ; } LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ; LINKLIBS on $(<) = gdi32.lib comctl32.lib shlwapi.lib user32.lib version.lib shell32.lib advapi32.lib oldnames.lib kernel32.lib ws2_32.lib winmm.lib odbc32.lib odbccp32.lib $(2) ; } rule P4GTLinkage { local _lf = /subsystem:windows ; switch $(TYPE_DEBUG) { case true : _lf += /DEBUG ; case * : _lf += /MAP ; } _lf += /DLL ; _lf += /INCREMENTAL:NO ; _lf += /NODEFAULTLIB:"libcmt" ; _lf += /NODEFAULTLIB:"libc" ; switch $(OSPLAT) { case X86 : _lf += /MACHINE:x86 ; case X64 : _lf += /MACHINE:x64 ; } LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ; if $(OSPLAT) != X64 { LINKLIBS on $(<) = $(P4GT)/htmlhelp/htmlhelp.lib gdi32.lib comctl32.lib shlwapi.lib user32.lib version.lib shell32.lib advapi32.lib oldnames.lib kernel32.lib ws2_32.lib winmm.lib odbc32.lib odbccp32.lib $(2) ; } else { LINKLIBS on $(<) = $(P4GT)/htmlhelp/htmlhelp_x64.lib gdi32.lib comctl32.lib shlwapi.lib user32.lib version.lib shell32.lib advapi32.lib oldnames.lib kernel32.lib ws2_32.lib winmm.lib odbc32.lib odbccp32.lib $(2) ; } } rule P4GTDefines { if $(MSVSVER) >= 8 { C++FLAGS += /Zc:wchar_t- ; WinDefines /GR : _USRDLL _WINDLL NT_PLUGIN ; } else { WinDefines /GR /GX : _USRDLL _WINDLL NT_PLUGIN ; } # # Setting environment variable "LANG=ja" triggers Japanese # localized P4GT builds only. # switch $(LANG) { case ja : C++FLAGS += /DLANG_ja ; } } rule P4EXPDefines { local u = ; if $(OSVER) != 98 && ! $(NOUNICODE) { u += [ FDefines UNICODE _UNICODE ] ; } WinDefines /Ob1 /EHa $(u) : _UNICODE _ATL_STATIC_REGISTRY _USRDLL _WINDLL ; } rule P4EXPDOTH { DEPENDS $(<) : $(>) ; Clean clean : $(<) ; } rule P4EXPDOTHDEPENDS { DEPENDS $(<) : $(>) ; } rule P4EXPMIDL { DEPENDS $(<) : $(>) ; switch $(OSPLAT) { case X64 : EXP64MIDL $(<) : $(>) ; case * : EXPMIDL $(<) : $(>) ; } Clean clean : $(<) p4exp.tlb dlldata.c p4exp_p.c ; } actions EXPMIDL { midl /env win32 /Oicf /tlb ".\p4exp.tlb" /h "p4exp.h" /iid $(<) $(>) } actions EXP64MIDL { midl /env x64 /Oicf /tlb ".\p4exp.tlb" /h "p4exp.h" /iid $(<) $(>) } rule P4EXPLinkage { # P4EXPLinkage exe : libs ; - set up link flags windows exe local _lf = /subsystem:windows ; switch $(TYPE_DEBUG) { case true : _lf += /DEBUG ; case * : _lf += /MAP ; } _lf += /DLL ; _lf += /def:p4exp.def ; switch $(OSPLAT) { case X86 : _lf += /MACHINE:X86 ; case X64 : _lf += /MACHINE:X64 ; } LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ; LINKLIBS on $(<) = gdi32.lib comctl32.lib shlwapi.lib user32.lib version.lib shell32.lib advapi32.lib oldnames.lib kernel32.lib ws2_32.lib winmm.lib $(2) ; } rule P4SccDefines { WinDefines /GX : _USRDLL _WINDLL ; } rule P4WinDefines { local u = ; # Unicode builds except on Win98. if $(OSVER) != 98 && ! $(NOUNICODE) { u += [ FDefines UNICODE _UNICODE ] ; } else { u += [ FDefines _MBCS ] ; } u += /GR /EHsc /GS ; if $(TYPE_DEBUG) = true { u += /Zi ; } WinDefines $(u) : STRICT ; } rule P4WinDiffDefines { WinDefines /GR /GX : P4DIFF ; } rule WinDefines { SubDirC++Flags /W3 $(1) [ FDefines NDEBUG _WINDOWS $(2) ] ; switch $(OSPLAT) { case X64 : SubDirC++Flags [ FDefines WIN64 ] ; case * : SubDirC++Flags [ FDefines WIN32 ] ; } if $(TYPE_DYNAMIC) { SubDirC++Flags [ FDefines _AFXDLL ] ; } } rule WinDllDeffile { # WinDllDeffile exe : file ; - set /def: file for link SEARCH on $(>) = $(SEARCH_SOURCE) ; DEFFILE on $(<) = $(>) ; DEPENDS $(<) : $(>) ; } rule WinDllLinkage { # WinDllLinkage exe : libs ; - set up link flags windows DLL WinLinkage $(<) : $(>) ; LINKFLAGS on $(<) += /dll ; } rule WinDllNoMainLinkage { # WinDllNoMain exe ; LINKFLAGS on $(<) += /NOENTRY /SUBSYSTEM:WINDOWS /DLL ; switch $(OSPLAT) { case X64 : LINKFLAGS on $(<) += /MACHINE:X64 ; case * : LINKFLAGS on $(<) += /MACHINE:I386 ; } LINKLIBS on $(<) = $(2) ; } rule WinLinkage { # WinLinkage exe : libs ; - set up link flags windows exe local _lf = /subsystem:windows ; switch $(TYPE_DEBUG) { case true : _lf += /DEBUG ; case * : _lf += /MAP /DEBUG ; } if $(OSVER) != 98 && ! $(NOUNICODE) { _lf += /ENTRY:"wWinMainCRTStartup" ; } switch $(OSPLAT) { case X86 : _lf += /MACHINE:X86 ; } LINKFLAGS on $(<) = $(LINKFLAGS) $(_lf) ; LINKLIBS on $(<) = $(2) ; } rule WinRes { # WinRes exe : *.rc : flags ; - compile .rc->.res, link # Compile .rc into .res for linking into executable. # (Strictly MSVCNT, I presume.) local s r e ; e = [ FAppendSuffix $(<) : $(SUFEXE) ] ; s = [ FGristSourceFiles $(>) ] ; r = $(s:S=.res:G=) ; DEPENDS $(e) : $(r) ; DEPENDS $(r) : $(s) ; LinkLibraries $(e) : $(r) ; LOCATE on $(r) = $(LOCATE_TARGET) ; SEARCH on $(s) = $(SEARCH_SOURCE) ; # .rc files have #includes, but we're pretty sure # they include only files local to the .rc's directory HDRRULE on $(>) = HdrRule ; HDRSCAN on $(>) = $(HDRPATTERN) ; HRDSEARCH on $(>) = $(SEARCH_SOURCE) ; HDRGRIST on $(>) = $(HDRGRIST) ; # Bind headers RCFLAGS on $(r) = $(RCFLAGS) $(3) ; RCHDRS on $(r) = [ on $(r) FIncludes $(SUBDIRHDRS) $(HDRS) $(RCSTDHDRS) ] ; switch $(OSPLAT) { case X86 : RCFLAGS on $(r) += /d _WIN32 ; case X64 : RCFLAGS on $(r) += /d _WIN64 ; } WinRc $(r) : $(s) ; Clean clean : $(r) ; } rule WinResIdent { # WinResIdent *.rc ; local s r p v ; s = [ FGristSourceFiles $(<) ] ; r = $(s:S=.res:G=) ; # If RELEASE=2005.1 and PATCHLEVEL=69929 then # P4_FILE_VERSION = 2005.1.6.9929 # P4_PRODUCT_VERSION = 2005.1 p = [ Match (.*)(....) : $(PATCHLEVEL) ] ; v = $(RELEASE[1]).$(RELEASE[2]).$(p:J=.) $(RELEASE[3]) ; rule Fconcat { return $(<:J) ; } RCFLAGS on $(r) += [ FDefines [ Fconcat P4_INT_MAJOR= $(RELEASE[1]) ] [ Fconcat P4_INT_MINOR= $(RELEASE[2]) ] [ Fconcat P4_INT_HBUILD= $(p[1]) ] [ Fconcat P4_INT_LBUILD= $(p[2]) ] [ Fconcat P4_FILE_VERSION= [ FQuote $(v[1]) ] ] [ Fconcat P4_PRODUCT_VERSION= [ FQuote $(v:J=.) ] ] [ Fconcat P4_COPYRIGHT= [ FQuote $(RELEASE[1]) ] ] ] ; # Source file includes Version Includes $(s) : Version ; } actions WinRc { rc /fo $(<) $(RCFLAGS) "$(RCHDRS)" $(>) } ################################################# # # Section 7. QT build rules and actions. # ################################################# # # QtDefines ; - Add defines/headers for building with QT # QtFormLibrary lib : *.ui ; make .h's and archive .obj's # QtHeaders ts : headers ; - list headers for i18n xlation # QtLibrary lib : ts : files ; - Library call with lupdate # QtLinkage exe : opt ; - linkflags/libs for building with QT # QtConsoleLinkage exe ; - QtLinkage for a console app on NT # QtLrelease qm : ts ; - build qm from ts files with lrelease # QtMoc x.cpp : x.h ; - preprocess with moc # QtMocLibrary lib : *.h ; - moc, compile, & archive # QtResource qrc : mod : pngs ; - name pngs to make resource # QtResourceCpp cpp : qrc ; - build .cpp from resource file # QtUicCpp x.cpp : x.ui x.h ; - preprocess with uic to make .cpp # QtUicHdr x.h : x.ui ; - preprocess with uic to make .h # QtLanguages = ja en ; rule QtHeaders { # QtHeaders ts : headers ; - list headers for lupdate # This just stashes the named headers in the QTLUPHDRS # variable, used by QtLupdate1 to generate the translation # files. # We give the headers a separate grist, so that we don't # confuse their other uses (just in case we mess up here). QtLupdate $(<) : h : $(>:G=QTLHDR) ; } rule QtLibrary { # QtLibrary lib : ts : files ; - Library call with lupdate Library $(1) : $(3) ; QtLupdate $(2) : s : [ FGristSourceFiles $(3) ] ; } rule QtLrelease { # QtLrelease qm : ts ; for _i in $(QtLanguages) { QtLreleaseRun $(1)_$(_i).qm : $(2)_$(_i).ts ; } LOCATE on $(_qm) = $(LOCATE_TARGET) ; } rule QtLreleaseRun { # QtLreleaseRun qm : ts ; NotFile lrelease ; Depends lrelease : $(1) ; Depends $(1) : $(2) ; Clean clean : $(1) ; LOCATE on $(1) = $(LOCATE_TARGET) ; } actions QtLreleaseRun { $(QTLREL) $(>) -qm $(<) } rule QtLupdate { # QtLupdate ts : h/s : files ; - Add sources/hdrs to lupdate # This rule is deeply complicated, and here's why. # # TrollTech's lupdate command uses a .pro file to declare the name # and location of the .ts, source, and header files to be # processed. Unfortunately, rather than computing the location of # these files relative to the current working directory, they are # determined relative to the location of the .pro file! # # The naive solution would be to write the .pro files out to the # current working directory, but that means parallel builds on # different platforms using a shared workspace can clobber each other. # # Writing the .pro files out to the build output directory is # pretty much impossible to do right, because Jam offers no way to # compute the relative path to a source file from any other # arbitrary location; you can only compute it from the current # working directory. Thus, you might be able to finagle "jam # lupdate" to work from p4-bin, but then it would blow up if you # tried to run it from p4-qt. # # To avoid the platform-clobbering race, we create a temporary # directory in the current working directory, wherever that is, # write the .pro files there, and fix up the file paths using a # now-known relative prefix ("..") from cwd. The .pro files are # then deleted and you wind up with an empty temporary directory. # There might be some clever way to remove that that I don't know # about, but it's a harmless artifact. # # If LUPDATE_MERGE is set, the .ts files are written to the # directory "lupdate.merged_ts" instead of the bin.<platform> # directory, and obsolete entries are retained. These are the # versions of the files that should be checked back into # p4-qt/translations when they are to be permanently updated. local tmpdir = tmp_lupdate.$(OS:L)$(OSVER:EL)$(OSPLAT:EL) ; if $(LUPDATE_MERGE) { tmpdir = lupdate.merged_ts ; } local cwdrel = ..$(SLASH) ; NotFile $(cwdrel) ; for lang in $(QtLanguages) { # add grist to distinguish source .ts file from the copy of it # in target dir local _ts = $(1)_$(lang).ts ; local _tss = $(_ts:G=SRC) ; SEARCH on $(_tss) = [ FSubDirPath P4QT translations ] ; local _pro = $(1)_$(lang).pro ; local _proh = $(1)_h_$(lang).pro ; local _pros = $(1)_s_$(lang).pro ; local _prox = $(1)_$(2)_$(lang).pro ; on $(_ts) if ! $(Done) { Done on $(_ts) = true ; # .ts -> .pro -> s.pro (QtLupTmp)-> sources # -> h.pro (QtLupTmp)-> headers # -> .ts from source tree, aka _tss NotFile lupdate ; Depends lupdate : $(_ts) ; Depends $(_ts) : $(_pro) ; Depends $(_pro) : $(_proh) $(_pros) ; Depends $(_proh) $(_pros) : $(_tss) ; Clean clean : $(_ts) ; if $(LUPDATE_MERGE) { LOCATE on $(_ts) = $(tmpdir) ; } else { LOCATE on $(_ts) = $(LOCATE_TARGET) ; } MakeLocate $(_proh) $(_pros) $(_pro) : $(tmpdir) ; QTLTRANS on $(_pro) = $(_ts) ; # Copy translated ts files from source tree # Update ts files using pro file, headers/sources # Build pro file from list of headers/sources # lupdate reads and writes the same .ts file # we keep any translations in .ts files in the source tree # but need to copy them into the target dir for lupdate to # be able to update them # it is a manual step not involving jam to copy them back # to the source tree # source .ts file may not be present; that's ok because # lupdate will create one NOCARE $(_tss) ; # Zero h.pro/s.pro files to begin with QtLupTmp0 $(_proh) ; QtLupTmp0 $(_pros) ; QtLupdatePro $(_pro) $(cwdrel) : $(_proh) $(_pros) ; QtLupdateRun $(_ts) : $(_tss) $(_pro) ; # Zonk pro files when done RmTemps $(_ts) : $(_pro) ; RmTemps $(_pro) : $(_proh) $(_pros) ; } SEARCH on $(3) = $(SEARCH_SOURCE) ; Depends $(_prox) : $(3) ; QtLupTmp1 $(_prox) $(cwdrel) : $(3) ; } } # QtLupdatePro pro cwdrel : hpro spro ; # If set, cwdrel is extra path from cwd needed to instruct lupdate # where the sources really are relative to the pro file, because # lupdate searches for files relative to the location of the pro file, # not cwd. if $(NT) { actions quietly together piecemeal QtLupTmp1 { echo $(<[2]:E)$(>) \ >> $(<[1]) } actions quietly QtLupTmp0 { copy nul: $(<) } actions quietly QtLupdatePro bind QTLTRANS { echo TRANSLATIONS = $(<[2]:E)$(QTLTRANS) > $(<[1]) echo HEADERS = \ >> $(<[1]) type $(>[1]) >> $(<[1]) echo. >> $(<[1]) echo SOURCES = \ >> $(<[1]) type $(>[2]) >> $(<[1]) echo. >> $(<[1]) } } else { actions quietly together piecemeal QtLupTmp1 { echo $(<[2]:E)$(>) \\ >> $(<[1]) } # Zero out the file if it already exists, or create it. This way # the commands in QtLupdatePro will not print errors for files that # don't exist because there are e.g. no h files to write to it. actions quietly QtLupTmp0 { : > $(<) } actions quietly QtLupdatePro bind QTLTRANS { echo TRANSLATIONS = $(<[2]:E)$(QTLTRANS) > $(<[1]) echo HEADERS = \\ >> $(<[1]) cat $(>[1]) >> $(<[1]) echo "" >> $(<[1]) echo SOURCES = \\ >> $(<[1]) cat $(>[2]) >> $(<[1]) echo "" >> $(<[1]) } } # QtLupdateRun ts : tss pro ; # copy the source .ts file (tss) into the output directory (ts) # and make sure it's writable, then run lupdate on the pro file (pro) # to extracted strings from the .cpp/.h files and update the ts # file (ts) with newly found strings if $(CHMOD) { actions QtLupdateRun { $(CP) $(>[1]) $(<[1]) $(CHMOD) +w $(<[1]) $(QTLUP) $(>[2]) } } else { actions QtLupdateRun { $(CP) $(>[1]) $(<[1]) $(QTLUP) $(>[2]) } } rule QtBaseDefines { # QtDefines ; - Add defines/headers for building with QT BoostHdrs ; if ! $(QTDIR) { Exit Can't build in QT directories without QTDIR set. ; } if $(JAMVERSION) < 2.4.1 { Exit QT builds require 2.4.1 ; } if $(JAMBASEDATE) < 2005.05.05 && ! $(QT25WARN) { Echo QT builds work poorly without Jambase 2005.05.05 ; QT25WARN = true ; } QTLUP = [ FDirName $(QTDIR) bin lupdate ] ; QTLREL = [ FDirName $(QTDIR) bin lrelease ] ; QTMOC = [ FDirName $(QTDIR) bin moc ] ; QTUIC = [ FDirName $(QTDIR) bin uic ] ; QEMBED = [ FDirName $(QTDIR) bin qembed ] ; if ! $(LUPDATE_MERGE) && ( $(LUPDATE_NO_OBSOLETE) || $(PRODUCTION) ) { # lrelease has a "bug" whereby if entries in one ts file are # marked obsolete but are active in another ts file (because # keys were moved, say) then lrelease may drop duplicates # *favoring the obsolete entries*, which it then doesn't # include in the .qm file. (The order of preference depends on # the order of files on the command line.) So for production # builds, we strip the obsolete entries for the tmp ts files. # # The default is to keep the obsolete entries because we don't # always want to throw them away; they are useful for the # linquist tool and when we check in merged ts files we should # usually save them. QTLUP += -no-obsolete ; } local _d _f ; _d += QT_NO_STL ; _d += QT_THREAD_SUPPORT ; _d += QT_NO_CAST_TO_ASCII ; _d += QT_NO_CAST_FROM_ASCII ; _d += QT_STATICPLUGIN ; if $(QTOPENGL) = no { _d += NO_OPENGL ; } if $(TEST) { _d += TEST ; } # Source code debugging # DEBUG is in our code -- conditional compilations # QT_NO_* is in QT code switch $(TYPE_DEBUG) { case true : _d += DEBUG ; case * : _d += QT_NO_DEBUG QT_NO_CHECK ; } switch $(OS) { case NT : _f += /EHsc /GR /W4 ; _f += /wd4127 ; # conditional expression is constant _f += /wd4512 ; # assignment operator could not be generated # from Qt's Makefile # but we want stricter warnings and don't use precompiled headers # _f += /Zm200 /W3 ; if $(MSVSVER) >= 8 { # VS8 treats wchar_t as a builtin type by default # while prior version use a typedef _f += /Zc:wchar_t- ; } if $(TYPE_DEBUG) { # enable runtime checks for debug builds only # this isn't compatible with optimizations _f += /RTCcsu ; if $(VLD) { _d += VLD ; } } case MACOSX : if $(TYPE_DEBUG) && ! $(TEST) { # Crank up the warnings. _f += -Wall -Wextra -Wformat -Woverloaded-virtual -Wno-shadow -Wno-system-headers -Wunknown-pragmas -Wno-unreachable-code -Wnon-virtual-dtor -Wextra-tokens ; } } SubDirC++Flags [ FDefines $(_d) ] $(_f) ; } rule QtCoreHeaders { QtAllHeaders : Qt QtCore ; } # If a list of ": modules ..." is specified, just add those directories # into the search list. Otherwise, a default list is generated. rule QtAllHeaders { local QtModules = $(2) ; if ! $(QtModules) { QtModules = Qt QtCore QtGui QtAssistant QtNetwork QtWebKit QtXml QtXmlPatterns ; } if $(OS) = NT || $(OS) = MACOSX { QtModules += phonon ; } if $(QTOPENGL) != no { QtModules += QtOpenGL ; } for module in $(QtModules) { SubDirHdrs [ FDirName $(QTDIR) include $(module) ] ; # Also search the framework directories so that # non-module-qualified #include <QFoo> directives # work even when headers are not installed in # QTDIR/include/qtmodule. if $(OS) = MACOSX && ! $(QT_NO_FRAMEWORK_INCLUDES) { SubDirHdrs [ FDirName $(QTDIR) lib $(module).framework Headers ] ; } } SubDirHdrs [ FDirName $(QTDIR) include ] ; SubDirHdrs $(LOCATE_SOURCE[1]) ; if $(OS) = FREEBSD { SubDirHdrs /usr/X11R6/include ; } if $(OS) = NT && $(TYPE_DEBUG) && $(VLD) { SubDirHdrs $(VLD)/include ; } } rule QtDefines { # QtDefines ; - Add defines/headers for building with QT # Adds headers for all Qt modules if $(MSVSVER) = 8 && $(WindowsSdkDir) { # Include vista SDK directory for vs2005 # This should only be done for Qt products. # Prior to adding the SDK dir, make sure the API # includes defined at the top of this Jamrules are # inserted. Otherwise we may pick up the wrong # error.h. local _h ; for _h in $(HDRS) { SubDirHdrs $(_h) ; } SubDirHdrs $(WindowsSdkDir:J=" ")/include ; } QtBaseDefines $(1) ; QtAllHeaders $(1) ; } rule QtCoreDefines { # QtCoreDefines ; - Add defines/headers for building with QT # Adds headers for QtCore only; no QtGui or other rot if $(MSVSVER) = 8 && $(WindowsSdkDir) { # Include vista SDK directory for vs2005 # This should only be done for Qt products. # Prior to adding the SDK dir, make sure the API # includes defined at the top of this Jamrules are # inserted. Otherwise we may pick up the wrong # error.h. local _h ; for _h in $(HDRS) { SubDirHdrs $(_h) ; } SubDirHdrs $(WindowsSdkDir:J=" ")/include ; } QtBaseDefines ; QtCoreHeaders ; } rule QtLinkage { # QtLinkage exe : opt : qtlibs : rpath ; - linkflags/libs for building with QT local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; local _opt = $(2) ; # Executable-local rpaths are only supported by the dynamic # linker/loader on solaris and linux so far. MacOSX also supports # them but the syntax and mechanism is different; see MacP4VdyldFixup. # # Please don't use this parameter for absolute paths; it should be # for paths relative to the executable, wherever it is run, a la # the linux/solaris $ORIGIN token. # # Use the literal token "NULL" for rpath arg if you want to supress # any dynamic rpath. local _rpath = $(4) ; if $(_rpath) = "" { _rpath = $ORIGIN/../lib/p4v/qt4/lib ; } # The order here is significant when linking statically. # # The STATIC variable is a list of additional library dependencies # which the static Qt libraries have. They don't need to be # enumerated when doing shared builds because the shared libraries # already have their library dependencies enumerated in the shared # object files and the linker picks these up automatically. For # static libraries there is no such facility. local QT4LIBLIST ; local QT4LIBLIST_STATIC ; if $(3) { # If a Qt library list is specified in the 3rd # parameter to this rule, we use those and only # those libraries. QT4LIBLIST = $(3) ; } else { # otherwise, we use a library list customized for p4v. if $(TEST) # unit testing { QT4LIBLIST += QtTest ; } if $(QTOPENGL) != no { QT4LIBLIST += QtOpenGL ; # $(UNIX) is set even for osx, but we must exclude macs here. if $(UNIX) && $(OS) != MACOSX && ! $(TYPE_DYNAMIC) { QT4LIBLIST_STATIC += GL ; } } QT4LIBLIST += QtXml QtXmlPatterns QtNetwork QtGui QtWebKit QtCore ; } switch $(OS) { # We don't want to embed rpath entries for QTDIR/lib in # production builds because they are not located in a # standard system directory (unlike e.g. /usr/X11R6/lib). # Doing so results in unnecessary stat calls on customer # filesystems that may even cause network timeouts. We # link Qt statically in unix production builds. # # Please don't add X libraries here in order to satisfy # dependencies in development builds of Qt. The libraries # listed here are the dependencies required for production # builds; adding more dynamic linker dependencies # decreases portability. # # If you are working with QT shared libraries in a # development environment, there are 3 alternatives: # 1. set LD_LIBRARY_PATH # 2. edit your system ld.so.conf # 3. use the dev_LINKFLAGS and dev_LINKLIBS hooks: # jam -sdev_LINKFLAGS="..." -sdev_LINKLIBS="..." case FREEBSD : LINKFLAGS on $(_t) += # -Wl,-rpath,$(QTDIR)/lib -L$(QTDIR)/lib -L/usr/X11R6/lib $(LINKFLAGS) $(dev_LINKFLAGS) ; if ! $(TYPE_DYNAMIC) { QT4LIBLIST_STATIC += Xrender Xrandr Xcursor fontconfig SM Xfixes X11 m ; } LINKLIBS on $(_t) += -l$(QT4LIBLIST)$(QT_LIBINFIX:E) -l$(QT4LIBLIST_STATIC) -pthread /usr/local/lib/libiconv.a $(LINKLIBS) $(dev_LINKLIBS) ; case SOLARIS : LINKFLAGS on $(_t) += -L$(QTDIR)/lib -L/usr/X11R6/lib -L/usr/openwin/lib -L/usr/sfw/lib -L/opt/lude/lib $(LINKFLAGS) $(dev_LINKFLAGS) ; if $(TYPE_DYNAMIC) { if $(_rpath) != "NULL" { LINKFLAGS on $(_t) += -Wl,-R,'$(_rpath)' ; } LINKFLAGS on $(_t) += -Wl,-R,/usr/sfw/lib ; } else # ! $(TYPE_DYNAMIC) { # These libraries must be enumerated explicitly because our # static production Qt libs depend on them. QT4LIBLIST_STATIC += ICE SM Xrender Xfixes Xext fontconfig freetype X11 rt ; } LINKLIBS on $(_t) += -l$(QT4LIBLIST)$(QT_LIBINFIX:E) -l$(QT4LIBLIST_STATIC) -lm -lpthread -lrt $(LINKLIBS) $(dev_LINKLIBS) ; case LINUX : if $(TYPE_DYNAMIC) && $(_rpath) != "NULL" { LINKFLAGS on $(_t) += -Wl,-rpath,'$(_rpath)' ; } switch $(OSPLAT) { case X86 : LINKFLAGS on $(_t) += -L$(QTDIR)/lib -L/usr/X11R6/lib $(LINKFLAGS) $(dev_LINKFLAGS) ; case X86_64 : LINKFLAGS on $(_t) += -L$(QTDIR)/lib -L/usr/X11R6/lib64 $(LINKFLAGS) $(dev_LINKFLAGS) ; } if ! $(TYPE_DYNAMIC) { # These libraries must be enumerated explicitly because our # static production Qt libs depend on them. QT4LIBLIST_STATIC += Xrender Xrandr Xcursor fontconfig ICE SM X11 Xext m rt dl ; } LINKLIBS on $(_t) += -l$(QT4LIBLIST)$(QT_LIBINFIX:E) -l$(QT4LIBLIST_STATIC) -pthread $(LINKLIBS) $(dev_LINKLIBS) ; case MACOSX : # QtWebKit 4.5.0 and later depend on this framework. if ! $(3) { QT4LIBLIST += phonon ; } LINKFLAGS on $(_t) += $(LINKFLAGS) # comment out -prebind flag, because Qt is # not built prebound #-prebind -L$(QTDIR)/lib # look here for normal libs -F$(QTDIR)/lib # ...for structured frameworks too # This (dynamic) library is listed here so that it appears # before any other objects and specifically before # libsupp.a, to avoid symbol name collisions. libz is # needed for the QuickTime framework. -lz $(dev_LINKFLAGS) ; LINKLIBS on $(_t) += $(LINKLIBS) # This is already on the global LINKLIBS #-framework ApplicationServices ; #-framework Foundation ; -framework QuickTime -framework OpenGL -framework AGL -framework AppKit ; # If you want to link with Qt4 as frameworks on mac, # use -sTYPE=dyn or dyng. Otherwise you get a static # (or unix-style dynamic but non-frameworks) link. if $(TYPE_DYNAMIC) { # This pads the executable header so that # we can later change dynamic shared # library paths recorded in the output file. # (See MacP4VdyldFixup action.) LINKFLAGS on $(_t) += -Wl,-headerpad_max_install_names ; for _frmwk in $(QT4LIBLIST)$(QT_LIBINFIX:E) { LINKLIBS on $(_t) += -framework $(_frmwk) ; } } else { # These libraries must be enumerated explicitly because our # static production Qt libs depend on them. QT4LIBLIST_STATIC += iconv ssl crypto ; LINKLIBS on $(_t) += -l$(QT4LIBLIST)$(QT_LIBINFIX:E) -l$(QT4LIBLIST_STATIC) ; } LINKLIBS on $(_t) += $(dev_LINKLIBS) ; if $(_opt) != "console" { QtMacPackage $(<) ; } case NT : if ! $(3) { QT4LIBLIST += phonon ; } # warn about non-dynamic builds on NT if ! $(TYPE_DYNAMIC) && ! $(QTWARNED) { echo Warning: you really want jam -sTYPE=dyn for QT on NT. ; QTWARNED = 1 ; } # no dos box unless debug if $(_opt) = "console" { LINKFLAGS on $(_t) += $(LINKFLAGS) /subsystem:console ; } else if ! $(TYPE_DEBUG) { LINKFLAGS on $(_t) += $(LINKFLAGS) /subsystem:windows ; } local d = "" ; if $(TYPE_DEBUG) { d = d ; } # We use QT_LIBINFIX=P4 for our production builds, but in Qt # 4.5 and earlier, qtmain doesn't get the infix string. In Qt # 4.6 and later, it does. Since we don't want to have to # "know" this (or parse the value of QTDIR to figure it out), # we just check the filesystem to see which one is there. # # Currently (as of p10.1) we are building DTG with a 4.5.x # version of Qt and the P4V family with Qt 4.6.x, so this # infix variability comes into play. local qtmain = [ FDirEntries $(QTDIR) lib : qtmain$(QT_LIBINFIX:E)$(d).lib qtmain$(d).lib ] ; LINKLIBS on $(_t) = [ FDirName $(QTDIR) lib $(qtmain[1]) ] ; for _lib in $(QT4LIBLIST)$(QT_LIBINFIX:E) { LINKLIBS on $(_t) += [ FDirName $(QTDIR) lib $(_lib)$(d)4.lib ] ; } LINKLIBS on $(_t) += advapi32.lib # for qtree user32.lib gdi32.lib comdlg32.lib ole32.lib oleaut32.lib shell32.lib uuid.lib imm32.lib winmm.lib ws2_32.lib winspool.lib version.lib ; if $(TYPE_DEBUG) && $(VLD) { LINKLIBS on $(_t) += $(VLD)/lib/vld.lib ; } case * : Exit Don't know how to link QT executables on $(OS). ; } } rule QtConsoleLinkage { # QtConsoleLinkage exe ; - QtLinkage for a console app on NT QtLinkage $(<) : console ; } rule QtDllLinkage { # QtLinkage exe ; - linkflags/libs for building with QT local QT4LIBLIST ; QT4LIBLIST += QtXml QtOpenGL QtNetwork QtGui QtCore phonon ; # WebKit not built for static DLL on Windows if $(TYPE_DYNAMIC) && $(OS) = NT { QT4LIBLIST += QtWebKit ; } switch $(OS) { case NT : # warn about non-dynamic builds on NT if ! $(TYPE_DYNAMIC) && ! $(QTWARNED) { echo Warning: you really want jam -sTYPE=dyn for QT on NT. ; QTWARNED = 1 ; } LINKFLAGS on $(<) += $(LINKFLAGS) /DLL ; echo Warning: you are building a dll $(LINKFLAGS) ; # no dos box unless debug if ! $(TYPE_DEBUG) { LINKFLAGS on $(<) += $(LINKFLAGS) /subsystem:windows ; } # advertise symbols available if $(TYPE_DEBUG) && $(MSVSVER) >= 9 { LINKFLAGS on $(<) += /ASSEMBLYDEBUG ; } local d = "" ; if $(TYPE_DEBUG) { d = d ; } local n = "" ; if $(TYPE_DYNAMIC) { n = 4 ; } # We use QT_LIBINFIX=P4 for our production builds, but in Qt # 4.5 and earlier, qtmain doesn't get the infix string. In Qt # 4.6 and later, it does. Since we don't want to have to # "know" this (or parse the value of QTDIR to figure it out), # we just check the filesystem to see which one is there. # # Currently (as of p10.1) we are building SCC with a 4.5.x # version of Qt and the P4V family with Qt 4.6.x, so this # infix variability comes into play. local qtmain = [ FDirEntries $(QTDIR) lib : qtmain$(QT_LIBINFIX:E)$(d).lib qtmain$(d).lib ] ; LINKLIBS on $(<) = [ FDirName $(QTDIR) lib $(qtmain[1]) ] ; for _lib in $(QT4LIBLIST)$(QT_LIBINFIX:E) { LINKLIBS on $(<) += [ FDirName $(QTDIR) lib $(_lib)$(d)$(n).lib ] ; } LINKLIBS on $(<) += advapi32.lib # for qtree user32.lib gdi32.lib comdlg32.lib ole32.lib oleaut32.lib shell32.lib uuid.lib imm32.lib winmm.lib ws2_32.lib winspool.lib shlwapi.lib version.lib ; if ! $(TYPE_DYNAMIC) { LINKLIBS on $(<) += opengl32.lib ; # for static QtOpenGL.lib } if $(TYPE_DEBUG) && $(VLD) { echo addding vld ; LINKLIBS on $(<) += $(VLD)/lib/vld.lib ; } case * : Exit Don't know how to link QT executables on $(OS). ; } } # Mac special package - make a raw executable into a .app folder # This does x things: # 1. locates the actual exe in exe.app/Contents/MacOS/exe # 2. Creates exe.app/Contents/PkgInfo # 3. Creates exe.app/Contents/Info.plist # 4. Creates exe.app/Contents/Resources/application.icns rule QtMacPackage { # QtMacPackage exe ; Depends $(<) : <$(<)>PkgInfo ; Depends $(<) : <$(<)>Info.plist ; Depends $(<) : <$(<)>application.icns ; MakeLocate $(<) : [ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents MacOS ] ; MakeLocate <$(<)>PkgInfo : [ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents ] ; MakeLocate <$(<)>Info.plist : [ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents ] ; MakeLocate <$(<)>application.icns : [ FSubDirPath $(EXEC_TOKENS) $(<:S=.app) Contents Resources ] ; MacCreatorCode <$(<)>Info.plist : $(<) ; QtMacPackageInfo <$(<)>PkgInfo ; QMS on <$(<)>PkgInfo = [ MacCreatorCode $(<) ] ; QtMacPlist <$(<)>Info.plist : $(<) ; } actions QtMacPackageInfo { echo "APPL$(QMS)" > $(<) } rule QtMacIcons { File <$(<)>application.icns : $(>) ; } rule QtMacPlist { local osid = $(OS)$(OSVER:E)$(OSPLAT:E) ; Depends files : $(<) ; # Add the standard items to the Info.plist file # QtMacAddPListItem $(>) : CFBundleExecutable : $(>) ; QtMacAddPListItem $(>) : CFBundlePackageType : "APPL" ; QtMacAddPListItem $(>) : CFBundleShortVersionString : $(RELEASE:J=.) ; QtMacAddPListItem $(>) : CFBundleVersion : $(RELEASE:J=.)/$(PATCHLEVEL)$(SPECIAL:E) ; QtMacAddPListItem $(>) : CFBundleGetInfoString : "$(RELEASE:J=.), Copyright $(SUPPDATE[1]) Perforce Software, Inc." ; QtMacAddPListItem $(>) : CFBundleIconFile : application.icns ; QtMacAddPListItem $(>) : P4RevString : "$(>:U)/$(osid[1]:U)/$(RELEASE:J=.)/$(PATCHLEVEL)$(SPECIAL:E) ($(SUPPDATE[1])/$(SUPPDATE[2])/$(SUPPDATE[3]))" ; MODE on $(<) = $(FILEMODE) ; Chmod $(<) ; # This is just for the output hack in the action QtMacPList JOINER_VARIABLE on $(<) = " >> " ; } # Adds a string item to Info.plist # concatenates the XML description to a string which contains the contents # rule QtMacAddPListItem { MAC_PLIST_CONTENTS on <$(<)>Info.plist += " \" <key>$(2)</key>\"" ; MAC_PLIST_CONTENTS on <$(<)>Info.plist += " \" <string>$(3)</string>\"" ; } # Writes out an XML file that conforms to the Info.pllist format # # look at the central line very carefully # the whole thing gets expanded into multiple lines because # there are no spaces in this line. They are made into multiple # permutations of every value in MAC_PLIST_CONTENTS. # each value begins with a space (so there is a space after "echo" # and each one uses the one value in JOINER_VARIABLE so it can # put spaces between current the MAC_PLIST_CONTENTS value, and # the value of the file which it will be appended to # actions QtMacPlist { echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > $(<) echo "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" >> $(<) echo "<plist version=\"1.0\">" >> $(<) echo "<dict>" >> $(<) echo$(MAC_PLIST_CONTENTS)$(JOINER_VARIABLE)$(<); echo "</dict>" >> $(<) echo "</plist>" >> $(<) } # Library rules rule QtHdrRule { # Our own HdrRule that knows a .ui doesn't itself include # a .h, but instead causes the resulting .cpp to do so. # What .cpp? TCPP is set on the .ui by QtFormLibrary, # and that's how we know it's this rigged dependency. HdrRule $(TCPP:E=$(<)) : $(>) ; } rule QtFormLibrary { # QtFormLibrary lib : *.ui ; make .h's and archive .obj's # For each x.ui file we generate _3_ files: # # x.h (uic x.ui) # tx.cpp (uic x.ui x.h) (temp) # mx.cpp (moc x.h) (temp) # # The tx.cpp and mx.cpp get compiled into tx.o and mx.o # and archived into the library. Library $(<) : m$(>:S=.cpp) ; Library $(<) : t$(>:S=.cpp) ; local i ; for i in $(>) { local h = $(i:S=.h) ; local ui = [ FGristSourceFiles $(i) ] ; local mcpp = [ FGristSourceFiles m$(i:S=.cpp) ] ; local tcpp = [ FGristSourceFiles t$(i:S=.cpp) ] ; local mobj = $(mcpp:S=$(SUFOBJ)) ; local tobj = $(tcpp:S=$(SUFOBJ)) ; # .ui's can include .h files, though what it actually # means is that the generated tx.cpp includes the .h's, # so we pass the tx.cpp name down to our own QtHdrRule. TCPP on $(ui) = $(tcpp) ; HDRRULE on $(ui) = QtHdrRule ; HDRSCAN on $(ui) = "<include .*>(.*)</include>" ; HDRSEARCH on $(ui) = $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ; QtUicHdr $(h) : $(ui) ; QtUicCpp $(tcpp) : $(ui) $(h) ; QtMoc $(mcpp) : $(h) ; if ! $(TYPE_DEBUG) { RmTemps $(mobj) : $(mcpp) ; } if ! $(TYPE_DEBUG) { RmTemps $(tobj) : $(tcpp) ; } Includes $(mcpp) : $(h) ; Includes $(tcpp) : $(h) ; } } rule QtForms { # QtForms *.ui ; make .h's # For each x.ui file we generate a single header file: # # ui_x.h (uic x.ui) local i ; for i in $(>) { local h = ui_$(i:S=.h) ; local ui = [ FGristSourceFiles $(i) ] ; Depends $(<) : $(h) ; QtUicHdr $(h) : $(ui) ; } } rule QtMocLibrary { # QtMocLibrary lib : *.h ; - moc, compile, & archive # X.h -> temp mX.cpp -> temp mX.obj -> lib # Normal library rule on the generated m*.cpp files Library $(<) : m$(>:S=.cpp) ; # Make mX.cpp from X.h using moc # mX.cpp is a temp local h ; for h in $(>) { local cpp = [ FGristSourceFiles m$(h:S=.cpp) ] ; local obj = $(cpp:S=$(SUFOBJ)) ; local gh = [ FGristFiles $(h) ] ; QtMoc $(cpp) : $(gh) ; if ! $(TYPE_DEBUG) { RmTemps $(obj) : $(cpp) ; } } } # Source file rules rule FSplit { # string : delim (default /) local s = $(>:E=/) ; local x = [ MATCH ([^$(s)]*)$(s)(.*) : $(<) ] ; if ! $(x) { return $(<) ; } return $(x[1]) [ FSplit $(x[2]) : $(>) ] ; } rule FLocalPath { # path1 path2 ... -- turns / into / or \ as needed local r ; for i in $(<) { r = $(r) [ FDirName [ FSplit $(i) ] ] ; } return $(r) ; } rule QrcHdrRule { # Echo $(<) is $(>) ; local t = [ FLocalPath $(>) ] ; Includes $(<) : $(t) ; SEARCH on $(t) = $(HDRSEARCH) ; } actions Qrc { $(QTRCC) -binary -o $(<) $(>) } rule Qrc { # Qrc file.rcc : file.qrc ; MakeLocate $(<) : $(EXEC) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; QTRCC = [ FDirName $(QTDIR) bin rcc ] ; HDRRULE on $(>) = QrcHdrRule ; HDRSCAN on $(>) = "<file.*>(.*)</file>" ; HDRSEARCH on $(>) = $(SEARCH_SOURCE:E) ; Depends all : $(<) ; Depends $(<) : $(>) ; } rule QtMoc { # QtMoc x.cpp : x.h ; - preprocess with moc # Derive a .cpp from .h using Qt's moc NotFile src ; Depends src : $(<) ; Depends all : $(<) ; Depends $(<) : $(>) ; Clean clean : $(<) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MakeLocate $(<) : $(LOCATE_SOURCE) ; } actions QtMoc { $(QTMOC) -DOS_$(OS) $(>) -o $(<) } rule QtHelpGenBuild { # QtHelpGenBuild target.qhc : source.qhp : command : default_target_suffix ; local dst = $(1) ; local src = [ FDirName $(2) ] ; local cmd = $(3) ; local default_suffix = $(4) ; if ! $(dst) { dst = $(src:B) $(default_suffix) ; dst = $(dst:J=".") ; } MakeLocate $(dst) : $(ALL_LOCATE_TARGET) ; Depends all : $(dst) ; Depends $(dst) : $(src) ; Clean clean : $(dst) ; QTHELPBIN on $(dst) = [ FDirName $(QTDIR) bin $(cmd) ] ; QTHELPSRC on $(dst) = $(src) ; QtHelpGenRun $(dst) : $(src) ; } rule QtHelpGen { QtHelpGenBuild $(1) : $(2) : qhelpgenerator : qhc ; } rule QtHelpCollectionGen { QtHelpGenBuild $(1) : $(2) : qcollectiongenerator : qch ; } # LD_LIBRARY_PATH is for unix. # DYLD_LIBRARY_PATH and DYLD_FRAMEWORK_PATH are for OSX. # The trolltech build process does not hardcode these so they need # to go into the environment. # # These help generation programs, at least as of version 4.4.2, # also seem to have a bunch of problems on several platforms # writing over NFS whether or not locking is enabled. So write to # /tmp and then copy back into place. actions QtHelpGenRun { LD_LIBRARY_PATH=$(QTDIR)/lib DYLD_LIBRARY_PATH=$(QTDIR)/lib DYLD_FRAMEWORK_PATH=$(QTDIR)/lib export LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH $(QTHELPBIN) -o ${TMPDIR-/tmp}/$(<:B)$$ $(QTHELPSRC) && $(CP) ${TMPDIR-/tmp}/$(<:B)$$ $(<) } rule QtUicCpp { # QtUicCpp x.cpp : x.ui x.h ; - preprocess with uic to make .cpp NotFile src ; Depends src : $(<) ; Depends all : $(<) ; Depends $(<) : $(>) ; Clean clean : $(<) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MakeLocate $(<) : $(LOCATE_SOURCE) ; } # don't include dir name in x.h actions QtUicCpp { $(QTUIC) $(>[1]) -i $(>[2]:D=) -o $(<) } rule QtUicHdr { # QtUicHdr x.h : x.ui ; - preprocess with uic to make .h NotFile src ; Depends src : $(<) ; Depends all : $(<) ; Depends $(<) : $(>) ; Clean clean : $(<) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MakeLocate $(<) : $(LOCATE_SOURCE) ; } actions QtUicHdr { $(QTUIC) $(>) -o $(<) } rule QtUnitTest { # $(1) = component to build unit test for # the component is defined in $(1).h and $(1).cpp # the unit test is defined in t_$(1).h and t_$(1).cpp # $(2) = list of other components this test depends on # $(3) = list of libraries this test depends on local lib = t_$(1) ; # Need to build component into differently named object file # because Library rule will delete normal object file. # Create unique names that don't conflict with the unit test # files by adding .ut suffix before extension. Object <$(SOURCE_GRIST)>$(1).ut$(SUFOBJ) : <$(SOURCE_GRIST)>$(1).cpp ; QtMoc <$(SOURCE_GRIST)>m$(1).ut.cpp : <$(SOURCE_GRIST)>$(1).h ; Object <$(SOURCE_GRIST)>m$(1).ut$(SUFOBJ) : <$(SOURCE_GRIST)>m$(1).ut.cpp ; LibraryFromObjects t_$(1) : <$(SOURCE_GRIST)>$(1).ut$(SUFOBJ) <$(SOURCE_GRIST)>m$(1).ut$(SUFOBJ) ; # Rebuild any dependencies for same reason. for dep in $(2) { Object <$(SOURCE_GRIST)>$(dep).$(1).ut$(SUFOBJ) : <$(SOURCE_GRIST)>$(dep).cpp ; QtMoc <$(SOURCE_GRIST)>m$(dep).$(1).ut.cpp : <$(SOURCE_GRIST)>$(dep).h ; Object <$(SOURCE_GRIST)>m$(dep).$(1).ut$(SUFOBJ) : <$(SOURCE_GRIST)>m$(dep).$(1).ut.cpp ; LibraryFromObjects t_$(1) : <$(SOURCE_GRIST)>$(dep).$(1).ut$(SUFOBJ) <$(SOURCE_GRIST)>m$(dep).$(1).ut$(SUFOBJ) ; } # Need to compile unit test too since we're forced to use MainFromObjects. # Moc'ed cpp files, and their obj files, end up with mt_ prefix. Object <$(SOURCE_GRIST)>t_$(1)$(SUFOBJ) : <$(SOURCE_GRIST)>t_$(1).cpp ; QtMoc <$(SOURCE_GRIST)>mt_$(1).cpp : <$(SOURCE_GRIST)>t_$(1).h ; Object <$(SOURCE_GRIST)>mt_$(1)$(SUFOBJ) : <$(SOURCE_GRIST)>mt_$(1).cpp ; MainFromObjects $(1) : <$(SOURCE_GRIST)>mt_$(1)$(SUFOBJ) <$(SOURCE_GRIST)>t_$(1)$(SUFOBJ) ; LinkLibraries $(1) : $(lib) $(3) ; QtConsoleLinkage $(1) ; } rule QtUnitTestSuite { for dep in $(2) { local exe = $(dep)$(SUFEXE) ; MakeLocate $(exe) : $(LOCATE_TARGET) ; Depends $(1) : $(exe) ; if $(RUNTESTS) { QtUnitTestCase $(1) : $(exe) ; } } } actions QtUnitTestCase { $(2) } rule P4QtCoreHdrs { SubDirHdrs $(P4QT) p4api include ; SubDirHdrs $(P4QT) core include ; } rule P4SccCoreHdrs { SubDirHdrs $(P4SCC) p4api include ; SubDirHdrs $(P4SCC) core include ; } ################################################# # # Section 8. Lua build rules and actions. # ################################################# # Rule to deal with Lua generated files and tool dependencies for # P4-Report. Note that there are cases where parallel builds will # fail. For example, if you make a clean build, edit scripts/file.lua, # then re-build, you'll still have old p4-bin/file.lb results, so # bin2c and luac might finish after or during the C++ compile. # # This problem only applies to incremental builds. If production # builds are from-scratch, then they should be safe. rule P4ReportDEPENDS { # Make sure we first build the Lua compiler and bin2c utility # before we try and make the header files. DEPENDS luacode.h : luac$(SUFEXE) bin2c$(SUFEXE) ; DEPENDS luaclicode.h : luac$(SUFEXE) bin2c$(SUFEXE) ; # Make sure we create the header files before compiling p4sql # and p4odbc.dll. DEPENDS p4sql$(SUFEXE) : luacode.h luaclicode.h ; DEPENDS p4odbc.dll : luacode.h luaclicode.h ; } rule Lua2c { local _t ; _t = [ FGristFiles $(>:S=.lb) ] ; LuaCompile $(>) ; LOCATE on $(<) = $(SEARCH_SOURCE) ; DEPENDS lib : $(<) ; DEPENDS $(<) : $(_t) ; LuaBin2c $(<) : $(_t) ; Clean clean : $(<) ; Clean clean : $(_t) ; } rule LuaCompile { local _t _i ; for _i in [ FGristFiles $(<:S=.lua) ] { _t = $(_i:S=.lb) ; SEARCH on $(_i) = $(SEARCH_SOURCE) ; LOCATE on $(_t) = $(LOCATE_TARGET) ; DEPENDS obj : $(_t) ; DEPENDS $(_t) : $(_i) ; Luac $(_t) : $(_i) ; Clean clean : $(_t) ; } } actions LuaBin2c { $(ALL_LOCATE_TARGET)$(SLASH)bin2c $(>) > $(<) } actions Luac { $(ALL_LOCATE_TARGET)$(SLASH)luac -s -o $(<) $(>) } ################################################# # # Section 9. Per-platform actions. # ################################################# if $(OS) = IPHONE { # The "security unlock-keychain" command here should have no effect # if the keychain is already unlocked, even if the supplied # password is incorrect. But it will unlock keychains with blank # passwords, which should avoid some accidental production failures. actions P4Scout_xcodebuild { security unlock-keychain -p '' login.keychain pwd=`pwd` cd $(SCOUTSRCDIR) && xcodebuild -configuration $(>) P4APIDIR=$pwd/$(P4APIDIR) && cd build/$(>)-iphoneos && zip -9 -r -y -q $(>)-$(<).zip $(<) && zip -9 -r -y -q $(>)-$(<).dSYM.zip $(<).dSYM && mv $(>)-$(<).zip $(>)-$(<).dSYM.zip $pwd/$(EXEC) } } if $(UNIX) || $(NT) { # Provide proper quoting for file names with spaces in them. actions File { $(CP) "$(>)" "$(<)" } } if $(NT) && $(MSVCNT) { actions updated together piecemeal Archive { pushd $(<:D) if exist $(<:BS) set _$(<:B)_=$(<:BS) $(AR) /nologo /out:$(<:BS) %_$(<:B)_% $(>:BS) popd } # When embedding a manifest, the resource id should be 1 for exe files, # 2 for dlls. Various P4-GT plugins require 1, despite being dlls. # P4-GT targets are identified with the prefix string "P4GT". actions Link bind NEEDLIBS DEFFILE { $(LINK) $(LINKFLAGS) /out:$(<) /def:$(DEFFILE) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) set _target=$(<) set _file=%_target:$(ALL_LOCATE_TARGET)$(SLASH)=% set _rsrc=1 if /i %_target:~-3,3% neq exe set _rsrc=2 if /i %_file:~0,4% equ P4GT set _rsrc=1 if exist $(<).manifest mt -manifest $(<).manifest -outputresource:$(<);%_rsrc% } } if $(NT) { actions Cc { $(CC) /c /Fo$(<) /Fd$(PDBFILENAME) $(CCFLAGS) $(CCDEFS) "$(CCHDRS)" "/I$(STDHDRS)" $(>) } actions C++ { $(C++) /c /Fo$(<) /Fd$(PDBFILENAME) $(C++FLAGS) $(CCDEFS) "$(CCHDRS)" "/I$(STDHDRS)" /Tp$(>) } actions MkTarArchive { tar cf $(<) -C $(>:P) $(>:BE)$(>:SE) } # If someone beat us to creating the directory, don't bomb. actions MkDir1 { $(MKDIR) $(<) if exist $(<) set ERRORLEVEL=0 } } if $(VMS) { actions MkTarArchive { set default $(<:D) vmstar cvdzf $(<:B)$(<:S) [.$(>:B)...] set file/prot=(o:rwed) $(<:B)$(<:S) } actions MkZipArchive { set default $(<:D) zip "-9wrV" $(<:B)$(<:S) $(>:BS=.dir) } actions MkBckArchive { set default $(<:D) backup [.$(>:B)...] $(<:B)$(<:S)/save set file/prot=(o:rwed) $(<:B)$(<:S) } } # # MakeQtConf # if $(OS) = MACOSX { actions MakeQtConf1 { echo "[paths]" > $(<) echo "plugins = PlugIns" >> $(<) echo "translations = Resources/translations" >> $(<) } } else if $(UNIX) { actions MakeQtConf1 { echo "[paths]" > $(<) echo "plugins = ../lib/p4v/qt4/plugins" >> $(<) echo "translations = ../lib/p4v/P4VResources/translations" >> $(<) } } else if $(NT) { actions MakeQtConf1 { echo "[paths]" > $(<) echo "plugins = plugins" >> $(<) echo "translations = translations" >> $(<) } } ################################################# # # Section 10. Useful miscellanea # ################################################# # Numerous client packages use this variable: p4-dtg, p4-convert, # the scripted APIs, etc. # We can't set this in Section 1 because the rule isn't defined yet. if ! $(P4APIDIR) { local _apidir = [ P4APIDirName p4api ] ; P4APIDIR = [ FDirName $(EXEC) $(_apidir[1]) ] ; } # Tell the user where the top of the code tree is. # # For example if you were in say, some arbitrary working directory # deeply under p4-qt/..., how could you easily get back to the # p4-bin directory? # # $ alias topdir='jam locate-topdir 2>&1 | sed -ne "/^TOPDIR=/s///p"' # $ cd `topdir`/p4-bin # # This is probably more useful for scripts, however. rule LocateTopDir { local loc = [ FSubDirPath AllP4 ] ; NOTFILE $(loc:G=locate) ; EchoLocate $(<) : $(loc:G=locate) ; } actions EchoLocate { echo "TOPDIR=$(>:G=:E=.)" ; } LocateTopDir locate-topdir ; # end of Jamrules
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 7893 | Johan Nilsson |
OFFLINE CHANGELIST 10 - SUBMITTED ON 2011/03/23 11:18:27 Upgrade project files to VS2010 and switching to msbuild for the entire project. Retargeted everything to .NET4 Client Profile for the time being, due to VS2010 C++ limitations (can't target anything other than 4.0 without complicating the setup too much). Shouldn't be too hard to retarget later if push comes to shove. Added VS2010 P4API stuff directly inside this project also to make things easier to get up and running for the moment. Removed old static P4API libraries. ____________________________________________________________ OFFLINE CHANGELIST 9 - SUBMITTED ON 2011/03/22 07:35:31 Converted to VS2010 |