#============================================================================ # Rules for library creation # Copyright (C)2003 by Matze Braun # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Library General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public # License for more details. # # You should have received a copy of the GNU Library General Public License # along with this library; if not, write to the Free Software Foundation, # Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # #============================================================================ # Suppress ar's noisy report that it created the archive we asked it to create. if $(AR) && $(AR[2]) = ru { AR = $(AR[1]) ruc ; } ## Library libname : sources [ : options ] ## Build a library out of sourcefiles. All sourcefiles will be passed ## to the Objects rule which tries to compile them into object-files. You ## can create rules for your own filetypes with the UserObject rule. Header ## files will just be ignored. They are only used for MSVC projectfile ## generation. ## Available options are 'shared' if you want to build a shared library on ## platforms which support that. You can specify the 'noinstall' option if ## you don't want an install target generated. ## Don't specify any extensions for the library name, also leave out the ## leading "lib". ## Options: ## noinstall: Do not set up a default installation target. ## independent: The target will not be made a dependency of the libs and ## all targets. ## shared: Create as a shared library on supported platforms. ## nohelp: Do not invoke Help for this target. ## notest: Do not set up unit-testing support for this target. ## optional: Affects handling of the library in cs-config; it is only ## reported as available when actually built. rule Library { local options = $(3) ; CheckOptions noinstall independent shared nohelp notest optional : $(options) : $(<) ; local target = [ ConstructLibraryTarget $(<) : $(options) ] ; local sources = [ DoSourceGrist $(>) ] ; local objects ; local i ; for i in $(sources) { if $(i:S) = $(SUFOBJ) { objects += $(i) ; } else { objects += [ CompileObjects $(i) ] ; } } $(<)_TYPE = library ; $(<)_OBJECTS = $(objects) ; $(<)_SOURCES = $(sources) ; $(<)_TARGET = $(target) ; # so 'jam foo' works when it's really foo.exe (Windows) or foo.app (MacOS/X) if $(target) != $(<) { Depends $(<) : $(target) ; NotFile $(<) ; } # library depends on its member objects if ! [ IsElem independent : $(options) ] { if $(KEEPOBJS) { Depends obj : $(objects) ; } else { Depends libs : $(<) ; } } if ( ! [ IsElem shared : $(options) ] ) || ( $(BUILD_SHARED_LIBS) != "yes" ) { $(<)_SHARED = "" ; LibraryStatic $(<) : $(objects) : [ Filter $(options) : shared ] : $(target) ; } else { $(<)_SHARED = "shared" ; LibraryShared $(<) : $(objects) : $(options) : $(target) ; } CFlags $(<) : $(LIBRARY.CFLAGS) ; LFlags $(<) : $(LIBRARY.LFLAGS) ; # create target clean rule Always $(<)clean ; NotFile $(<)clean ; Clean $(<)clean : $(objects) $($(<)_CLEANEXTRA) ; Clean clean : $($(<)_CLEANEXTRA) ; if ! [ IsElem nohelp : $(options) ] { local desc = [ Description $(<) ] ; if ! $(desc) { desc = "$(<) library" ; } Help $(<) : "Build the $(desc)" ; } if ! [ IsElem notest : $(options) ] { UnitTest $(<) ; } } ## LibDepends libname : dependant libraries ## Make Library dependant on other libraries. This will tell the build ## system that your library uses functions from other libraries in the ## project. Note that a library shouldn't be linked with any external ## library that should be done by the final application which uses the ## library. rule LibDepends { $(<)_depends += $(>) ; if "$($(<)_SHARED)" { LinkWith $(<) : $(>) ; } UnitTestLibDepends $(<) : $(>) ; } #---------------------------------------------------------------------------- # private part # LibraryStatic libname : sources : options : decoratedtarget rule LibraryStatic { local objects = $(>) ; local options = $(3) ; local target = $(4) ; # Set LOCATE for the library and its contents. The bound # value shows up as $(NEEDLIBS) on the Link actions. # For compatibility, we only do this if the library doesn't # already have a path. if ! $(target:D) { MakeLocate $(target) $(target)($(objects:BS)) : $(LOCATE.OBJECTS)/libs ; } if $(NOARSCAN) { # If we can't scan the library to timestamp its contents, # we have to just make the library depend directly on the # on-disk object files. Depends $(target) : $(objects) ; } else { # If we can scan the library, we make the library depend # on its members and each member depend on the on-disk # object file. Depends $(target) : $(target)($(objects:BS)) ; local i ; for i in $(objects) { Depends $(target)($(i:BS)) : $(i) ; } } # Generate install rules if ! [ IsElem noinstall : $(options) ] { if "$(RANLIB)" { Depends install_lib : [ DoInstall $(target) : $(libdir) : : Ranlib ] ; } else { Depends install_lib : [ DoInstall $(target) : $(libdir) ] ; } # Add to global library list if [ IsElem optional : $(options) ] { INSTALLEDLIBS_OPTIONAL += $(<) ; } else { INSTALLEDLIBS += $(<) ; } } if $(CRELIB) { CreLib $(target) : $(objects[1]) ; } Archive $(target) : $(objects) ; if $(RANLIB) { Ranlib $(target) ; } # If we can't scan the library, we have to leave the .o's around. if ! ( $(NOARSCAN) || $(NOARUPDATE) || $(KEEPOBJS) ) { RmTemps $(target) : $(objects) ; } } # LibraryStatic libname : sources : options : decoratedtarget rule LibraryShared { local objects = $(>) ; local options = $(3) ; local target = $(4) ; local linklib = [ ConstructSharedLibraryLinkLib $(<) : $(options) ] ; local deplibs ; local i ; for i in $(LIBDEPENDS) { deplibs += [ ConstructLibraryLinkTarget $(i) : $(options) ] ; } # Generate install rules if ! [ IsElem noinstall : $(options) ] { if $(TARGET.OS) != WIN32 { Depends install_lib : [ DoInstall $(target) : $(libdir) ] ; } else { Depends install_lib : [ DoInstall $(target) : $(bindir) ] ; Depends install_lib : [ DoInstall $(linklib) : $(libdir) ] ; } # Add to global library list if [ IsElem optional : $(options) ] { INSTALLEDLIBS_OPTIONAL += $(<) ; } else { INSTALLEDLIBS += $(<) ; } } Depends $(<) : $(linklib) ; if $(linklib) != $(target) { Depends $(linklib) : $(target) ; MakeLocate $(linklib) : $(LOCATE.OBJECTS)/libs ; SEARCH on $(linklib) = $(LOCATE.OBJECTS)/libs ; } Depends $(target) : $(objects) ; $(<)_CLEANEXTRA += $(target) ; Depends $(target) : $(deplibs) ; CFlags $(<) : [ FDefines CS_$(<:U)_LIB ] ; LFlags $(<) : $(LINKLIBS) ; SystemLinkSharedLibrary $(target) : $(objects) $(deplibs) : $(linklib) ; if $(LINK.DEBUG.INFO.SEPARATE) = "yes" { local debugfile = [ SplitDebugInfo $(target) ] ; $(<)_CLEANEXTRA += $(debugfile) ; if ! [ IsElem noinstall : $(options) ] { NoCare $(debugfile) ; Depends install_lib : [ DoInstall $(debugfile) : $(libdir) : $(INSTALL_DATA) ] ; } } } rule ConstructLibraryTarget { if ( ! [ IsElem shared : $(>) ] ) || ( $(BUILD_SHARED_LIBS) != "yes" ) { return [ ConstructStaticLibraryTarget $(<) : [ Filter $(>) : shared ] ] ; } else { return [ ConstructSharedLibraryTarget $(<) : $(>) ] ; } } rule ConstructLibraryLinkTarget { if ( ! [ IsElem shared : $(>) ] ) || ( $(BUILD_SHARED_LIBS) != "yes" ) { return [ ConstructStaticLibraryTarget $(<) : [ Filter $(>) : shared ] ] ; } else { return [ ConstructSharedLibraryLinkLib $(<) : $(>) ] ; } } actions together Ranlib { $(RANLIB) $(<) } # Construct pseudo target libs which is used instead of the pseudo target lib # in Jambase Depends lib : libs ; NotFile libs ; Help libs : "Build all link libraries" ;