common.mk revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
1# Copyright (c) 2012 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5# 6# GNU Make based build file. For details on GNU Make see: 7# http://www.gnu.org/software/make/manual/make.html 8# 9 10 11# 12# Toolchain 13# 14# By default the VALID_TOOLCHAINS list contains newlib and glibc. If your 15# project only builds in one or the other then this should be overridden 16# accordingly. 17# 18VALID_TOOLCHAINS?=newlib glibc 19TOOLCHAIN?=$(word 1,$(VALID_TOOLCHAINS)) 20 21 22# 23# Top Make file, which we want to trigger a rebuild on if it changes 24# 25TOP_MAKE:=$(word 1,$(MAKEFILE_LIST)) 26 27 28# 29# Figure out which OS we are running on. 30# 31GETOS=python $(NACL_SDK_ROOT)/tools/getos.py 32OSNAME:=$(shell $(GETOS)) 33 34 35# 36# Verify we selected a valid toolchain for this example 37# 38ifeq (,$(findstring $(TOOLCHAIN),$(VALID_TOOLCHAINS))) 39 $(warning Availbile choices are: $(VALID_TOOLCHAINS)) 40 $(error Can not use TOOLCHAIN=$(TOOLCHAIN) on this example.) 41endif 42 43 44# 45# Build Configuration 46# 47# The SDK provides two sets of libraries, Debug and Release. Debug libraries 48# are compiled without optimizations to make debugging easier. By default 49# this will build a Debug configuration. 50# 51CONFIG?=Debug 52 53 54# 55# Note for Windows: 56# The GCC and LLVM toolchains (include the version of Make.exe that comes 57# with the SDK) expect and are capable of dealing with the '/' seperator. 58# For this reason, the tools in the SDK, including Makefiles and build scripts 59# have a preference for POSIX style command-line arguments. 60# 61# Keep in mind however that the shell is responsible for command-line escaping, 62# globbing, and variable expansion, so those may change based on which shell 63# is used. For Cygwin shells this can include automatic and incorrect expansion 64# of response files (files starting with '@'). 65# 66# Disable DOS PATH warning when using Cygwin based NaCl tools on Windows. 67# 68ifeq ($(OSNAME),win) 69 CYGWIN?=nodosfilewarning 70 export CYGWIN 71endif 72 73 74# 75# If NACL_SDK_ROOT is not already set, then set it relative to this makefile. 76# 77THIS_MAKEFILE:=$(CURDIR)/$(lastword $(MAKEFILE_LIST)) 78NACL_SDK_ROOT?=$(realpath $(dir $(THIS_MAKEFILE))/..) 79 80 81# 82# Check that NACL_SDK_ROOT is set to a valid location. 83# We use the existence of tools/oshelpers.py to verify the validity of the SDK 84# root. 85# 86ifeq (,$(wildcard $(NACL_SDK_ROOT)/tools/oshelpers.py)) 87 $(error NACL_SDK_ROOT is set to an invalid location: $(NACL_SDK_ROOT)) 88endif 89 90 91# 92# If this makefile is part of a valid nacl SDK, but NACL_SDK_ROOT is set 93# to a different location this is almost certainly a local configuration 94# error. 95# 96LOCAL_ROOT:=$(realpath $(dir $(THIS_MAKEFILE))/..) 97ifneq (,$(wildcard $(LOCAL_ROOT)/tools/oshelpers.py)) 98 ifneq ($(realpath $(NACL_SDK_ROOT)), $(realpath $(LOCAL_ROOT))) 99 $(error common.mk included from an SDK that does not match the current NACL_SDK_ROOT) 100 endif 101endif 102 103 104# 105# Alias for standard POSIX file system commands 106# 107OSHELPERS=python $(NACL_SDK_ROOT)/tools/oshelpers.py 108WHICH:=$(OSHELPERS) which 109ifdef V 110RM:=$(OSHELPERS) rm 111CP:=$(OSHELPERS) cp 112MKDIR:=$(OSHELPERS) mkdir 113MV:=$(OSHELPERS) mv 114else 115RM:=@$(OSHELPERS) rm 116CP:=@$(OSHELPERS) cp 117MKDIR:=@$(OSHELPERS) mkdir 118MV:=@$(OSHELPERS) mv 119endif 120 121 122 123# 124# Compute path to requested NaCl Toolchain 125# 126TC_PATH:=$(abspath $(NACL_SDK_ROOT)/toolchain) 127 128 129# 130# Check for required minimum SDK version. 131# 132ifdef NACL_SDK_VERSION_MIN 133 VERSION_CHECK:=$(shell $(GETOS) --check-version=$(NACL_SDK_VERSION_MIN) 2>&1) 134 ifneq ($(VERSION_CHECK),) 135 $(error $(VERSION_CHECK)) 136 endif 137endif 138 139 140# 141# The default target 142# 143# If no targets are specified on the command-line, the first target listed in 144# the makefile becomes the default target. By convention this is usually called 145# the 'all' target. Here we leave it blank to be first, but define it later 146# 147all: 148 149 150# 151# Target a toolchain 152# 153# $1 = Toolchain Name 154# 155define TOOLCHAIN_RULE 156.PHONY: all_$(1) 157all_$(1): 158 +$(MAKE) TOOLCHAIN=$(1) 159TOOLCHAIN_LIST+=all_$(1) 160endef 161 162 163# 164# The target for all versions 165# 166USABLE_TOOLCHAINS=$(filter $(OSNAME) newlib glibc pnacl,$(VALID_TOOLCHAINS)) 167 168ifeq ($(NO_HOST_BUILDS),1) 169USABLE_TOOLCHAINS:=$(filter-out $(OSNAME),$(USABLE_TOOLCHAINS)) 170endif 171 172$(foreach tool,$(USABLE_TOOLCHAINS),$(eval $(call TOOLCHAIN_RULE,$(tool),$(dep)))) 173 174.PHONY: all_versions 175all_versions: $(TOOLCHAIN_LIST) 176 177 178OUTBASE?=. 179OUTDIR:=$(OUTBASE)/$(TOOLCHAIN)/$(CONFIG) 180STAMPDIR?=$(OUTDIR) 181LIBDIR?=$(NACL_SDK_ROOT)/lib 182 183 184# 185# Target to remove temporary files 186# 187.PHONY: clean 188clean: 189 $(RM) -f $(TARGET).nmf 190 $(RM) -fr $(OUTDIR) 191 192 193# 194# Rules for output directories. 195# 196# Output will be places in a directory name based on Toolchain and configuration 197# be default this will be "newlib/Debug". We use a python wrapped MKDIR to 198# proivde a cross platform solution. The use of '|' checks for existance instead 199# of timestamp, since the directory can update when files change. 200# 201%dir.stamp : 202 $(MKDIR) -p $(dir $@) 203 @echo Directory Stamp > $@ 204 205 206# 207# Dependency Macro 208# 209# $1 = Name of stamp 210# $2 = Directory for the sub-make 211# $3 = Extra Settings 212# 213define DEPEND_RULE 214ifndef $(IGNORE_DEPS) 215.PHONY : rebuild_$(1) 216 217rebuild_$(1) :| $(STAMPDIR)/dir.stamp 218ifeq (,$(2)) 219 +$(MAKE) -C $(NACL_SDK_ROOT)/src/$(1) STAMPDIR=$(abspath $(STAMPDIR)) $(abspath $(STAMPDIR)/$(1).stamp) $(3) 220else 221 +$(MAKE) -C $(2) STAMPDIR=$(abspath $(STAMPDIR)) $(abspath $(STAMPDIR)/$(1).stamp) $(3) 222endif 223 224all: rebuild_$(1) 225$(STAMPDIR)/$(1).stamp : rebuild_$(1) 226 227else 228 229.PHONY : $(STAMPDIR)/$(1).stamp 230$(STAMPDIR)/$(1).stamp : 231 @echo Ignore $(1) 232endif 233endef 234 235 236ifeq ($(TOOLCHAIN),win) 237HOST_EXT=.dll 238else 239HOST_EXT=.so 240endif 241 242 243# 244# Common Compile Options 245# 246ifeq ($(CONFIG),Release) 247POSIX_FLAGS?=-g -O2 -pthread -MMD 248else 249POSIX_FLAGS?=-g -O0 -pthread -MMD -DNACL_SDK_DEBUG 250endif 251 252NACL_CFLAGS?=-Wno-long-long -Werror 253NACL_CXXFLAGS?=-Wno-long-long -Werror 254NACL_LDFLAGS?=-Wl,-as-needed 255 256# 257# Default Paths 258# 259ifeq (,$(findstring $(TOOLCHAIN),linux mac win)) 260INC_PATHS?=$(NACL_SDK_ROOT)/include $(EXTRA_INC_PATHS) 261else 262INC_PATHS?=$(NACL_SDK_ROOT)/include/$(OSNAME) $(NACL_SDK_ROOT)/include $(EXTRA_INC_PATHS) 263endif 264 265LIB_PATHS?=$(NACL_SDK_ROOT)/lib $(EXTRA_LIB_PATHS) 266 267# 268# Define a LOG macro that allow a command to be run in quiet mode where 269# the command echoed is not the same as the actual command executed. 270# The primary use case for this is to avoid echoing the full compiler 271# and linker command in the default case. Defining V=1 will restore 272# the verbose behavior 273# 274# $1 = The name of the tool being run 275# $2 = The target file being built 276# $3 = The full command to run 277# 278ifdef V 279define LOG 280$(3) 281endef 282else 283ifeq ($(OSNAME),win) 284define LOG 285@echo $(1) $(2) && $(3) 286endef 287else 288define LOG 289@echo " $(1) $(2)" && $(3) 290endef 291endif 292endif 293 294 295# 296# Convert a source path to a object file path. 297# 298# $1 = Source Name 299# $2 = Arch suffix 300# 301define SRC_TO_OBJ 302$(OUTDIR)/$(basename $(subst ..,__,$(1)))$(2).o 303endef 304 305 306# 307# Convert a source path to a dependency file path. 308# 309# $1 = Source Name 310# $2 = Arch suffix 311# 312define SRC_TO_DEP 313$(patsubst %.o,%.d,$(call SRC_TO_OBJ,$(1),$(2))) 314endef 315 316 317# 318# If the requested toolchain is a NaCl or PNaCl toolchain, the use the 319# macros and targets defined in nacl.mk, otherwise use the host sepecific 320# macros and targets. 321# 322ifneq (,$(findstring $(TOOLCHAIN),linux mac)) 323include $(NACL_SDK_ROOT)/tools/host_gcc.mk 324endif 325 326ifneq (,$(findstring $(TOOLCHAIN),win)) 327include $(NACL_SDK_ROOT)/tools/host_vc.mk 328endif 329 330ifneq (,$(findstring $(TOOLCHAIN),glibc newlib)) 331include $(NACL_SDK_ROOT)/tools/nacl_gcc.mk 332endif 333 334ifneq (,$(findstring $(TOOLCHAIN),pnacl)) 335include $(NACL_SDK_ROOT)/tools/nacl_llvm.mk 336endif 337 338# 339# File to redirect to to in order to hide output. 340# 341ifeq ($(OSNAME),win) 342DEV_NULL=nul 343else 344DEV_NULL=/dev/null 345endif 346 347# 348# Assign a sensible default to CHROME_PATH. 349# 350CHROME_PATH?=$(shell python $(NACL_SDK_ROOT)/tools/getos.py --chrome 2> $(DEV_NULL)) 351 352# 353# Verify we can find the Chrome executable if we need to launch it. 354# 355.PHONY: check_for_chrome 356check_for_chrome: 357ifeq (,$(wildcard $(CHROME_PATH))) 358 $(warning No valid Chrome found at CHROME_PATH=$(CHROME_PATH)) 359 $(error Set CHROME_PATH via an environment variable, or command-line.) 360else 361 $(warning Using chrome at: $(CHROME_PATH)) 362endif 363 364 365# 366# Variables for running examples with Chrome. 367# 368RUN_PY:=python $(NACL_SDK_ROOT)/tools/run.py 369 370# Add this to launch Chrome with additional environment variables defined. 371# Each element should be specified as KEY=VALUE, with whitespace separating 372# key-value pairs. e.g. 373# CHROME_ENV=FOO=1 BAR=2 BAZ=3 374CHROME_ENV?= 375 376# Additional arguments to pass to Chrome. 377CHROME_ARGS+=--enable-nacl --enable-pnacl --incognito --ppapi-out-of-process 378 379 380# Paths to Debug and Release versions of the Host Pepper plugins 381PPAPI_DEBUG=$(abspath $(OSNAME)/Debug/$(TARGET)$(HOST_EXT));application/x-ppapi-debug 382PPAPI_RELEASE=$(abspath $(OSNAME)/Release/$(TARGET)$(HOST_EXT));application/x-ppapi-release 383 384 385PAGE?=index.html 386PAGE_TC_CONFIG="$(PAGE)?tc=$(TOOLCHAIN)&config=$(CONFIG)" 387 388.PHONY: run 389run: check_for_chrome all 390ifeq (,$(wildcard $(PAGE))) 391 $(error No valid HTML page found at $(PAGE)) 392endif 393 $(RUN_PY) -C $(CURDIR) -P $(PAGE_TC_CONFIG) \ 394 $(addprefix -E ,$(CHROME_ENV)) -- $(CHROME_PATH) $(CHROME_ARGS) \ 395 --register-pepper-plugins="$(PPAPI_DEBUG),$(PPAPI_RELEASE)" 396 397.PHONY: run_package 398run_package: check_for_chrome all 399 $(CHROME_PATH) --load-and-launch-app=$(CURDIR) --enable-nacl --enable-pnacl 400 401 402SYSARCH=$(shell python $(NACL_SDK_ROOT)/tools/getos.py --nacl-arch) 403GDB_ARGS+=-D $(TC_PATH)/$(OSNAME)_x86_$(TOOLCHAIN)/bin/$(SYSARCH)-nacl-gdb 404GDB_ARGS+=-D $(abspath $(OUTDIR))/$(TARGET)_$(SYSARCH).nexe 405 406.PHONY: debug 407debug: check_for_chrome all 408 $(RUN_PY) $(GDB_ARGS) \ 409 -C $(CURDIR) -P $(PAGE_TC_CONFIG) \ 410 $(addprefix -E ,$(CHROME_ENV)) -- $(CHROME_PATH) $(CHROME_ARGS) \ 411 --enable-nacl-debug \ 412 --register-pepper-plugins="$(PPAPI_DEBUG),$(PPAPI_RELEASE)" 413 414 415# uppercase aliases (for backward compatibility) 416.PHONY: CHECK_FOR_CHROME DEBUG LAUNCH RUN 417CHECK_FOR_CHROME: check_for_chrome 418DEBUG: debug 419LAUNCH: run 420RUN: run 421