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
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
17 ifneq ($(ENABLE_BIONIC
),)
18 ALL_TOOLCHAINS ?
= pnacl newlib glibc clang-newlib bionic
20 ALL_TOOLCHAINS ?
= pnacl newlib glibc clang-newlib
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
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.
58 TOOLCHAIN_TARGETS
+= $(1)_TARGET
61 +$(MAKE
) TOOLCHAIN
=$(1) $(MAKECMDGOALS
)
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
))
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
)
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.
91 $(warning Availbile choices are
: $(VALID_TOOLCHAINS
))
92 $(error Can not use TOOLCHAIN
=$(TOOLCHAIN
) on this example.
)
95 # Dummy targets for recursive make with unsupported toolchain...
96 .PHONY
: all clean install
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
)))
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.
)
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.
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
149 CYGWIN ?
= nodosfilewarning
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
166 ifeq (,$(wildcard $(NACL_SDK_ROOT
)/tools
/oshelpers.py
))
167 $(error NACL_SDK_ROOT is set to an invalid location
: $(NACL_SDK_ROOT
))
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
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
)
185 # Alias for standard POSIX file system commands
187 OSHELPERS
= python
$(NACL_SDK_ROOT
)/tools
/oshelpers.py
188 WHICH
:= $(OSHELPERS
) which
190 RM
:= $(OSHELPERS
) rm
191 CP
:= $(OSHELPERS
) cp
192 MKDIR
:= $(OSHELPERS
) mkdir
193 MV
:= $(OSHELPERS
) mv
195 RM
:= @
$(OSHELPERS
) rm
196 CP
:= @
$(OSHELPERS
) cp
197 MKDIR
:= @
$(OSHELPERS
) mkdir
198 MV
:= @
$(OSHELPERS
) mv
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
))
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
235 # The install target is used to install built libraries to thier final destination.
236 # By default this is the NaCl SDK 'lib' folder.
247 OUTDIR
:= $(OUTBASE
)/$(TOOLCHAIN
)/standalone_
$(CONFIG
)
249 OUTDIR
:= $(OUTBASE
)/$(TOOLCHAIN
)/$(CONFIG
)
251 STAMPDIR ?
= $(OUTDIR
)
252 LIBDIR ?
= $(NACL_SDK_ROOT
)/lib
256 # Target to remove temporary files
260 $(RM
) -f
$(TARGET
).nmf
262 $(RM
) -rf user-data-dir
266 # Rules for output directories.
268 # Output will be places in a directory name based on Toolchain and configuration
269 # be default this will be "newlib/Debug". We use a python wrapped MKDIR to
270 # proivde a cross platform solution. The use of '|' checks for existance instead
271 # of timestamp, since the directory can update when files change.
274 $(MKDIR
) -p
$(dir $@
)
275 @echo Directory Stamp
> $@
282 # $2 = Directory for the sub-make
283 # $3 = Extra Settings
289 rebuild_
$(1) :|
$(STAMPDIR
)/dir.stamp
291 +$(MAKE
) -C
$(NACL_SDK_ROOT
)/src
/$(1) STAMPDIR
=$(abspath
$(STAMPDIR
)) $(abspath
$(STAMPDIR
)/$(1).stamp
) $(3)
293 +$(MAKE
) -C
$(2) STAMPDIR
=$(abspath
$(STAMPDIR
)) $(abspath
$(STAMPDIR
)/$(1).stamp
) $(3)
297 $(STAMPDIR
)/$(1).stamp
: rebuild_
$(1)
301 .PHONY
: $(STAMPDIR
)/$(1).stamp
302 $(STAMPDIR
)/$(1).stamp
:
307 ifeq ($(TOOLCHAIN
),win
)
323 # Common Compile Options
325 # For example, -DNDEBUG is added to release builds by default
326 # so that calls to assert(3) are not included in the build.
328 ifeq ($(CONFIG
),Release
)
329 POSIX_CFLAGS ?
= -g
-O2
-pthread
-MMD
-DNDEBUG
333 POSIX_CFLAGS ?
= -g
-O0
-pthread
-MMD
-DNACL_SDK_DEBUG
336 NACL_CFLAGS ?
= -Wno-long-long
-Werror
337 NACL_CXXFLAGS ?
= -Wno-long-long
-Werror
338 NACL_LDFLAGS
+= -Wl
,-as-needed
-pthread
343 INC_PATHS
:= $(shell $(NACL_CONFIG
) -t
$(TOOLCHAIN
) --include-dirs
) $(EXTRA_INC_PATHS
)
344 LIB_PATHS
:= $(NACL_SDK_ROOT
)/lib
$(EXTRA_LIB_PATHS
)
347 # Define a LOG macro that allow a command to be run in quiet mode where
348 # the command echoed is not the same as the actual command executed.
349 # The primary use case for this is to avoid echoing the full compiler
350 # and linker command in the default case. Defining V=1 will restore
351 # the verbose behavior
353 # $1 = The name of the tool being run
354 # $2 = The target file being built
355 # $3 = The full command to run
364 @echo
$(1) $(2) && $(3)
368 @echo
" $(1) $(2)" && $(3)
375 # Convert a source path to a object file path.
381 $(OUTDIR
)/$(basename $(subst ..
,__
,$(1)))$(2).o
386 # Convert a source path to a dependency file path.
387 # We use the .deps extension for dependencies. These files are generated by
388 # fix_deps.py based on the .d files which gcc generates. We don't reference
389 # the .d files directly so that we can avoid the the case where the compile
390 # failed but still generated a .d file (in that case the .d file would not
391 # be processed by fix_deps.py)
397 $(patsubst %.o
,%.deps
,$(call SRC_TO_OBJ
,$(1),$(2)))
401 # The gcc-generated deps files end in .d
403 define SRC_TO_DEP_PRE_FIXUP
404 $(patsubst %.o
,%.d
,$(call SRC_TO_OBJ
,$(1),$(2)))
409 # If the requested toolchain is a NaCl or PNaCl toolchain, the use the
410 # macros and targets defined in nacl.mk, otherwise use the host sepecific
411 # macros and targets.
413 ifneq (,$(findstring $(TOOLCHAIN
),linux mac
))
414 include $(NACL_SDK_ROOT
)/tools
/host_gcc.mk
417 ifneq (,$(findstring $(TOOLCHAIN
),win
))
418 include $(NACL_SDK_ROOT
)/tools
/host_vc.mk
421 ifneq (,$(findstring $(TOOLCHAIN
),glibc newlib bionic clang-newlib
))
422 include $(NACL_SDK_ROOT
)/tools
/nacl_gcc.mk
425 ifneq (,$(findstring $(TOOLCHAIN
),pnacl
))
426 include $(NACL_SDK_ROOT
)/tools
/nacl_llvm.mk
430 # File to redirect to to in order to hide output.
440 # Variables for running examples with Chrome.
442 RUN_PY
:= python
$(NACL_SDK_ROOT
)/tools
/run.py
443 HTTPD_PY
:= python
$(NACL_SDK_ROOT
)/tools
/httpd.py
445 # Add this to launch Chrome with additional environment variables defined.
446 # Each element should be specified as KEY=VALUE, with whitespace separating
447 # key-value pairs. e.g.
448 # CHROME_ENV=FOO=1 BAR=2 BAZ=3
451 # Additional arguments to pass to Chrome.
452 CHROME_ARGS
+= --enable-nacl
--enable-pnacl
--no-first-run
453 CHROME_ARGS
+= --user-data-dir
=$(CURDIR
)/user-data-dir
456 # Paths to Debug and Release versions of the Host Pepper plugins
457 PPAPI_DEBUG
= $(abspath
$(OSNAME
)/Debug
/$(TARGET
)$(HOST_EXT
));application
/x-ppapi-debug
458 PPAPI_RELEASE
= $(abspath
$(OSNAME
)/Release
/$(TARGET
)$(HOST_EXT
));application
/x-ppapi-release
461 SYSARCH
:= $(shell $(GETOS
) --nacl-arch
)
462 SEL_LDR_PATH
:= python
$(NACL_SDK_ROOT
)/tools
/sel_ldr.py
465 # Common Compile Options
467 ifeq ($(CONFIG
),Debug
)
468 SEL_LDR_ARGS
+= --debug-libs
473 # Assign a sensible default to CHROME_PATH.
475 CHROME_PATH ?
= $(shell $(GETOS
) --chrome
2> $(DEV_NULL
))
478 # Verify we can find the Chrome executable if we need to launch it.
482 SPACE
:= $(NULL
) # one space after NULL is required
483 CHROME_PATH_ESCAPE
:= $(subst $(SPACE
),\
,$(CHROME_PATH
))
486 SANDBOX_ARGS
:= --no-sandbox
489 GDB_PATH
:= $(shell $(NACL_CONFIG
) -t
$(TOOLCHAIN
) --tool
=gdb
)
491 .PHONY
: check_for_chrome
493 ifeq (,$(wildcard $(CHROME_PATH_ESCAPE
)))
494 $(warning No valid Chrome found at CHROME_PATH
=$(CHROME_PATH
))
495 $(error Set CHROME_PATH via an environment variable
, or command-line.
)
497 $(warning Using chrome at
: $(CHROME_PATH
))
500 PAGE_TC_CONFIG ?
= "$(PAGE)?tc=$(TOOLCHAIN)&config=$(CONFIG)"
503 run
: check_for_chrome
all $(PAGE
)
504 $(RUN_PY
) -C
$(CURDIR
) -P
$(PAGE_TC_CONFIG
) \
505 $(addprefix -E
,$(CHROME_ENV
)) -- "$(CHROME_PATH)" \
507 --register-pepper-plugins
="$(PPAPI_DEBUG),$(PPAPI_RELEASE)"
510 run_package
: check_for_chrome
all
511 @echo
"$(TOOLCHAIN) $(CONFIG)" > $(CURDIR
)/run_package_config
512 "$(CHROME_PATH)" --load-and-launch-app
=$(CURDIR
) $(CHROME_ARGS
)
514 GDB_ARGS
+= -D
$(GDB_PATH
)
515 # PNaCl's nexe is acquired with "remote get nexe <path>" instead of the NMF.
516 ifeq (,$(findstring $(TOOLCHAIN
),pnacl
))
517 GDB_ARGS
+= -D
--eval-command
="nacl-manifest $(abspath $(OUTDIR))/$(TARGET).nmf"
518 GDB_ARGS
+= -D
$(GDB_DEBUG_TARGET
)
522 debug
: check_for_chrome
all $(PAGE
)
523 $(RUN_PY
) $(GDB_ARGS
) \
524 -C
$(CURDIR
) -P
$(PAGE_TC_CONFIG
) \
525 $(addprefix -E
,$(CHROME_ENV
)) -- "$(CHROME_PATH)" \
526 $(CHROME_ARGS
) $(SANDBOX_ARGS
) --enable-nacl-debug \
527 --register-pepper-plugins
="$(PPAPI_DEBUG),$(PPAPI_RELEASE)"
531 $(HTTPD_PY
) -C
$(CURDIR
)
534 # uppercase aliases (for backward compatibility)
535 .PHONY
: CHECK_FOR_CHROME DEBUG LAUNCH RUN
536 CHECK_FOR_CHROME
: check_for_chrome
541 endif # TOOLCHAIN is valid...
543 endif # TOOLCHAIN=all