1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/common/makefiles/NativeCompilation.gmk Tue Apr 10 08:18:28 2012 -0700 1.3 @@ -0,0 +1,277 @@ 1.4 +# 1.5 +# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 +# 1.8 +# This code is free software; you can redistribute it and/or modify it 1.9 +# under the terms of the GNU General Public License version 2 only, as 1.10 +# published by the Free Software Foundation. Oracle designates this 1.11 +# particular file as subject to the "Classpath" exception as provided 1.12 +# by Oracle in the LICENSE file that accompanied this code. 1.13 +# 1.14 +# This code is distributed in the hope that it will be useful, but WITHOUT 1.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 +# version 2 for more details (a copy is included in the LICENSE file that 1.18 +# accompanied this code). 1.19 +# 1.20 +# You should have received a copy of the GNU General Public License version 1.21 +# 2 along with this work; if not, write to the Free Software Foundation, 1.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 +# 1.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 +# or visit www.oracle.com if you need additional information or have any 1.26 +# questions. 1.27 +# 1.28 + 1.29 +# When you read this source. Remember that $(sort ...) has the side effect 1.30 +# of removing duplicates. It is actually this side effect that is 1.31 +# desired whenever sort is used below! 1.32 + 1.33 +ifeq (,$(_MAKEBASE_GMK)) 1.34 + $(error You must include MakeBase.gmk prior to including JavaCompilation.gmk) 1.35 +endif 1.36 + 1.37 +ifeq ($(COMPILER_TYPE),CC) 1.38 + COMPILING_MSG=echo Compiling $1 1.39 + LINKING_MSG=echo Linking $1 1.40 + LINKING_EXE_MSG=echo Linking executable $1 1.41 + ARCHIVING_MSG=echo Archiving $1 1.42 +else 1.43 + COMPILING_MSG= 1.44 + LINKING_MSG= 1.45 + LINKING_EXE_MSG= 1.46 + ARCHIVING_MSG= 1.47 +endif 1.48 + 1.49 +define add_native_source 1.50 + # param 1 = BUILD_MYPACKAGE 1.51 + # parma 2 = the source file name (..../alfa.c or .../beta.cpp) 1.52 + # param 3 = the bin dir that stores all .o (.obj) and .d files. 1.53 + # param 4 = the c flags to the compiler 1.54 + # param 5 = the c compiler 1.55 + # param 6 = the c++ flags to the compiler 1.56 + # param 7 = the c++ compiler 1.57 + 1.58 + ifneq (,$$(filter %.c,$2)) 1.59 + # Compile as a C file 1.60 + $1_$2_FLAGS=$4 1.61 + $1_$2_COMP=$5 1.62 + else 1.63 + # Compile as a C++ file 1.64 + $1_$2_FLAGS=$6 1.65 + $1_$2_COMP=$7 1.66 + endif 1.67 + # Generate the .o (.obj) file name and place it in the bin dir. 1.68 + $1_$2_OBJ:=$3/$$(patsubst %.cpp,%$(OBJ_SUFFIX),$$(patsubst %.c,%$(OBJ_SUFFIX),$$(notdir $2))) 1.69 + # Only continue if this object file hasn't been processed already. This lets the first found 1.70 + # source file override any other with the same name. 1.71 + ifeq (,$$(findstring $$($1_$2_OBJ),$$($1_OBJS_SO_FAR))) 1.72 + $1_OBJS_SO_FAR+=$$($1_$2_OBJ) 1.73 + # And this is the dependency file for this obj file. 1.74 + $1_$2_DEP:=$$(patsubst %$(OBJ_SUFFIX),%.d,$$($1_$2_OBJ)) 1.75 + # Include previously generated dependency information. (if it exists) 1.76 + -include $$($1_$2_DEP) 1.77 + 1.78 + ifeq ($(COMPILER_TYPE),CL) 1.79 + $1_$2_DEBUG_OUT_FLAGS:=-Fd$$(patsubst %$(OBJ_SUFFIX),%.pdb,$$($1_$2_OBJ)) \ 1.80 + -Fm$$(patsubst %$(OBJ_SUFFIX),%.map,$$($1_$2_OBJ)) 1.81 + endif 1.82 + 1.83 + $$($1_$2_OBJ) : $2 1.84 + ifeq ($(COMPILER_TYPE),CC) 1.85 + $$(call COMPILING_MSG,$$(notdir $2)) 1.86 + $$($1_$2_COMP) $$($1_$2_FLAGS) -MMD -MF $$($1_$2_DEP) -c $(CC_OUT_OPTION)$$($1_$2_OBJ) $2 1.87 + endif 1.88 + ifeq ($(COMPILER_TYPE),CL) 1.89 + $$(call COMPILING_MSG,$$(notdir $2)) 1.90 + $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEBUG_OUT_FLAGS) -c $(CC_OUT_OPTION)$$($1_$2_OBJ) $2 1.91 + endif 1.92 + endif 1.93 +endef 1.94 + 1.95 +define SetupNativeCompilation 1.96 + # param 1 is for example BUILD_MYPACKAGE 1.97 + # param 2,3,4,5,6,7,8 are named args. 1.98 + # SRC one or more directory roots to scan for C/C++ files. 1.99 + # LANG C or C++ 1.100 + # CFLAGS the compiler flags to be used, used both for C and C++. 1.101 + # CXXFLAGS the compiler flags to be used for c++, if set overrides CFLAGS. 1.102 + # LDFLAGS the linker flags to be used, used both for C and C++. 1.103 + # LDFLAGS_SUFFIX the linker flags to be added last on the commandline 1.104 + # typically the libraries linked to. 1.105 + # ARFLAGS the archiver flags to be used 1.106 + # BIN the directory where we store the object files 1.107 + # LIB the resulting library file 1.108 + # EXE the resulting exec file 1.109 + # INCLUDES only pick source from these directories 1.110 + # EXCLUDES do not pick source from these directories 1.111 + # INCLUDE_FILES only compile exactly these files! 1.112 + # EXCLUDE_FILES with these names 1.113 + # VERSIONINFO_RESOURCE Input file for RC. Setting this implies that RC will be run 1.114 + # RC_FLAGS flags for RC. 1.115 + $(if $2,$1_$(strip $2)) 1.116 + $(if $3,$1_$(strip $3)) 1.117 + $(if $4,$1_$(strip $4)) 1.118 + $(if $5,$1_$(strip $5)) 1.119 + $(if $6,$1_$(strip $6)) 1.120 + $(if $7,$1_$(strip $7)) 1.121 + $(if $8,$1_$(strip $8)) 1.122 + $(if $9,$1_$(strip $9)) 1.123 + $(if $(10),$1_$(strip $(10))) 1.124 + $(if $(11),$1_$(strip $(11))) 1.125 + $(if $(12),$1_$(strip $(12))) 1.126 + $(if $(13),$1_$(strip $(13))) 1.127 + $(if $(14),$1_$(strip $(14))) 1.128 + $(if $(15),$1_$(strip $(15))) 1.129 + $(if $(16),$1_$(strip $(16))) 1.130 + $(if $(17),$1_$(strip $(17))) 1.131 + $(if $(18),$1_$(strip $(18))) 1.132 + $(if $(19),$1_$(strip $(19))) 1.133 + $(if $(20),$1_$(strip $(20))) 1.134 + 1.135 + ifeq (,$$($1_LANG)) 1.136 + $$(error You have to specify LANG for native compilation $1) 1.137 + endif 1.138 + ifeq (C,$$($1_LANG)) 1.139 + $1_LD:=$(LD) 1.140 + $1_LDEXE:=$(LDEXE) 1.141 + else 1.142 + ifeq (C++,$$($1_LANG)) 1.143 + $1_LD:=$(LDCXX) 1.144 + $1_LDEXE:=$(LDEXECXX) 1.145 + else 1.146 + $$(error Unknown native language $$($1_LANG) for $1) 1.147 + endif 1.148 + endif 1.149 + 1.150 + # Make sure the dirs exist. 1.151 + $$(shell $(MKDIR) -p $$($1_SRC) $$($1_BIN) $$(dir $$($1_LIB)) $$(dir $$($1_EXE))) 1.152 + # Find all files in the source trees. Sort to remove duplicates. 1.153 + $1_ALL_SRCS := $$(sort $$(foreach i,$$($1_SRC), $$(shell $(FIND) $$i -type f))) 1.154 + # Extract the C/C++ files. 1.155 + $1_EXCLUDE_FILES:=$$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_EXCLUDE_FILES))) 1.156 + $1_INCLUDE_FILES:=$$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_INCLUDE_FILES))) 1.157 + ifneq ($$($1_EXCLUDE_FILES),) 1.158 + $1_EXCLUDE_FILES:=$$(addprefix %,$$($1_EXCLUDE_FILES)) 1.159 + endif 1.160 + $1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES),$$(filter %.c %.cpp,$$($1_ALL_SRCS))) 1.161 + ifneq (,$$(strip $$($1_INCLUDE_FILES))) 1.162 + $1_SRCS := $$(filter $$($1_INCLUDE_FILES),$$($1_SRCS)) 1.163 + endif 1.164 + ifeq (,$$($1_SRCS)) 1.165 + $$(error No sources found for $1 when looking inside the dirs $$($1_SRC)) 1.166 + endif 1.167 + # There can be only a single bin dir root, no need to foreach over the roots. 1.168 + $1_BINS := $$(wildcard $$($1_BIN)/*$(OBJ_SUFFIX)) 1.169 + # Now we have a list of all c/c++ files to compile: $$($1_SRCS) 1.170 + # and we have a list of all existing object files: $$($1_BINS) 1.171 + 1.172 + # Prepend the source/bin path to the filter expressions. Then do the filtering. 1.173 + ifneq ($$($1_INCLUDES),) 1.174 + $1_SRC_INCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_INCLUDES)))) 1.175 + $1_SRCS := $$(filter $$($1_SRC_INCLUDES),$$($1_SRCS)) 1.176 + endif 1.177 + ifneq ($$($1_EXCLUDES),) 1.178 + $1_SRC_EXCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_EXCLUDES)))) 1.179 + $1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_SRCS)) 1.180 + endif 1.181 + 1.182 + # Calculate the expected output from compiling the sources (sort to remove duplicates. Also provides 1.183 + # a reproducable order on the input files to the linker). 1.184 + $1_EXPECTED_OBJS:=$$(sort $$(addprefix $$($1_BIN)/,$$(patsubst %.cpp,%$(OBJ_SUFFIX),$$(patsubst %.c,%$(OBJ_SUFFIX),$$(notdir $$($1_SRCS)))))) 1.185 + $1 := $$($1_EXPECTED_OBJS) 1.186 + # Are there too many object files on disk? Perhaps because some source file was removed? 1.187 + $1_SUPERFLOUS_OBJS:=$$(sort $$(filter-out $$($1_EXPECTED_OBJS),$$($1_BINS))) 1.188 + # Clean out the superfluous object files. 1.189 + $$(shell $(RM) -f $$($1_SUPERFLUOUS_OBJS)) 1.190 + 1.191 + # Pickup extra HOST_OS_API and/or PLATFORM dependent variables for CFLAGS. 1.192 + $1_EXTRA_CFLAGS:=$$($1_CFLAGS_$(HOST_OS_API)) $$($1_CFLAGS_$(PLATFORM)) 1.193 + ifneq ($(DEBUG_LEVEL),release) 1.194 + # Pickup extra debug dependent variables for CFLAGS 1.195 + $1_EXTRA_CFLAGS+=$$($1_CFLAGS_debug) 1.196 + $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(HOST_OS_API)_debug) 1.197 + $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(PLATFORM)_debug) 1.198 + else 1.199 + $1_EXTRA_CFLAGS+=$$($1_CFLAGS_release) 1.200 + $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(HOST_OS_API)_release) 1.201 + $1_EXTRA_CFLAGS+=$$($1_CFLAGS_$(PLATFORM)_release) 1.202 + endif 1.203 + 1.204 + # Pickup extra HOST_OS_API and/or PLATFORM dependent variables for CXXFLAGS. 1.205 + $1_EXTRA_CXXFLAGS:=$$($1_CXXFLAGS_$(HOST_OS_API)) $$($1_CXXFLAGS_$(PLATFORM)) 1.206 + ifneq ($(DEBUG_LEVEL),release) 1.207 + # Pickup extra debug dependent variables for CXXFLAGS 1.208 + $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_debug) 1.209 + $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(HOST_OS_API)_debug) 1.210 + $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(PLATFORM)_debug) 1.211 + else 1.212 + $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_release) 1.213 + $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(HOST_OS_API)_release) 1.214 + $1_EXTRA_CXXFLAGS+=$$($1_CXXFLAGS_$(PLATFORM)_release) 1.215 + endif 1.216 + 1.217 + ifeq ($$($1_CXXFLAGS),) 1.218 + $1_CXXFLAGS:=$$($1_CFLAGS) 1.219 + endif 1.220 + ifeq ($$(strip $$($1_EXTRA_CXXFLAGS)),) 1.221 + $1_EXTRA_CXXFLAGS:=$$($1_EXTRA_CFLAGS) 1.222 + endif 1.223 + 1.224 + # Now create a list of the packages that are about to compile. Used when sending source 1.225 + # in a batch to the compiler. 1.226 + $$(shell $(RM) $$($1_BIN)/_the.list_of_sources) 1.227 + $$(eval $$(call ListPathsSafelyNow,$1_SRCS,\n, >> $$($1_BIN)/_the.list_of_sources)) 1.228 + 1.229 + # Now call add_native_source for each source file we are going to compile. 1.230 + $$(foreach p,$$($1_SRCS),\ 1.231 + $$(eval $$(call add_native_source,$1,$$p,$$($1_BIN),\ 1.232 + $$($1_CFLAGS) $$($1_EXTRA_CFLAGS),$(CC),\ 1.233 + $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS),$(CXX)))) 1.234 + 1.235 + # On windows we need to create a resource file 1.236 + ifeq ($(HOST_OS_API), winapi) 1.237 + ifneq (,$$($1_VERSIONINFO_RESOURCE)) 1.238 + ifneq (,$$($1_LIB)) 1.239 + ifeq (dynamic,$$(patsubst %$(SHARED_LIBRARY_SUFFIX),dynamic,$$($1_LIB))) 1.240 + $1_RES:=$$(patsubst %$(SHARED_LIBRARY_SUFFIX),%.res,$$($1_LIB)) 1.241 + else 1.242 + $1_RES:=$$(patsubst %$(STATIC_LIBRARY_SUFFIX),%.res,$$($1_LIB)) 1.243 + endif 1.244 + endif 1.245 + ifneq (,$$($1_EXE)) 1.246 + $1_RES:=$$(patsubst %$(EXE_SUFFIX),%.res,$$($1_EXE)) 1.247 + endif 1.248 + $$($1_RES): $$($1_VERSIONINFO_RESOURCE) 1.249 + $(RC) $$($1_RC_FLAGS) $(CC_OUT_OPTION)$$@ $$($1_VERSIONINFO_RESOURCE) 1.250 + endif 1.251 + endif 1.252 + 1.253 + # Pickup extra HOST_OS_API dependent variables (posix or winapi) and 1.254 + # (linux,solaris,windows,bsd) for LDFLAGS and LDFLAGS_SUFFIX 1.255 + $1_EXTRA_LDFLAGS:=$$($1_LDFLAGS_$(HOST_OS_API)) $$($1_LDFLAGS_$(PLATFORM)) 1.256 + $1_EXTRA_LDFLAGS_SUFFIX:=$$($1_LDFLAGS_SUFFIX_$(HOST_OS_API)) $$($1_LDFLAGS_SUFFIX_$(PLATFORM)) 1.257 + ifneq (,$$($1_LIB)) 1.258 + ifeq (dynamic,$$(patsubst %$(SHARED_LIBRARY_SUFFIX),dynamic,$$($1_LIB))) 1.259 + # Generating a dynamic library. 1.260 + $1_EXTRA_LDFLAGS+=$$(call SET_SHARED_LIBRARY_NAME,$$(notdir $$($1_LIB))) 1.261 + $$($1_LIB) : $$($1_EXPECTED_OBJS) $$($1_RES) 1.262 + $$(call LINKING_MSG,$$(notdir $$($1_LIB))) 1.263 + $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(LD_OUT_OPTION)$$($1_LIB) \ 1.264 + $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) 1.265 + else 1.266 + # Generating a static library, ie object file archive. 1.267 + $$($1_LIB) : $$($1_EXPECTED_OBJS) $$($1_RES) 1.268 + $$(call ARCHIVING_MSG,$$(notdir $$($1_LIB))) 1.269 + $(AR) $$($1_AR_FLAGS) $(AR_OUT_OPTION)$$($1_LIB) $$($1_EXPECTED_OBJS) \ 1.270 + $$($1_RES) $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) 1.271 + endif 1.272 + endif 1.273 + ifneq (,$$($1_EXE)) 1.274 + # A executable binary has been specified, setup the target for it. 1.275 + $$($1_EXE) : $$($1_EXPECTED_OBJS) $$($1_RES) 1.276 + $$(call LINKING_EXE_MSG,$$(notdir $$($1_EXE))) 1.277 + $$($1_LDEXE) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(EXE_OUT_OPTION)$$($1_EXE) \ 1.278 + $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) 1.279 + endif 1.280 +endef