Add ICU message format support
[chromium-blink-merge.git] / native_client_sdk / src / tools / common.mk
blobd23dc8f8ffe67fe9aad9172398312d3e4f2d8ef0
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.
6 # GNU Make based build file. For details on GNU Make see:
7 # http://www.gnu.org/software/make/manual/make.html
11 # Toolchain
13 # By default the VALID_TOOLCHAINS list contains pnacl, newlib and glibc. If
14 # your project only builds in one or the other then this should be overridden
15 # accordingly.
17 ifneq ($(ENABLE_BIONIC),)
18 ALL_TOOLCHAINS ?= pnacl newlib glibc clang-newlib bionic
19 else
20 ALL_TOOLCHAINS ?= pnacl newlib glibc clang-newlib
21 endif
23 VALID_TOOLCHAINS ?= $(ALL_TOOLCHAINS)
24 TOOLCHAIN ?= $(word 1,$(VALID_TOOLCHAINS))
27 # Top Make file, which we want to trigger a rebuild on if it changes
29 TOP_MAKE := $(word 1,$(MAKEFILE_LIST))
33 # Figure out which OS we are running on.
35 GETOS := python $(NACL_SDK_ROOT)/tools/getos.py
36 NACL_CONFIG := python $(NACL_SDK_ROOT)/tools/nacl_config.py
37 FIXDEPS := python $(NACL_SDK_ROOT)/tools/fix_deps.py -c
38 OSNAME := $(shell $(GETOS))
42 # TOOLCHAIN=all recursively calls this Makefile for all VALID_TOOLCHAINS.
44 ifeq ($(TOOLCHAIN),all)
46 # Define the default target
47 all:
50 # Generate a new MAKE command for each TOOLCHAIN.
52 # Note: We use targets for each toolchain (instead of an explicit recipe) so
53 # each toolchain can be built in parallel.
55 # $1 = Toolchain Name
57 define TOOLCHAIN_RULE
58 TOOLCHAIN_TARGETS += $(1)_TARGET
59 .PHONY: $(1)_TARGET
60 $(1)_TARGET:
61 +$(MAKE) TOOLCHAIN=$(1) $(MAKECMDGOALS)
62 endef
65 # The target for all versions
67 USABLE_TOOLCHAINS=$(filter $(OSNAME) $(ALL_TOOLCHAINS),$(VALID_TOOLCHAINS))
69 ifeq ($(NO_HOST_BUILDS),1)
70 USABLE_TOOLCHAINS:=$(filter-out $(OSNAME),$(USABLE_TOOLCHAINS))
71 endif
73 # Define the toolchain targets for all usable toolchains via the macro.
74 $(foreach tool,$(USABLE_TOOLCHAINS),$(eval $(call TOOLCHAIN_RULE,$(tool))))
76 .PHONY: all clean install
77 all: $(TOOLCHAIN_TARGETS)
78 clean: $(TOOLCHAIN_TARGETS)
79 install: $(TOOLCHAIN_TARGETS)
81 else # TOOLCHAIN=all
84 # Verify we selected a valid toolchain for this example
86 ifeq (,$(findstring $(TOOLCHAIN),$(VALID_TOOLCHAINS)))
88 # Only fail to build if this is a top-level make. When building recursively, we
89 # don't care if an example can't build with this toolchain.
90 ifeq ($(MAKELEVEL),0)
91 $(warning Availbile choices are: $(VALID_TOOLCHAINS))
92 $(error Can not use TOOLCHAIN=$(TOOLCHAIN) on this example.)
93 else
95 # Dummy targets for recursive make with unsupported toolchain...
96 .PHONY: all clean install
97 all:
98 clean:
99 install:
101 endif
103 else # TOOLCHAIN is valid...
106 # Build Configuration
108 # The SDK provides two sets of libraries, Debug and Release. Debug libraries
109 # are compiled without optimizations to make debugging easier. By default
110 # this will build a Release configuration. When debugging via "make debug",
111 # build the debug configuration by default instead.
113 ifneq (,$(findstring debug,$(MAKECMDGOALS)))
114 CONFIG ?= Debug
115 else
116 CONFIG ?= Release
117 endif
121 # Verify we selected a valid configuration for this example.
123 VALID_CONFIGS ?= Debug Release
124 ifeq (,$(findstring $(CONFIG),$(VALID_CONFIGS)))
125 $(warning Availbile choices are: $(VALID_CONFIGS))
126 $(error Can not use CONFIG=$(CONFIG) on this example.)
127 endif
131 # Note for Windows:
132 # The GCC and LLVM toolchains (include the version of Make.exe that comes
133 # with the SDK) expect and are capable of dealing with the '/' seperator.
134 # For this reason, the tools in the SDK, including Makefiles and build scripts
135 # have a preference for POSIX style command-line arguments.
137 # Keep in mind however that the shell is responsible for command-line escaping,
138 # globbing, and variable expansion, so those may change based on which shell
139 # is used. For Cygwin shells this can include automatic and incorrect expansion
140 # of response files (files starting with '@').
142 # Disable DOS PATH warning when using Cygwin based NaCl tools on Windows.
144 ifeq ($(OSNAME),win)
145 # Always use cmd.exe as the shell on Windows. Otherwise Make may try to
146 # search the path for sh.exe. If it is found in a path with a space, the
147 # command will fail.
148 SHELL := cmd.exe
149 CYGWIN ?= nodosfilewarning
150 export CYGWIN
151 endif
155 # If NACL_SDK_ROOT is not already set, then set it relative to this makefile.
157 THIS_MAKEFILE := $(CURDIR)/$(lastword $(MAKEFILE_LIST))
158 NACL_SDK_ROOT ?= $(realpath $(dir $(THIS_MAKEFILE))/..)
162 # Check that NACL_SDK_ROOT is set to a valid location.
163 # We use the existence of tools/oshelpers.py to verify the validity of the SDK
164 # root.
166 ifeq (,$(wildcard $(NACL_SDK_ROOT)/tools/oshelpers.py))
167 $(error NACL_SDK_ROOT is set to an invalid location: $(NACL_SDK_ROOT))
168 endif
172 # If this makefile is part of a valid nacl SDK, but NACL_SDK_ROOT is set
173 # to a different location this is almost certainly a local configuration
174 # error.
176 LOCAL_ROOT := $(realpath $(dir $(THIS_MAKEFILE))/..)
177 ifneq (,$(wildcard $(LOCAL_ROOT)/tools/oshelpers.py))
178 ifneq ($(realpath $(NACL_SDK_ROOT)), $(realpath $(LOCAL_ROOT)))
179 $(error common.mk included from an SDK that does not match the current NACL_SDK_ROOT)
180 endif
181 endif
185 # Alias for standard POSIX file system commands
187 OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py
188 WHICH := $(OSHELPERS) which
189 ifdef V
190 RM := $(OSHELPERS) rm
191 CP := $(OSHELPERS) cp
192 MKDIR := $(OSHELPERS) mkdir
193 MV := $(OSHELPERS) mv
194 else
195 RM := @$(OSHELPERS) rm
196 CP := @$(OSHELPERS) cp
197 MKDIR := @$(OSHELPERS) mkdir
198 MV := @$(OSHELPERS) mv
199 endif
204 # Compute path to requested NaCl Toolchain
206 TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain)
210 # Check for required minimum SDK version.
211 # A makefile can declare NACL_SDK_VERSION_MIN of the form "<major>.<position>",
212 # where <major> is the major Chromium version number, and <position> is the
213 # Chromium Cr-Commit-Position number. eg. "39.295386".
215 ifdef NACL_SDK_VERSION_MIN
216 VERSION_CHECK:=$(shell $(GETOS) --check-version=$(NACL_SDK_VERSION_MIN) 2>&1)
217 ifneq ($(VERSION_CHECK),)
218 $(error $(VERSION_CHECK))
219 endif
220 endif
224 # The default target
226 # If no targets are specified on the command-line, the first target listed in
227 # the makefile becomes the default target. By convention this is usually called
228 # the 'all' target. Here we leave it blank to be first, but define it later
230 all:
231 .PHONY: all
235 # The install target is used to install built libraries to thier final destination.
236 # By default this is the NaCl SDK 'lib' folder.
238 install:
239 .PHONY: install
241 ifdef SEL_LDR
242 STANDALONE = 1
243 endif
245 OUTBASE ?= .
246 CONFIG_DIR := $(CONFIG)
247 ifdef STANDALONE
248 CONFIG_DIR := standalone_$(CONFIG_DIR)
249 endif
250 ifdef MSAN
251 CONFIG_DIR := msan_$(CONFIG_DIR)
252 endif
253 ifdef TSAN
254 CONFIG_DIR := tsan_$(CONFIG_DIR)
255 endif
257 OUTDIR := $(OUTBASE)/$(TOOLCHAIN)/$(CONFIG_DIR)
258 STAMPDIR ?= $(OUTDIR)
259 LIBDIR ?= $(NACL_SDK_ROOT)/lib
263 # Target to remove temporary files
265 .PHONY: clean
266 clean:
267 $(RM) -f $(TARGET).nmf
268 $(RM) -rf $(OUTDIR)
269 $(RM) -rf user-data-dir
273 # Rules for output directories.
275 # Output will be places in a directory name based on Toolchain and configuration
276 # be default this will be "newlib/Debug". We use a python wrapped MKDIR to
277 # proivde a cross platform solution. The use of '|' checks for existance instead
278 # of timestamp, since the directory can update when files change.
280 %dir.stamp :
281 $(MKDIR) -p $(dir $@)
282 @echo Directory Stamp > $@
286 # Dependency Macro
288 # $1 = Name of stamp
289 # $2 = Directory for the sub-make
290 # $3 = Extra Settings
292 define DEPEND_RULE
293 ifndef IGNORE_DEPS
294 .PHONY: rebuild_$(1)
296 rebuild_$(1) :| $(STAMPDIR)/dir.stamp
297 ifeq (,$(2))
298 +$(MAKE) -C $(NACL_SDK_ROOT)/src/$(1) STAMPDIR=$(abspath $(STAMPDIR)) $(abspath $(STAMPDIR)/$(1).stamp) $(3)
299 else
300 +$(MAKE) -C $(2) STAMPDIR=$(abspath $(STAMPDIR)) $(abspath $(STAMPDIR)/$(1).stamp) $(3)
301 endif
303 all: rebuild_$(1)
304 $(STAMPDIR)/$(1).stamp: rebuild_$(1)
306 else
308 .PHONY: $(STAMPDIR)/$(1).stamp
309 $(STAMPDIR)/$(1).stamp:
310 @echo Ignore $(1)
311 endif
312 endef
314 ifeq ($(TOOLCHAIN),win)
315 ifdef STANDALONE
316 HOST_EXT = .exe
317 else
318 HOST_EXT = .dll
319 endif
320 else
321 ifdef STANDALONE
322 HOST_EXT =
323 else
324 HOST_EXT = .so
325 endif
326 endif
330 # Common Compile Options
332 # For example, -DNDEBUG is added to release builds by default
333 # so that calls to assert(3) are not included in the build.
335 ifeq ($(CONFIG),Release)
336 POSIX_CFLAGS ?= -g -O2 -pthread -MMD -DNDEBUG
337 NACL_LDFLAGS ?= -O2
338 PNACL_LDFLAGS ?= -O2
339 else
340 POSIX_CFLAGS ?= -g -O0 -pthread -MMD -DNACL_SDK_DEBUG
341 endif
343 NACL_CFLAGS ?= -Wno-long-long -Werror
344 NACL_CXXFLAGS ?= -Wno-long-long -Werror
345 NACL_LDFLAGS += -Wl,-as-needed -pthread
348 # Default Paths
350 INC_PATHS := $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) --include-dirs) $(EXTRA_INC_PATHS)
351 LIB_PATHS := $(NACL_SDK_ROOT)/lib $(EXTRA_LIB_PATHS)
354 # Define a LOG macro that allow a command to be run in quiet mode where
355 # the command echoed is not the same as the actual command executed.
356 # The primary use case for this is to avoid echoing the full compiler
357 # and linker command in the default case. Defining V=1 will restore
358 # the verbose behavior
360 # $1 = The name of the tool being run
361 # $2 = The target file being built
362 # $3 = The full command to run
364 ifdef V
365 define LOG
366 $(3)
367 endef
368 else
369 ifeq ($(OSNAME),win)
370 define LOG
371 @echo $(1) $(2) && $(3)
372 endef
373 else
374 define LOG
375 @echo " $(1) $(2)" && $(3)
376 endef
377 endif
378 endif
382 # Convert a source path to a object file path.
384 # $1 = Source Name
385 # $2 = Arch suffix
387 define SRC_TO_OBJ
388 $(OUTDIR)/$(basename $(subst ..,__,$(1)))$(2).o
389 endef
393 # Convert a source path to a dependency file path.
394 # We use the .deps extension for dependencies. These files are generated by
395 # fix_deps.py based on the .d files which gcc generates. We don't reference
396 # the .d files directly so that we can avoid the the case where the compile
397 # failed but still generated a .d file (in that case the .d file would not
398 # be processed by fix_deps.py)
400 # $1 = Source Name
401 # $2 = Arch suffix
403 define SRC_TO_DEP
404 $(patsubst %.o,%.deps,$(call SRC_TO_OBJ,$(1),$(2)))
405 endef
408 # The gcc-generated deps files end in .d
410 define SRC_TO_DEP_PRE_FIXUP
411 $(patsubst %.o,%.d,$(call SRC_TO_OBJ,$(1),$(2)))
412 endef
416 # If the requested toolchain is a NaCl or PNaCl toolchain, the use the
417 # macros and targets defined in nacl.mk, otherwise use the host sepecific
418 # macros and targets.
420 ifneq (,$(findstring $(TOOLCHAIN),linux mac))
421 include $(NACL_SDK_ROOT)/tools/host_gcc.mk
422 endif
424 ifneq (,$(findstring $(TOOLCHAIN),win))
425 include $(NACL_SDK_ROOT)/tools/host_vc.mk
426 endif
428 ifneq (,$(findstring $(TOOLCHAIN),glibc newlib bionic clang-newlib))
429 include $(NACL_SDK_ROOT)/tools/nacl_gcc.mk
430 endif
432 ifneq (,$(findstring $(TOOLCHAIN),pnacl))
433 include $(NACL_SDK_ROOT)/tools/nacl_llvm.mk
434 endif
437 # File to redirect to to in order to hide output.
439 ifeq ($(OSNAME),win)
440 DEV_NULL = nul
441 else
442 DEV_NULL = /dev/null
443 endif
447 # Variables for running examples with Chrome.
449 RUN_PY := python $(NACL_SDK_ROOT)/tools/run.py
450 HTTPD_PY := python $(NACL_SDK_ROOT)/tools/httpd.py
452 # Add this to launch Chrome with additional environment variables defined.
453 # Each element should be specified as KEY=VALUE, with whitespace separating
454 # key-value pairs. e.g.
455 # CHROME_ENV=FOO=1 BAR=2 BAZ=3
456 CHROME_ENV ?=
458 # Additional arguments to pass to Chrome.
459 CHROME_ARGS += --enable-nacl --enable-pnacl --no-first-run
460 CHROME_ARGS += --user-data-dir=$(CURDIR)/user-data-dir
463 # Paths to Debug and Release versions of the Host Pepper plugins
464 PPAPI_DEBUG = $(abspath $(OSNAME)/Debug/$(TARGET)$(HOST_EXT));application/x-ppapi-debug
465 PPAPI_RELEASE = $(abspath $(OSNAME)/Release/$(TARGET)$(HOST_EXT));application/x-ppapi-release
468 SYSARCH := $(shell $(GETOS) --nacl-arch)
469 SEL_LDR_PATH := python $(NACL_SDK_ROOT)/tools/sel_ldr.py
472 # Common Compile Options
474 ifeq ($(CONFIG),Debug)
475 SEL_LDR_ARGS += --debug-libs
476 endif
478 ifndef STANDALONE
480 # Assign a sensible default to CHROME_PATH.
482 CHROME_PATH ?= $(shell $(GETOS) --chrome 2> $(DEV_NULL))
485 # Verify we can find the Chrome executable if we need to launch it.
488 NULL :=
489 SPACE := $(NULL) # one space after NULL is required
490 CHROME_PATH_ESCAPE := $(subst $(SPACE),\ ,$(CHROME_PATH))
492 ifeq ($(OSNAME),win)
493 SANDBOX_ARGS := --no-sandbox
494 endif
496 GDB_PATH := $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) --tool=gdb)
498 .PHONY: check_for_chrome
499 check_for_chrome:
500 ifeq (,$(wildcard $(CHROME_PATH_ESCAPE)))
501 $(warning No valid Chrome found at CHROME_PATH=$(CHROME_PATH))
502 $(error Set CHROME_PATH via an environment variable, or command-line.)
503 else
504 $(warning Using chrome at: $(CHROME_PATH))
505 endif
506 PAGE ?= index.html
507 PAGE_TC_CONFIG ?= "$(PAGE)?tc=$(TOOLCHAIN)&config=$(CONFIG)"
509 .PHONY: run
510 run: check_for_chrome all $(PAGE)
511 $(RUN_PY) -C $(CURDIR) -P $(PAGE_TC_CONFIG) \
512 $(addprefix -E ,$(CHROME_ENV)) -- "$(CHROME_PATH)" \
513 $(CHROME_ARGS) \
514 --register-pepper-plugins="$(PPAPI_DEBUG),$(PPAPI_RELEASE)"
516 .PHONY: run_package
517 run_package: check_for_chrome all
518 @echo "$(TOOLCHAIN) $(CONFIG)" > $(CURDIR)/run_package_config
519 "$(CHROME_PATH)" --load-and-launch-app=$(CURDIR) $(CHROME_ARGS)
521 GDB_ARGS += -D $(GDB_PATH)
522 # PNaCl's nexe is acquired with "remote get nexe <path>" instead of the NMF.
523 ifeq (,$(findstring $(TOOLCHAIN),pnacl))
524 GDB_ARGS += -D --eval-command="nacl-manifest $(abspath $(OUTDIR))/$(TARGET).nmf"
525 GDB_ARGS += -D $(GDB_DEBUG_TARGET)
526 endif
528 .PHONY: debug
529 debug: check_for_chrome all $(PAGE)
530 $(RUN_PY) $(GDB_ARGS) \
531 -C $(CURDIR) -P $(PAGE_TC_CONFIG) \
532 $(addprefix -E ,$(CHROME_ENV)) -- "$(CHROME_PATH)" \
533 $(CHROME_ARGS) $(SANDBOX_ARGS) --enable-nacl-debug \
534 --register-pepper-plugins="$(PPAPI_DEBUG),$(PPAPI_RELEASE)"
536 .PHONY: serve
537 serve: all
538 $(HTTPD_PY) -C $(CURDIR)
539 endif
541 # uppercase aliases (for backward compatibility)
542 .PHONY: CHECK_FOR_CHROME DEBUG LAUNCH RUN
543 CHECK_FOR_CHROME: check_for_chrome
544 DEBUG: debug
545 LAUNCH: run
546 RUN: run
548 endif # TOOLCHAIN is valid...
550 endif # TOOLCHAIN=all