# 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 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 ; } ################################################# # # 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 QTCMDLIB : libqtcmd ; SetLibName QTCORELIB : libqtcore ; SetLibName QTP4APILIB : libqtp4api ; SetLibName QTIMAGELIB : libqtimage ; 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 built # pic: for special customer requests 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 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. switch $(TYPE) { case *g : TYPE_DEBUG = true ; } switch $(TYPE) { case dyn* : TYPE_DYNAMIC = 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 ; LINKFLAGS += -Wl,-syslibroot,$(MACOSX_SDK) ; switch $(OSVER:U) { case *CS : case * : C++FLAGS += -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_DARWIN80 ; LINKFLAGS += $(_arch) ; case DARWIN9* : CC = gcc ; C++ = g++ ; LINK = g++ ; MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk ; LINKFLAGS += -Wl,-syslibroot,$(MACOSX_SDK) ; switch $(OSVER:U) { case *CS : case * : C++FLAGS += -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 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. # But we still do not want to link stdc++ dynamically. #LINKLIBS += -lsupc++ ; LINKLIBS += -Wl,-dn,-lstdc++,-dy ; _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++ $(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? $(GENFLAGS) += +W2611,2997 ; 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 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 ; } $(GENFLAGS) += $(_mflags) -D_GNU_SOURCE ; LINKFLAGS += $(_mflags) ; QTOPENGL ?= no ; ZEROCONF = avahi ; case MACOSX : CC = cc ; C++ = cc ; $(GENFLAGS) += -DCASE_INSENSITIVE ; $(GENFLAGS) += -fpascal-strings ; # This looks like a flag but it is really a library macro # kind of thing and causes link problems if it at the front # of the link command so we make it a LIB LINKLIBS += -framework Carbon ; case MACOSX104 : # assumes using gcc 4.0.1 or newer CC = gcc ; C++ = g++ ; LINK = g++ ; MACOSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk ; # 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 -isysroot$(MACOSX_SDK) ; LINKFLAGS += -Wl,-syslibroot,$(MACOSX_SDK) ; # 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 Carbon ; # OSPLAT=U : universal binary # # Unlike the OS=DARWIN case we don't build x86_64 into the # universal binaries because Qt still uses the Carbon API, # which has no 64-bit implementation. 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 MACOSX105 : # assumes using gcc 4.0.1 or newer CC = gcc ; C++ = g++ ; LINK = g++ ; MACOSX_SDK ?= /Developer/SDKs/MacOSX10.5.sdk ; # 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 -isysroot$(MACOSX_SDK) ; LINKFLAGS += -Wl,-syslibroot,$(MACOSX_SDK) ; # 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 Carbon ; # OSPLAT=U : universal binary # # Unlike the OS=DARWIN case we don't build x86_64 into the # universal binaries because Qt still uses the Carbon API, # which has no 64-bit implementation. 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 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 = ; case NT* : local _Z = /Zi ; # flag to put debug syms in .pdb file 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 ; } # 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: STDHDRS = $(MSVCNT)\\include $(MSVCNT)\\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 ; $(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 ; $(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 1mb to 2mb. # See job31737. LINKFLAGS on p4d.exe = $(LINKFLAGS) /STACK:2097152 ; } 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) += -Dsolaris -D_LARGEFILE64_SOURCE -I/opt/lude/include ; 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 ; } ################################################# # # Section 5. Perforce-special rules and actions. # ################################################# # # Special Rules # # FRemoveAny x : y ; - return new array of x minus any values in y # 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 # LinkP4WebMacOptions exe ; - adjusting LINKLIBS/LINKFLAGS # 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 # MakeP4ThumbTar ; create p4vthumb.tgz on unix systems # MakeP4Vtar ; create p4v.tgz on unix systems # MakeP4Vdmg ; create P4V.dmg on Mac OSX # MacP4Vassistant target : apps ; install Qt assistant in apps 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 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) ] ; ents = [ Match $(dir)$(SLASH)(.*) : $(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 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 { if $(STRIP) && ( $(TYPE:E=opt) = opt || $(TYPE) = pic ) { 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) ; 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) ; } } else { 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 _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 { switch $(<:S) { case .tar : MkTarArchive $(<) : $(>) ; case .tgz : MkComressedTarArchive $(<) : $(>) ; case .tar.gz : MkComressedTarArchive $(<) : $(>) ; case .zip : MkZipArchive $(<) : $(>) ; case .bck : MkBckArchive $(<) : $(>) ; case * : exit "Don't know how to make $(<)" ; } } rule MakeP4ObjCdist { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4objc-$(release_info:J=.) ; local exec_dir = [ FSubDirPath P4BIN bin.tools ] ; 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) ] ; CopyRec p4objc-dist : $(topdir) sample : $(AllP4) p4-objc sample : images_watermarked $(watermark_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 MakeDTGTar { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4dtg-$(release_info:J=.) ; local topdir = $(EXEC) $(dirname) ; local bugzdir = $(EXEC) $(dirname) doc bugz3mysql5 ; 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 bugz3mysql5.so : bugz3mysql5.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 : $(bugzdir) patch.bugzilla-3 : $(P4DTG) sdk bugz patch.bugzilla-3 ; CopyRec p4dtg-dist : $(bugzdir) README.txt : $(P4DTG) sdk bugz README.txt ; CopyRec p4dtg-dist : $(bugzdir) README.p4dti.txt : $(P4DTG) sdk bugz README.p4dti.txt ; CopyRec p4dtg-dist : $(bugzdir) mk_dtgdtissue.pl : $(P4DTG) sdk bugz mk_dtgdtissue.pl ; CopyRec p4dtg-dist : $(bugzdir) dti_to_dtg.pl : $(P4DTG) sdk bugz dti_to_dtg.pl ; CopyRec p4dtg-dist : $(bugzdir) changeid.pl : $(P4DTG) sdk bugz changeid.pl ; CopyRec p4dtg-dist : $(bugzdir) jobspec.txt : $(P4DTG) sdk bugz jobspec.txt ; 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 = plugins/bugz3mysql5.so plugins/p4jobdt.so ; local _f ; for _f in $(_strip_bin) { _f = [ FDirName $(topdir) $(_f) ] ; Strip $(_f) ; } for _f in $(_strip_lib) { _f = [ FDirName $(topdir) $(_f) ] ; STRIP on $(_f) = $(STRIP) -x ; Strip1 $(_f) ; } local _tgz = p4dtg.tgz ; LOCATE on $(_tgz) = $(EXEC) ; Depends $(_tgz) : p4dtg-dist ; Depends all : $(_tgz) ; MkComressedTarArchive $(_tgz) : $(dirname) ; } rule MakeP4ThumbTar { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4thumb-$(release_info:J=.) ; local bindir = $(EXEC) $(dirname) bin ; local libdir = $(EXEC) $(dirname) lib p4v ; MakeLocate $(dirname) : $(EXEC) ; Depends p4thumbtar : $(dirname) ; CopyRec p4thumbtar : $(bindir) p4thumb.bin : p4thumb ; CopyRec p4thumbtar : $(bindir) p4thumb : $(AllP4) p4-qt apps p4v p4vwrapper.sh ; if $(TYPE_DYNAMIC) { CopyRec p4thumbtar : $(libdir) qt4 : $(EXEC_LIB) qt4 ; local qtconf = qt.conf ; MakeLocate $(qtconf) : [ FDirName $(bindir) ] ; Depends p4thumbtar : $(qtconf) ; MakeP4VUnixqtconf $(qtconf) ; MODE on $(qtconf) = $(FILEMODE) ; Chmod $(qtconf) ; } STRIP on [ FDirName $(bindir) p4thumb.bin ] = $(STRIP) -x ; Strip1 [ FDirName $(bindir) p4thumb.bin ] ; local _tgz = p4thumb.tgz ; LOCATE on $(_tgz) = $(EXEC) ; Depends $(_tgz) : p4thumbtar ; Depends all : $(_tgz) ; MkComressedTarArchive $(_tgz) : $(dirname) ; } rule MakeP4Vtar { local release_info = $(RELEASE[1-2]) $(PATCHLEVEL) $(RELEASE[3-]) ; local dirname = p4v-$(release_info:J=.) ; local bindir = $(EXEC) $(dirname) bin ; local libdir = $(EXEC) $(dirname) lib p4v ; MakeLocate $(dirname) : $(EXEC) ; Depends p4vtar : $(dirname) ; # FIXME (noahf): This is almost ready but needs some runtime (nfs locking) debugging # For now we are just copying pre-built collections below. #QtHelpGen : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qhp ; #QtHelpCollectionGen : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qhcp ; # #QtHelpGen : $(AllP4) p4-doc help p4merge p4mergehelp.qhp ; #QtHelpCollectionGen : $(AllP4) p4-doc help p4merge p4mergehelp.qhcp ; # P4V components and help CopyRec p4vtar : $(bindir) p4v.bin : p4v ; CopyRec p4vtar : $(bindir) p4v : $(AllP4) p4-qt apps p4v p4vwrapper.sh ; CopyRec p4vtar : $(libdir) P4VResources images.rcc : images.rcc ; CopyRec p4vtar : $(libdir) P4VResources p4vhelp p4vhelp.qhc : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qhc ; CopyRec p4vtar : $(libdir) P4VResources p4vhelp p4vhelp.qch : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qch ; CopyRec p4vtar : $(libdir) P4VResources p4vhelp p4v-gs.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs.pdf ; local _f ; local _examples = basic_p4vdefaults.xml basic_p4vfeatures.xml p4vdefaults.xml p4vfeatures.xml ; for _f in $(_examples) { CopyRec p4vtar : $(libdir) P4VResources examples $(_f) : $(AllP4) p4-qt doc $(_f) ; } # P4Merge components and help CopyRec p4vtar : $(bindir) p4merge.bin : p4merge ; CopyRec p4vtar : $(bindir) p4merge : $(AllP4) p4-qt apps p4v p4vwrapper.sh ; CopyRec p4vtar : $(libdir) P4VResources p4mergehelp p4mergehelp.qhc : $(AllP4) p4-doc help p4merge p4mergehelp.qhc ; CopyRec p4vtar : $(libdir) P4VResources p4mergehelp p4mergehelp.qch : $(AllP4) p4-doc help p4merge p4mergehelp.qch ; if $(TYPE_DYNAMIC) { CopyRec p4vtar : $(libdir) qt4 : $(EXEC_LIB) qt4 ; CopyRec p4vtar : $(bindir) assistant : $(EXEC_LIB) assistant_dyn ; local qtconf = qt.conf ; MakeLocate $(qtconf) : [ FDirName $(bindir) ] ; Depends p4vtar : $(qtconf) ; MakeP4VUnixqtconf $(qtconf) ; MODE on $(qtconf) = $(FILEMODE) ; Chmod $(qtconf) ; } else { CopyRec p4vtar : $(bindir) assistant : $(EXEC_LIB) assistant ; } STRIP on [ FDirName $(bindir) p4v.bin ] = $(STRIP) -x ; Strip1 [ FDirName $(bindir) p4v.bin ] ; STRIP on [ FDirName $(bindir) p4merge.bin ] = $(STRIP) -x ; Strip1 [ FDirName $(bindir) p4merge.bin ] ; local _tgz = p4v.tgz ; LOCATE on $(_tgz) = $(EXEC) ; Depends $(_tgz) : p4vtar ; Depends all : $(_tgz) ; MkComressedTarArchive $(_tgz) : $(dirname) ; } rule MakeP4Vdmg { local target = P4V.dmg ; local apps = p4v p4merge ; LOCATE on $(target) = $(EXEC) ; Depends $(target) : p4vdmg ; Depends p4vdmg : $(apps) ; # FIXME (noahf): This is almost ready but needs some runtime (nfs locking) debugging # For now we are just copying pre-built collections below. #QtHelpGen : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qhp ; #QtHelpCollectionGen : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qhcp ; # #QtHelpGen : $(AllP4) p4-doc help p4merge p4mergehelp.qhp ; #QtHelpCollectionGen : $(AllP4) p4-doc help p4merge p4mergehelp.qhcp ; # # Prep for p4v.app # local dir = $(EXEC) p4v.app Contents ; if $(TYPE_DYNAMIC) { CopyRec p4vdmg : $(dir) Frameworks : $(EXEC_LIB) Frameworks ; CopyRec p4vdmg : $(dir) PlugIns : $(EXEC_LIB) PlugIns ; } dir = $(dir) Resources ; CopyRec p4vdmg : $(dir) images.rcc : images.rcc ; CopyRec p4vdmg : $(dir) Help p4vhelp.qhc : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qhc ; CopyRec p4vdmg : $(dir) Help p4vhelp.qch : $(AllP4) p4-doc help p4v-html-pure p4vhelp.qch ; CopyRec p4vdmg : $(dir) Help p4v-gs.pdf : $(AllP4) p4-doc manuals p4v-gs p4v-gs.pdf ; local _f ; local _examples = basic_p4vdefaults.xml basic_p4vfeatures.xml p4vdefaults.xml p4vfeatures.xml ; for _f in $(_examples) { CopyRec p4vdmg : $(dir) examples $(_f) : $(AllP4) p4-qt doc $(_f) ; } # # Prep for p4merge.app # dir = $(EXEC) p4merge.app Contents ; if $(TYPE_DYNAMIC) { CopyRec p4vdmg : $(dir) Frameworks : $(EXEC_LIB) Frameworks ; CopyRec p4vdmg : $(dir) PlugIns : $(EXEC_LIB) PlugIns ; } dir = $(dir) Resources ; CopyRec p4vdmg : $(dir) images.rcc : images.rcc ; CopyRec p4vdmg : $(dir) Help p4mergehelp.qhc : $(AllP4) p4-doc help p4merge p4mergehelp.qhc ; CopyRec p4vdmg : $(dir) Help p4mergehelp.qch : $(AllP4) p4-doc help p4merge p4mergehelp.qch ; CopyRec p4vdmg : $(dir) launchp4merge : p4merge_mac_shim ; # # Fixup dynamic library references for both apps and copy # in version check stub. # if $(TYPE_DYNAMIC) { local _bin ; for _bin in $(apps) { local _old = [ FDirName $(EXEC) $(_bin:S=.app) Contents MacOS $(_bin) ] ; # Must use the same grist here as in QtMacPackage. _old = $(_old:G=$(_bin)) ; local _new = $(_old).real ; Depends p4vdmg : $(_new) ; Depends $(_new) : $(_bin) ; MacP4VdyldFixup $(_new) : $(_bin) ; MacP4Vqtconf p4vdmg : $(_bin) : [ FDirName $(EXEC) $(_bin:S=.app) ] ; } } MacP4Vassistant p4vdmg : $(apps) ; buildDMG $(target) : $(EXEC:G=dir)/$(apps:S=.app) ; } # Install dynamic or static version of the assistant. # The assistant comes straight from the TrollTech distribution for # now, though someday we may make our own branded version. rule MacP4Vassistant { local _assistant_src _app ; if $(TYPE_DYNAMIC) { _assistant_src = assistant_dyn.tar ; } else { _assistant_src = assistant.tar ; } LOCATE on $(_assistant_src) = $(EXEC_LIB) ; ASSISTANT_ICONS on Assistant.app = $(AllP4)/p4-qt/apps/p4v/img/p4v_help.icns ; ASSISTANT_ICONS on Assistant.app = $(AllP4)/p4-qt/apps/p4merge/img/p4_merge_help.icns ; for _app in $(>) { local _dst = <$(_app)>Assistant.app ; local _dstdir = [ FSubDirPath $(EXEC_TOKENS) $(_app:S=.app) Contents Resources ] ; MakeLocate $(_dst) : $(_dstdir) ; Depends $(<) : $(_dst) ; Depends $(_dst) : $(_assistant_src) ; MacP4Vassistant_install $(_dst) : $(_assistant_src) ; if $(TYPE_DYNAMIC) { MacP4Vqtconf $(<) : $(_dst) : [ FDirName $(_dstdir) Assistant.app ] ; } } } rule MacP4Vqtconf { local qtconf = <$(3)>qt.conf ; local qtconfdir = [ FDirName $(3) Contents Resources ] ; LOCATE on $(qtconf) = $(qtconfdir) ; Depends $(1) : $(qtconf) ; Depends $(qtconf) : $(2) ; MakeP4VMacqtconf $(qtconf) ; MODE on $(qtconf) = $(FILEMODE) ; Chmod $(qtconf) ; } # 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 MakeP4VUnixqtconf { echo "[paths]" > $(<) echo "plugins = ../lib/p4v/qt4/plugins" >> $(<) } actions MakeP4VMacqtconf { echo "[paths]" > $(<) echo "plugins = PlugIns" >> $(<) } actions buildDMG { $(AllP4)/tools/scripts/buildDMG.pl \ -debug \ -compressionLevel 9 \ -buildDir $(EXEC) \ -dmgName $(<:B) \ -volName $(<:B) \ $(>) } 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) > $(<) } rule LinkSmartHeap { if $(SMARTHEAP) = yes { local _64 = "" ; local d = "" ; if $(OSPLAT) = X86_64 || $(OSPLAT) = X64 { _64 = 64 ; } if $(TYPE) = g { 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) ; } } } ################################################# # # 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 /EHsc $(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) $(STDHDRS) ] ; 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 # QtEmbed x.h : files : flags ; - preprocess with qembed # QtFormLibrary lib : *.ui ; make .h's and archive .obj's # QtHeaders ts : headers ; - list headers for i18n xlation # QtImages x.h : files ; - make a .h from image files # 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 $(_ts) $(_qm) = $(LOCATE_TARGET) ; } rule QtLreleaseRun { # QtLreleaseRun qm : ts ; NotFile lupdate ; Depends lupdate : $(1) ; Depends $(1) : $(2) ; Clean clean : $(1) ; LOCATE on $(1) $(2) = $(LOCATE_TARGET) ; } actions QtLreleaseRun { $(QTLREL) $(>) -qm $(<) } rule QtLupdate { # QtLupdate ts : h/s : files ; - Add sources/hdrs to lupdate for lang in $(QtLanguages) { local _ts = $(1)_$(lang).ts ; # add grist to distinguish source .ts file # from the copy of it in target dir local _tss = $(_ts:G=QTLUPCPY) ; # 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) ; # _pro must be in current directory # or lupdate gets confused. LOCATE on $(_ts) $(_proh) $(_pros) = $(LOCATE_TARGET) ; 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) ; QtLupdateRun $(_ts) : $(_tss) $(_pro) ; QtLupdatePro $(_pro) : $(_proh) $(_pros) ; # Zonk pro files when done RmTemps $(_ts) : $(_pro) ; RmTemps $(_pro) : $(_proh) $(_pros) ; # Zero h.pro/s.pro files to begin with QtLupTmp0 $(_proh) ; QtLupTmp0 $(_pros) ; } # Add files to building or h.pro/s.pro file Depends $(_prox) : $(3) ; SEARCH on $(3) = $(SEARCH_SOURCE) ; QtLupTmp1 $(_prox) : $(3) ; } } # QtLupdatePro pro : hpro spro ; if $(OS) = NT { actions quietly together piecemeal QtLupTmp1 { echo $(>) \ >> $(<) } actions quietly QtLupTmp0 { echo. > $(<) $(RM) $(<) } actions quietly QtLupdatePro bind QTLTRANS { echo TRANSLATIONS = $(QTLTRANS) > $(<) echo HEADERS = \ >> $(<) type $(>[1]) >> $(<) echo. >> $(<) echo SOURCES = \ >> $(<) type $(>[2]) >> $(<) echo. >> $(<) } } else { actions quietly together piecemeal QtLupTmp1 { echo $(>) \\ >> $(<) } actions quietly QtLupTmp0 { $(RM) $(<) } actions quietly QtLupdatePro bind QTLTRANS { echo TRANSLATIONS = $(QTLTRANS) > $(<) echo HEADERS = \\ >> $(<) cat $(>[1]) >> $(<) echo "" >> $(<) echo SOURCES = \\ >> $(<) cat $(>[2]) >> $(<) echo "" >> $(<) } } # 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]) $(<) $(CHMOD) $(MODE) $(<) $(QTLUP) $(>[2]) } } else { actions QtLupdateRun { $(CP) $(>[1]) $(<) $(QTLUP) $(>[2]) } } rule QtBaseDefines { # QtDefines ; - Add defines/headers for building with QT 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 ] ; 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 $(1) = QT3 { _d += QT3_SUPPORT ; NEED_QT3SUPPORT = 1 ; } 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 ; } } } 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 ; } if $(1) = QT3 { QtModules = Qt3Support $(QtModules) ; NEED_QT3SUPPORT = 1 ; } for module in $(QtModules) { SubDirHdrs [ FDirName $(QTDIR) include $(module) ] ; # Also search the framework directories so that # non-module-qualified #include 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 ; } if $(1) = QT3 { echo including qt3 support for $(SUBDIR) ; } 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 $(NEED_QT3SUPPORT) { QT4LIBLIST += Qt3Support ; } if $(TESTS) # 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 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 $(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. 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 Carbon -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 : 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 ; } LINKLIBS on $(_t) = [ FDirName $(QTDIR) lib qtmain$(d).lib ] ; 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 ; if $(NEED_QT3SUPPORT) { QT4LIBLIST += Qt3Support ; } QT4LIBLIST += QtXml QtOpenGL QtNetwork QtGui QtWebKit QtCore phonon ; 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 ; } LINKLIBS on $(<) = [ FDirName $(QTDIR) lib qtmain$(d).lib ] ; for _lib in $(QT4LIBLIST)$(QT_LIBINFIX:E) { LINKLIBS on $(<) += [ FDirName $(QTDIR) lib $(_lib)$(d)4.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_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 += " \" $(2)\"" ; MAC_PLIST_CONTENTS on <$(<)>Info.plist += " \" $(3)\"" ; } # 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 "" > $(<) echo "" >> $(<) echo "" >> $(<) echo "" >> $(<) echo$(MAC_PLIST_CONTENTS)$(JOINER_VARIABLE)$(<); echo "" >> $(<) echo "" >> $(<) } # 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) = "(.*)" ; 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 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 QtImages { # QtImages x.h : files ; - make a .h from image files # Delete and do piecemeal append for line-length limited NT. QtEmpty $(<) ; QEMBED on $(<) = $(QTUIC) ; QtEmbed $(<) : $(>) : -embed $(<:B) ; } actions QtEmpty { $(RM) $(<) } rule QtEmbed { # QtEmbed x.h : files : flags ; - preprocess with qembed NotFile src ; Depends src : $(<) ; Depends all : $(<) ; Depends $(<) : $(>) ; Clean clean : $(<) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MakeLocate $(<) : $(LOCATE_SOURCE) ; QEMBEDFLAGS on $(<) = $(3) ; } actions piecemeal QtEmbed { $(QEMBED) $(QEMBEDFLAGS) $(>) >> $(<) } 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 $(>) = "(.*)" ; 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 P4QtCoreHdrs { SubDirHdrs $(P4QT) p4api include ; SubDirHdrs $(P4QT) 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 $(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 } actions QtEmpty { if exist $(<) $(RM) $(<) } actions Link bind NEEDLIBS DEFFILE { $(LINK) $(LINKFLAGS) /out:$(<) /def:$(DEFFILE) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) if exist $(<).manifest mt -manifest $(<).manifest -outputresource:$(<);2 } } if $(NT) { actions Cc { $(CC) /c /Fo$(<) /Fd$(EXEC)\ $(CCFLAGS) $(CCDEFS) "$(CCHDRS)" "/I$(STDHDRS)" $(>) } actions C++ { $(C++) /c /Fo$(<) /Fd$(EXEC)\ $(C++FLAGS) $(CCDEFS) "$(CCHDRS)" "/I$(STDHDRS)" /Tp$(>) } actions MkTarArchive { tar cf $(<) -C $(>:P) $(>:BE)$(>:SE) } } 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) } } # end of Jamrules