duke@1: # duke@1: # Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. duke@1: # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: # duke@1: # This code is free software; you can redistribute it and/or modify it duke@1: # under the terms of the GNU General Public License version 2 only, as duke@1: # published by the Free Software Foundation. Sun designates this duke@1: # particular file as subject to the "Classpath" exception as provided duke@1: # by Sun in the LICENSE file that accompanied this code. duke@1: # duke@1: # This code is distributed in the hope that it will be useful, but WITHOUT duke@1: # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: # version 2 for more details (a copy is included in the LICENSE file that duke@1: # accompanied this code). duke@1: # duke@1: # You should have received a copy of the GNU General Public License version duke@1: # 2 along with this work; if not, write to the Free Software Foundation, duke@1: # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: # duke@1: # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@1: # CA 95054 USA or visit www.sun.com if you need additional information or duke@1: # have any questions. duke@1: # duke@1: duke@1: # duke@1: # Generic makefile for building shared libraries. duke@1: # duke@1: duke@1: include $(TOPDIR)/make/common/Classes.gmk duke@1: duke@1: # duke@1: # It is important to define these *after* including Classes.gmk duke@1: # in order to override the values defined inthat makefile. duke@1: # duke@1: duke@1: ACTUAL_LIBRARY_NAME = $(LIB_PREFIX)$(LIBRARY).$(LIBRARY_SUFFIX) duke@1: ACTUAL_LIBRARY_DIR = $(LIB_LOCATION) duke@1: ACTUAL_LIBRARY = $(ACTUAL_LIBRARY_DIR)/$(ACTUAL_LIBRARY_NAME) duke@1: duke@1: library:: $(ACTUAL_LIBRARY) duke@1: duke@1: FILES_o = $(patsubst %.c, %.$(OBJECT_SUFFIX), $(addprefix $(OBJDIR)/, $(notdir $(FILES_c)))) duke@1: FILES_o += $(patsubst %.s, %.$(OBJECT_SUFFIX), $(addprefix $(OBJDIR)/, $(notdir $(FILES_s)))) duke@1: FILES_o += $(patsubst %.cpp, %.$(OBJECT_SUFFIX), $(addprefix $(OBJDIR)/, $(notdir $(FILES_cpp)))) duke@1: duke@1: ifeq ($(INCREMENTAL_BUILD),true) duke@1: FILES_d = $(patsubst %.c, %.$(DEPEND_SUFFIX), $(addprefix $(OBJDIR)/, $(notdir $(FILES_c)))) duke@1: FILES_d += $(patsubst %.cpp, %.$(DEPEND_SUFFIX), $(addprefix $(OBJDIR)/, $(notdir $(FILES_cpp)))) duke@1: endif # INCREMENTAL_BUILD duke@1: duke@1: ifeq ($(PLATFORM),solaris) duke@1: # List of all lint files, one for each .c file (only for C) duke@1: FILES_ln = $(patsubst %.c, %.$(LINT_SUFFIX), $(addprefix $(OBJDIR)/, $(notdir $(FILES_c)))) duke@1: endif duke@1: duke@1: # duke@1: # C++ libraries must be linked with CC. duke@1: # duke@1: ifdef CPLUSPLUSLIBRARY duke@1: LINKER=$(LINK.cc) duke@1: else duke@1: LINKER=$(LINK.c) duke@1: endif duke@1: duke@1: # We either need to import (copy) libraries in, or build them duke@1: $(ACTUAL_LIBRARY):: $(INIT) $(TEMPDIR) $(LIBDIR) $(BINDIR) $(EXTDIR) classheaders duke@1: duke@1: # duke@1: # COMPILE_APPROACH: Different approaches to compile up the native object duke@1: # files as quickly as possible. duke@1: # The setting of parallel works best on Unix, batch on Windows. duke@1: # duke@1: duke@1: COMPILE_FILES_o = $(OBJDIR)/.files_compiled duke@1: $(COMPILE_FILES_o): $(FILES_d) $(FILES_o) duke@1: @$(ECHO) "$<" >> $@ duke@1: clean:: duke@1: $(RM) $(COMPILE_FILES_o) duke@1: duke@1: # duke@1: # COMPILE_APPROACH=parallel: Will trigger compilations (just compilations) to duke@1: # happen in parallel. Greatly decreases Unix build time, even on single CPU duke@1: # machines, more so on multiple CPU machines. Default is 2 compiles duke@1: # at a time, but can be adjusted with ALT_PARALLEL_COMPILE_JOBS. duke@1: # Note that each .d file will also be dependent on it's .o file, see duke@1: # Rules.gmk. duke@1: # Note this does not depend on Rules.gmk to work like batch (below) duke@1: # and this technique doesn't seem to help Windows build time nor does duke@1: # it work very well, it's possible the Windows Visual Studio compilers duke@1: # don't work well in a parallel situation, this needs investigation. duke@1: # duke@1: duke@1: ifeq ($(COMPILE_APPROACH),parallel) duke@1: duke@1: .PHONY: library_parallel_compile duke@1: duke@1: library_parallel_compile: duke@1: @$(ECHO) "Begin parallel compiles: $(shell $(PWD))" duke@1: @$(MAKE) -j $(PARALLEL_COMPILE_JOBS) $(COMPILE_FILES_o) duke@1: @$(ECHO) "Done with parallel compiles: $(shell $(PWD))" duke@1: duke@1: $(ACTUAL_LIBRARY):: library_parallel_compile duke@1: duke@1: endif duke@1: duke@1: # duke@1: # COMPILE_APPROACH=batch: Will trigger compilations (just compilations) to duke@1: # happen in batch mode. Greatly decreases Windows build time. duke@1: # See logic in Rules.gmk for how compiles happen, the $(MAKE) in duke@1: # library_batch_compile below triggers the actions in Rules.gmk. duke@1: # Note that each .d file will also be dependent on it's .o file, see duke@1: # Rules.gmk. duke@1: # duke@1: ifeq ($(COMPILE_APPROACH),batch) duke@1: duke@1: .PHONY: library_batch_compile duke@1: duke@1: library_batch_compile: duke@1: @$(ECHO) "Begin BATCH compiles: $(shell $(PWD))" duke@1: $(MAKE) $(COMPILE_FILES_o) duke@1: $(MAKE) batch_compile duke@1: @$(ECHO) "Done with BATCH compiles: $(shell $(PWD))" duke@1: $(MAKE) COMPILE_APPROACH=normal $(COMPILE_FILES_o) duke@1: duke@1: $(ACTUAL_LIBRARY):: library_batch_compile duke@1: duke@1: endif duke@1: duke@1: ifeq ($(PLATFORM), windows) duke@1: duke@1: # duke@1: # Library building rules. duke@1: # duke@1: duke@1: $(LIBRARY).lib:: $(OBJDIR) duke@1: duke@1: # build it into $(OBJDIR) so that the other generated files get put duke@1: # there, then copy just the DLL (and MAP file) to the requested directory. duke@1: # duke@1: $(ACTUAL_LIBRARY):: $(OBJDIR)/$(LIBRARY).lcf duke@1: @$(prep-target) duke@1: @$(MKDIR) -p $(OBJDIR) duke@1: $(LINK) -dll -out:$(OBJDIR)/$(@F) \ duke@1: -map:$(OBJDIR)/$(LIBRARY).map \ duke@1: $(LFLAGS) @$(OBJDIR)/$(LIBRARY).lcf \ duke@1: $(OTHER_LCF) $(JAVALIB) $(LDLIBS) duke@1: $(CP) $(OBJDIR)/$(@F) $@ duke@1: $(CP) $(OBJDIR)/$(LIBRARY).map $(@D) duke@1: $(CP) $(OBJDIR)/$(LIBRARY).pdb $(@D) duke@1: duke@1: $(OBJDIR)/$(LIBRARY).lcf: $(OBJDIR)/$(LIBRARY).res $(COMPILE_FILES_o) $(FILES_m) duke@1: @$(prep-target) duke@1: @$(MKDIR) -p $(TEMPDIR) duke@1: @$(ECHO) $(FILES_o) > $@ duke@1: ifndef LOCAL_RESOURCE_FILE duke@1: @$(ECHO) $(OBJDIR)/$(LIBRARY).res >> $@ duke@1: endif duke@1: @$(ECHO) Created $@ duke@1: duke@1: RC_FLAGS += /D "J2SE_FNAME=$(LIBRARY).dll" \ duke@1: /D "J2SE_INTERNAL_NAME=$(LIBRARY)" \ duke@1: /D "J2SE_FTYPE=0x2L" duke@1: duke@1: $(OBJDIR)/$(LIBRARY).res: $(VERSIONINFO_RESOURCE) duke@1: ifndef LOCAL_RESOURCE_FILE duke@1: @$(prep-target) duke@1: $(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(@) $(VERSIONINFO_RESOURCE) duke@1: endif duke@1: duke@1: # duke@1: # Install a .lib file if required. duke@1: # duke@1: ifeq ($(INSTALL_DOT_LIB), true) duke@1: $(ACTUAL_LIBRARY):: $(LIBDIR)/$(LIBRARY).lib duke@1: duke@1: clean:: duke@1: -$(RM) $(LIBDIR)/$(LIBRARY).lib duke@1: duke@1: $(LIBDIR)/$(LIBRARY).lib:: $(OBJDIR)/$(LIBRARY).lib duke@1: $(install-file) duke@1: duke@1: $(LIBDIR)/$(LIBRARY).dll:: $(OBJDIR)/$(LIBRARY).dll duke@1: $(install-file) duke@1: duke@1: endif # INSTALL_DOT_LIB duke@1: duke@1: else # PLATFORM duke@1: duke@1: # duke@1: # On Solaris, use mcs to write the version into the comment section of duke@1: # the shared library. On other platforms set this to false at the duke@1: # make command line. duke@1: # duke@1: $(ACTUAL_LIBRARY):: $(COMPILE_FILES_o) $(FILES_m) $(FILES_reorder) duke@1: @$(prep-target) duke@1: @$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), _OPT=$(_OPT)" duke@1: @$(ECHO) "Rebuilding $@ because of $?" duke@1: $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(FILES_o) $(LDLIBS) duke@1: ifeq ($(WRITE_LIBVERSION),true) duke@1: $(MCS) -d -a "$(FULL_VERSION)" $@ duke@1: endif # WRITE_LIBVERSION duke@1: duke@1: endif # PLATFORM duke@1: duke@1: # duke@1: # Cross check all linted files against each other duke@1: # duke@1: ifeq ($(PLATFORM),solaris) duke@1: lint.errors : $(FILES_ln) duke@1: $(LINT.c) $(FILES_ln) $(LDLIBS) duke@1: endif duke@1: duke@1: # duke@1: # Class libraries with JNI native methods get a include to the package. duke@1: # duke@1: ifdef PACKAGE duke@1: vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR) duke@1: vpath %.c $(SHARE_SRC)/native/$(PKGDIR) duke@1: OTHER_INCLUDES += -I$(SHARE_SRC)/native/common -I$(PLATFORM_SRC)/native/common duke@1: OTHER_INCLUDES += -I$(SHARE_SRC)/native/$(PKGDIR) \ duke@1: -I$(PLATFORM_SRC)/native/$(PKGDIR) duke@1: endif duke@1: duke@1: # duke@1: # Clean/clobber rules duke@1: # duke@1: clean:: duke@1: $(RM) -r $(ACTUAL_LIBRARY) duke@1: duke@1: clobber:: clean duke@1: duke@1: # duke@1: # INCREMENTAL_BUILD means that this workspace will be built over and over duke@1: # possibly incrementally. This means tracking the object file dependencies duke@1: # on include files so that sources get re-compiled when the include files duke@1: # change. When building from scratch and doing a one time build (like duke@1: # release engineering or nightly builds) set INCREMENTAL_BUILD=false. duke@1: # duke@1: duke@1: ifeq ($(INCREMENTAL_BUILD),true) duke@1: duke@1: # duke@1: # Workaround: gnumake sometimes says files is empty when it shouldn't duke@1: # was: files := $(foreach file, $(wildcard $(OBJDIR)/*.$(DEPEND_SUFFIX)), $(file)) duke@1: # duke@1: files := $(shell $(LS) $(OBJDIR)/*.$(DEPEND_SUFFIX) 2>/dev/null) duke@1: duke@1: # duke@1: # Only include these files if we have any. duke@1: # duke@1: ifneq ($(strip $(files)),) duke@1: duke@1: include $(files) duke@1: duke@1: endif # files duke@1: duke@1: endif # INCREMENTAL_BUILD duke@1: duke@1: # duke@1: # Default dependencies duke@1: # duke@1: duke@1: all: build duke@1: duke@1: build: library duke@1: duke@1: debug: duke@1: $(MAKE) VARIANT=DBG build duke@1: duke@1: fastdebug: duke@1: $(MAKE) VARIANT=DBG FASTDEBUG=true build duke@1: duke@1: .PHONY: all build debug fastdebug duke@1: