1# Copyright (C) 2009-2010 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16# Initialization of the NDK build system. This file is included by
17# several build scripts.
18#
19
20# Disable GNU Make implicit rules
21
22# this turns off the suffix rules built into make
23.SUFFIXES:
24
25# this turns off the RCS / SCCS implicit rules of GNU Make
26% : RCS/%,v
27% : RCS/%
28% : %,v
29% : s.%
30% : SCCS/s.%
31
32# If a rule fails, delete $@.
33.DELETE_ON_ERROR:
34
35
36# Define NDK_LOG=1 in your environment to display log traces when
37# using the build scripts. See also the definition of ndk_log below.
38#
39NDK_LOG := $(strip $(NDK_LOG))
40ifeq ($(NDK_LOG),true)
41    override NDK_LOG := 1
42endif
43
44# Check that we have at least GNU Make 3.81
45# We do this by detecting whether 'lastword' is supported
46#
47MAKE_TEST := $(lastword a b c d e f)
48ifneq ($(MAKE_TEST),f)
49    $(error Android NDK: GNU Make version $(MAKE_VERSION) is too low (should be >= 3.81))
50endif
51ifeq ($(NDK_LOG),1)
52    $(info Android NDK: GNU Make version $(MAKE_VERSION) detected)
53endif
54
55# NDK_ROOT *must* be defined and point to the root of the NDK installation
56NDK_ROOT := $(strip $(NDK_ROOT))
57ifndef NDK_ROOT
58    $(error ERROR while including init.mk: NDK_ROOT must be defined !)
59endif
60ifneq ($(words $(NDK_ROOT)),1)
61    $(info,The Android NDK installation path contains spaces: '$(NDK_ROOT)')
62    $(error,Please fix the problem by reinstalling to a different location.)
63endif
64
65# ====================================================================
66#
67# Define a few useful variables and functions.
68# More stuff will follow in definitions.mk.
69#
70# ====================================================================
71
72# Used to output warnings and error from the library, it's possible to
73# disable any warnings or errors by overriding these definitions
74# manually or by setting NDK_NO_WARNINGS or NDK_NO_ERRORS
75
76__ndk_name    := Android NDK
77__ndk_info     = $(info $(__ndk_name): $1 $2 $3 $4 $5)
78__ndk_warning  = $(warning $(__ndk_name): $1 $2 $3 $4 $5)
79__ndk_error    = $(error $(__ndk_name): $1 $2 $3 $4 $5)
80
81ifdef NDK_NO_INFO
82__ndk_info :=
83endif
84ifdef NDK_NO_WARNINGS
85__ndk_warning :=
86endif
87ifdef NDK_NO_ERRORS
88__ndk_error :=
89endif
90
91# -----------------------------------------------------------------------------
92# Function : ndk_log
93# Arguments: 1: text to print when NDK_LOG is defined to 1
94# Returns  : None
95# Usage    : $(call ndk_log,<some text>)
96# -----------------------------------------------------------------------------
97ifeq ($(NDK_LOG),1)
98ndk_log = $(info $(__ndk_name): $1)
99else
100ndk_log :=
101endif
102
103# -----------------------------------------------------------------------------
104# Function : host-toolchain-path
105# Arguments: 1: NDK root
106#            2: Toolchain name
107# Returns  : The parent path of all toolchains for this host. Note that
108#            HOST_TAG64 == HOST_TAG for 32-bit systems.
109# -----------------------------------------------------------------------------
110ifeq ($(NDK_NEW_TOOLCHAINS_LAYOUT),true)
111    host-toolchain-path = $1/$(HOST_TAG64)/$2
112else
113    host-toolchain-path = $1/$2/prebuilt/$(HOST_TAG64)
114endif
115
116# -----------------------------------------------------------------------------
117# Function : get-toolchain-root
118# Arguments: 1: Toolchain name
119# Returns  : Path to the given prebuilt toolchain.
120# -----------------------------------------------------------------------------
121get-toolchain-root = $(call host-toolchain-path,$(NDK_TOOLCHAINS_ROOT),$1)
122
123# -----------------------------------------------------------------------------
124# Function : get-binutils-root
125# Arguments: 1: NDK root
126#            2: Toolchain name (no version number)
127# Returns  : Path to the given prebuilt binutils.
128# -----------------------------------------------------------------------------
129get-binutils-root = $1/binutils/$2
130
131# -----------------------------------------------------------------------------
132# Function : get-gcclibs-path
133# Arguments: 1: NDK root
134#            2: Toolchain name (no version number)
135# Returns  : Path to the given prebuilt gcclibs.
136# -----------------------------------------------------------------------------
137get-gcclibs-path = $1/gcclibs/$2
138
139# ====================================================================
140#
141# Host system auto-detection.
142#
143# ====================================================================
144
145#
146# Determine host system and architecture from the environment
147#
148HOST_OS := $(strip $(HOST_OS))
149ifndef HOST_OS
150    # On all modern variants of Windows (including Cygwin and Wine)
151    # the OS environment variable is defined to 'Windows_NT'
152    #
153    # The value of PROCESSOR_ARCHITECTURE will be x86 or AMD64
154    #
155    ifeq ($(OS),Windows_NT)
156        HOST_OS := windows
157    else
158        # For other systems, use the `uname` output
159        UNAME := $(shell uname -s)
160        ifneq (,$(findstring Linux,$(UNAME)))
161            HOST_OS := linux
162        endif
163        ifneq (,$(findstring Darwin,$(UNAME)))
164            HOST_OS := darwin
165        endif
166        # We should not be there, but just in case !
167        ifneq (,$(findstring CYGWIN,$(UNAME)))
168            HOST_OS := windows
169        endif
170        ifeq ($(HOST_OS),)
171            $(call __ndk_info,Unable to determine HOST_OS from uname -s: $(UNAME))
172            $(call __ndk_info,Please define HOST_OS in your environment.)
173            $(call __ndk_error,Aborting.)
174        endif
175    endif
176    $(call ndk_log,Host OS was auto-detected: $(HOST_OS))
177else
178    $(call ndk_log,Host OS from environment: $(HOST_OS))
179endif
180
181# For all systems, we will have HOST_OS_BASE defined as
182# $(HOST_OS), except on Cygwin where we will have:
183#
184#  HOST_OS      == cygwin
185#  HOST_OS_BASE == windows
186#
187# Trying to detect that we're running from Cygwin is tricky
188# because we can't use $(OSTYPE): It's a Bash shell variable
189# that is not exported to sub-processes, and isn't defined by
190# other shells (for those with really weird setups).
191#
192# Instead, we assume that a program named /bin/uname.exe
193# that can be invoked and returns a valid value corresponds
194# to a Cygwin installation.
195#
196HOST_OS_BASE := $(HOST_OS)
197
198ifeq ($(HOST_OS),windows)
199    ifneq (,$(strip $(wildcard /bin/uname.exe)))
200        $(call ndk_log,Found /bin/uname.exe on Windows host, checking for Cygwin)
201        # NOTE: The 2>NUL here is for the case where we're running inside the
202        #       native Windows shell. On cygwin, this will create an empty NUL file
203        #       that we're going to remove later (see below).
204        UNAME := $(shell /bin/uname.exe -s 2>NUL)
205        $(call ndk_log,uname -s returned: $(UNAME))
206        ifneq (,$(filter CYGWIN%,$(UNAME)))
207            $(call ndk_log,Cygwin detected: $(shell uname -a))
208            HOST_OS := cygwin
209            DUMMY := $(shell rm -f NUL) # Cleaning up
210        else
211            ifneq (,$(filter MINGW32%,$(UNAME)))
212                $(call ndk_log,MSys detected: $(shell uname -a))
213                HOST_OS := cygwin
214            else
215                $(call ndk_log,Cygwin *not* detected!)
216            endif
217        endif
218    endif
219endif
220
221ifneq ($(HOST_OS),$(HOST_OS_BASE))
222    $(call ndk_log, Host operating system detected: $(HOST_OS), base OS: $(HOST_OS_BASE))
223else
224    $(call ndk_log, Host operating system detected: $(HOST_OS))
225endif
226
227# Always use /usr/bin/file on Darwin to avoid relying on broken Ports
228# version. See http://b.android.com/53769 .
229HOST_FILE_PROGRAM := file
230ifeq ($(HOST_OS),darwin)
231HOST_FILE_PROGRAM := /usr/bin/file
232endif
233
234HOST_ARCH := $(strip $(HOST_ARCH))
235HOST_ARCH64 :=
236ifndef HOST_ARCH
237    ifeq ($(HOST_OS_BASE),windows)
238        HOST_ARCH := $(PROCESSOR_ARCHITECTURE)
239        ifeq ($(HOST_ARCH),AMD64)
240            HOST_ARCH := x86
241        endif
242        # Windows is 64-bit if either ProgramW6432 or ProgramFiles(x86) is set
243        ifneq ("/",$(shell echo "%ProgramW6432%/%ProgramFiles(x86)%"))
244            HOST_ARCH64 := x86_64
245        endif
246    else # HOST_OS_BASE != windows
247        UNAME := $(shell uname -m)
248        ifneq (,$(findstring 86,$(UNAME)))
249            HOST_ARCH := x86
250            ifneq (,$(shell $(HOST_FILE_PROGRAM) -L $(SHELL) | grep 'x86[_-]64'))
251                HOST_ARCH64 := x86_64
252            endif
253        endif
254        # We should probably should not care at all
255        ifneq (,$(findstring Power,$(UNAME)))
256            HOST_ARCH := ppc
257        endif
258        ifeq ($(HOST_ARCH),)
259            $(call __ndk_info,Unsupported host architecture: $(UNAME))
260            $(call __ndk_error,Aborting)
261        endif
262    endif # HOST_OS_BASE != windows
263    $(call ndk_log,Host CPU was auto-detected: $(HOST_ARCH))
264else
265    $(call ndk_log,Host CPU from environment: $(HOST_ARCH))
266endif
267
268ifeq (,$(HOST_ARCH64))
269    HOST_ARCH64 := $(HOST_ARCH)
270endif
271
272HOST_TAG := $(HOST_OS_BASE)-$(HOST_ARCH)
273HOST_TAG64 := $(HOST_OS_BASE)-$(HOST_ARCH64)
274
275# The directory separator used on this host
276HOST_DIRSEP := :
277ifeq ($(HOST_OS),windows)
278  HOST_DIRSEP := ;
279endif
280
281# The host executable extension
282HOST_EXEEXT :=
283ifeq ($(HOST_OS),windows)
284  HOST_EXEEXT := .exe
285endif
286
287# If we are on Windows, we need to check that we are not running
288# Cygwin 1.5, which is deprecated and won't run our toolchain
289# binaries properly.
290#
291ifeq ($(HOST_TAG),windows-x86)
292    ifeq ($(HOST_OS),cygwin)
293        # On cygwin, 'uname -r' returns something like 1.5.23(0.225/5/3)
294        # We recognize 1.5. as the prefix to look for then.
295        CYGWIN_VERSION := $(shell uname -r)
296        ifneq ($(filter XX1.5.%,XX$(CYGWIN_VERSION)),)
297            $(call __ndk_info,You seem to be running Cygwin 1.5, which is not supported.)
298            $(call __ndk_info,Please upgrade to Cygwin 1.7 or higher.)
299            $(call __ndk_error,Aborting.)
300        endif
301    endif
302    # special-case the host-tag
303    HOST_TAG := windows
304endif
305
306$(call ndk_log,HOST_TAG set to $(HOST_TAG))
307
308# Check for NDK-specific versions of our host tools
309HOST_TOOLS_ROOT := $(NDK_ROOT)/prebuilt/$(HOST_TAG64)
310HOST_PREBUILT := $(strip $(wildcard $(HOST_TOOLS_ROOT)/bin))
311HOST_AWK := $(strip $(NDK_HOST_AWK))
312HOST_MAKE := $(strip $(NDK_HOST_MAKE))
313HOST_PYTHON := $(strip $(NDK_HOST_PYTHON))
314ifdef HOST_PREBUILT
315    $(call ndk_log,Host tools prebuilt directory: $(HOST_PREBUILT))
316    # The windows prebuilt binaries are for ndk-build.cmd
317    # On cygwin, we must use the Cygwin version of these tools instead.
318    ifneq ($(HOST_OS),cygwin)
319        ifndef HOST_AWK
320            HOST_AWK := $(wildcard $(HOST_PREBUILT)/awk$(HOST_EXEEXT))
321        endif
322        ifndef HOST_MAKE
323            HOST_MAKE := $(wildcard $(HOST_PREBUILT)/make$(HOST_EXEEXT))
324        endif
325       ifndef HOST_PYTHON
326            HOST_PYTHON := $(wildcard $(HOST_PREBUILT)/python$(HOST_EXEEXT))
327        endif
328    endif
329else
330    $(call ndk_log,Host tools prebuilt directory not found, using system tools)
331endif
332
333HOST_ECHO := $(strip $(NDK_HOST_ECHO))
334ifdef HOST_PREBUILT
335    ifndef HOST_ECHO
336        # Special case, on Cygwin, always use the host echo, not our prebuilt one
337        # which adds \r\n at the end of lines.
338        ifneq ($(HOST_OS),cygwin)
339            HOST_ECHO := $(strip $(wildcard $(HOST_PREBUILT)/echo$(HOST_EXEEXT)))
340        endif
341    endif
342endif
343ifndef HOST_ECHO
344    HOST_ECHO := echo
345endif
346$(call ndk_log,Host 'echo' tool: $(HOST_ECHO))
347
348# Define HOST_ECHO_N to perform the equivalent of 'echo -n' on all platforms.
349ifeq ($(HOST_OS),windows)
350  # Our custom toolbox echo binary supports -n.
351  HOST_ECHO_N := $(HOST_ECHO) -n
352else
353  # On Posix, just use bare printf.
354  HOST_ECHO_N := printf %s
355endif
356$(call ndk_log,Host 'echo -n' tool: $(HOST_ECHO_N))
357
358HOST_CMP := $(strip $(NDK_HOST_CMP))
359ifdef HOST_PREBUILT
360    ifndef HOST_CMP
361        HOST_CMP := $(strip $(wildcard $(HOST_PREBUILT)/cmp$(HOST_EXEEXT)))
362    endif
363endif
364ifndef HOST_CMP
365    HOST_CMP := cmp
366endif
367$(call ndk_log,Host 'cmp' tool: $(HOST_CMP))
368
369#
370# Verify that the 'awk' tool has the features we need.
371# Both Nawk and Gawk do.
372#
373HOST_AWK := $(strip $(HOST_AWK))
374ifndef HOST_AWK
375    HOST_AWK := awk
376endif
377$(call ndk_log,Host 'awk' tool: $(HOST_AWK))
378
379# Location of all awk scripts we use
380BUILD_AWK := $(NDK_ROOT)/build/awk
381
382AWK_TEST := $(shell $(HOST_AWK) -f $(BUILD_AWK)/check-awk.awk)
383$(call ndk_log,Host 'awk' test returned: $(AWK_TEST))
384ifneq ($(AWK_TEST),Pass)
385    $(call __ndk_info,Host 'awk' tool is outdated. Please define NDK_HOST_AWK to point to Gawk or Nawk !)
386    $(call __ndk_error,Aborting.)
387endif
388
389#
390# On Cygwin/MSys, define the 'cygwin-to-host-path' function here depending on the
391# environment. The rules are the following:
392#
393# 1/ If NDK_USE_CYGPATH=1 and cygpath does exist in your path, cygwin-to-host-path
394#    calls "cygpath -m" for each host path.  Since invoking 'cygpath -m' from GNU
395#    Make for each source file is _very_ slow, this is only a backup plan in
396#    case our automatic substitution function (described below) doesn't work.
397#
398# 2/ Generate a Make function that performs the mapping from cygwin/msys to host
399#    paths through simple substitutions.  It's really a series of nested patsubst
400#    calls, that loo like:
401#
402#     cygwin-to-host-path = $(patsubst /cygdrive/c/%,c:/%,\
403#                             $(patsusbt /cygdrive/d/%,d:/%, \
404#                              $1)
405#    or in MSys:
406#     cygwin-to-host-path = $(patsubst /c/%,c:/%,\
407#                             $(patsusbt /d/%,d:/%, \
408#                              $1)
409#
410# except that the actual definition is built from the list of mounted
411# drives as reported by "mount" and deals with drive letter cases (i.e.
412# '/cygdrive/c' and '/cygdrive/C')
413#
414ifeq ($(HOST_OS),cygwin)
415    CYGPATH := $(strip $(HOST_CYGPATH))
416    ifndef CYGPATH
417        $(call ndk_log, Probing for 'cygpath' program)
418        CYGPATH := $(strip $(shell which cygpath 2>/dev/null))
419        ifndef CYGPATH
420            $(call ndk_log, 'cygpath' was *not* found in your path)
421        else
422            $(call ndk_log, 'cygpath' found as: $(CYGPATH))
423        endif
424    endif
425
426    ifeq ($(NDK_USE_CYGPATH),1)
427        ifndef CYGPATH
428            $(call __ndk_info,No cygpath)
429            $(call __ndk_error,Aborting)
430        endif
431        $(call ndk_log, Forced usage of 'cygpath -m' through NDK_USE_CYGPATH=1)
432        cygwin-to-host-path = $(strip $(shell $(CYGPATH) -m $1))
433    else
434        # Call an awk script to generate a Makefile fragment used to define a function
435        WINDOWS_HOST_PATH_FRAGMENT := $(shell mount | tr '\\' '/' | $(HOST_AWK) -f $(BUILD_AWK)/gen-windows-host-path.awk)
436        ifeq ($(NDK_LOG),1)
437            $(info Using cygwin substitution rules:)
438            $(eval $(shell mount | tr '\\' '/' | $(HOST_AWK) -f $(BUILD_AWK)/gen-windows-host-path.awk -vVERBOSE=1))
439        endif
440        $(eval cygwin-to-host-path = $(WINDOWS_HOST_PATH_FRAGMENT))
441    endif
442endif # HOST_OS == cygwin
443
444# The location of the build system files
445BUILD_SYSTEM := $(NDK_ROOT)/build/core
446
447# Include common definitions
448include $(BUILD_SYSTEM)/definitions.mk
449
450# ====================================================================
451#
452# Read all platform-specific configuration files.
453#
454# Each platform must be located in build/platforms/android-<apilevel>
455# where <apilevel> corresponds to an API level number, with:
456#   3 -> Android 1.5
457#   4 -> next platform release
458#
459# ====================================================================
460
461# The platform files were moved in the Android source tree from
462# $TOP/ndk/build/platforms to $TOP/development/ndk/platforms. However,
463# the official NDK release packages still place them under the old
464# location for now, so deal with this here
465#
466NDK_PLATFORMS_ROOT := $(strip $(NDK_PLATFORMS_ROOT))
467ifndef NDK_PLATFORMS_ROOT
468    NDK_PLATFORMS_ROOT := $(strip $(wildcard $(NDK_ROOT)/platforms))
469    ifndef NDK_PLATFORMS_ROOT
470        NDK_PLATFORMS_ROOT := $(strip $(wildcard $(NDK_ROOT)/build/platforms))
471    endif
472
473    ifndef NDK_PLATFORMS_ROOT
474        $(call __ndk_info,Could not find platform files (headers and libraries))
475        $(if $(strip $(wildcard $(NDK_ROOT)/RELEASE.TXT)),\
476            $(call __ndk_info,Please define NDK_PLATFORMS_ROOT to point to a valid directory.)\
477        ,\
478            $(call __ndk_info,Please run build/tools/gen-platforms.sh to build the corresponding directory.)\
479        )
480        $(call __ndk_error,Aborting)
481    endif
482
483    $(call ndk_log,Found platform root directory: $(NDK_PLATFORMS_ROOT))
484endif
485ifeq ($(strip $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)),)
486    $(call __ndk_info,Your NDK_PLATFORMS_ROOT points to an invalid directory)
487    $(call __ndk_info,Current value: $(NDK_PLATFORMS_ROOT))
488    $(call __ndk_error,Aborting)
489endif
490
491NDK_ALL_PLATFORMS := $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)))
492$(call ndk_log,Found supported platforms: $(NDK_ALL_PLATFORMS))
493
494$(foreach _platform,$(NDK_ALL_PLATFORMS),\
495  $(eval include $(BUILD_SYSTEM)/add-platform.mk)\
496)
497
498# we're going to find the maximum platform number of the form android-<number>
499# ignore others, which could correspond to special and experimental cases
500NDK_PREVIEW_LEVEL := L
501NDK_ALL_PLATFORM_LEVELS := $(filter android-%,$(NDK_ALL_PLATFORMS))
502NDK_ALL_PLATFORM_LEVELS := $(patsubst android-%,%,$(NDK_ALL_PLATFORM_LEVELS))
503ifneq (,$(filter $(NDK_PREVIEW_LEVEL),$(NDK_ALL_PLATFORM_LEVELS)))
504    $(call __ndk_info,Please remove stale preview platforms/android-$(NDK_PREVIEW_LEVEL))
505    $(call __ndk_info,API level android-L is renamed as android-21.)
506    $(call __ndk_error,Aborting)
507endif
508$(call ndk_log,Found stable platform levels: $(NDK_ALL_PLATFORM_LEVELS))
509
510NDK_MAX_PLATFORM_LEVEL := 3
511$(foreach level,$(NDK_ALL_PLATFORM_LEVELS),\
512  $(eval NDK_MAX_PLATFORM_LEVEL := $$(call max,$$(NDK_MAX_PLATFORM_LEVEL),$$(level)))\
513)
514
515$(call ndk_log,Found max platform level: $(NDK_MAX_PLATFORM_LEVEL))
516
517# Allow the user to point at an alternate location for the toolchains. This is
518# particularly helpful if we want to use prebuilt toolchains for building an NDK
519# module. Specifically, we use this to build libc++ using ndk-build instead of
520# the old build-cxx-stl.sh and maintaining two sets of build rules.
521NDK_TOOLCHAINS_ROOT := $(strip $(NDK_TOOLCHAINS_ROOT))
522ifndef NDK_TOOLCHAINS_ROOT
523    NDK_TOOLCHAINS_ROOT := $(strip $(NDK_ROOT)/toolchains)
524endif
525
526# ====================================================================
527#
528# Read all toolchain-specific configuration files.
529#
530# Each toolchain must have a corresponding config.mk file located
531# in build/toolchains/<name>/ that will be included here.
532#
533# Each one of these files should define the following variables:
534#   TOOLCHAIN_NAME   toolchain name (e.g. arm-linux-androideabi-4.9)
535#   TOOLCHAIN_ABIS   list of target ABIs supported by the toolchain.
536#
537# Then, it should include $(ADD_TOOLCHAIN) which will perform
538# book-keeping for the build system.
539#
540# ====================================================================
541
542# the build script to include in each toolchain config.mk
543ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
544
545# the list of known abis and archs
546NDK_KNOWN_DEVICE_ABI64S := arm64-v8a x86_64 mips64
547NDK_KNOWN_DEVICE_ABI32S := armeabi-v7a armeabi x86 mips
548NDK_KNOWN_DEVICE_ABIS := $(NDK_KNOWN_DEVICE_ABI64S) $(NDK_KNOWN_DEVICE_ABI32S)
549NDK_KNOWN_ABIS     := armeabi-v7a-hard $(NDK_KNOWN_DEVICE_ABIS)
550NDK_KNOWN_ABI32S   := armeabi-v7a-hard $(NDK_KNOWN_DEVICE_ABI32S)
551NDK_KNOWN_ARCHS    := arm x86 mips arm64 x86_64 mips64
552_archs := $(sort $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*/arch-*))))
553NDK_FOUND_ARCHS    := $(_archs:arch-%=%)
554
555# the list of abis 'APP_ABI=all' is expanded to
556ifneq (,$(filter yes all all32 all64,$(_NDK_TESTING_ALL_)))
557NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_ABIS)
558NDK_APP_ABI_ALL32_EXPANDED := $(NDK_KNOWN_ABI32S)
559else
560NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_DEVICE_ABIS)
561NDK_APP_ABI_ALL32_EXPANDED := $(NDK_KNOWN_DEVICE_ABI32S)
562endif
563NDK_APP_ABI_ALL64_EXPANDED := $(NDK_KNOWN_DEVICE_ABI64S)
564
565# For testing purpose
566ifeq ($(_NDK_TESTING_ALL_),all32)
567NDK_APP_ABI_ALL_EXPANDED := $(NDK_APP_ABI_ALL32_EXPANDED)
568else
569ifeq ($(_NDK_TESTING_ALL_),all64)
570NDK_APP_ABI_ALL_EXPANDED := $(NDK_APP_ABI_ALL64_EXPANDED)
571endif
572endif
573
574# The first API level ndk-build enforces -fPIE for executable
575NDK_FIRST_PIE_PLATFORM_LEVEL := 16
576
577# the list of all toolchains in this NDK
578NDK_ALL_TOOLCHAINS :=
579NDK_ALL_ABIS       :=
580NDK_ALL_ARCHS      :=
581
582TOOLCHAIN_CONFIGS := $(wildcard $(NDK_ROOT)/build/core/toolchains/*/config.mk)
583$(foreach _config_mk,$(TOOLCHAIN_CONFIGS),\
584  $(eval include $(BUILD_SYSTEM)/add-toolchain.mk)\
585)
586
587NDK_ALL_TOOLCHAINS   := $(sort $(NDK_ALL_TOOLCHAINS))
588NDK_ALL_ABIS         := $(sort $(NDK_ALL_ABIS))
589NDK_ALL_ARCHS        := $(sort $(NDK_ALL_ARCHS))
590
591# Check that each ABI has a single architecture definition
592$(foreach _abi,$(strip $(NDK_ALL_ABIS)),\
593  $(if $(filter-out 1,$(words $(NDK_ABI.$(_abi).arch))),\
594    $(call __ndk_info,INTERNAL ERROR: The $(_abi) ABI should have exactly one architecture definitions. Found: '$(NDK_ABI.$(_abi).arch)')\
595    $(call __ndk_error,Aborting...)\
596  )\
597)
598
599# Allow the user to define NDK_TOOLCHAIN to a custom toolchain name.
600# This is normally used when the NDK release comes with several toolchains
601# for the same architecture (generally for backwards-compatibility).
602#
603NDK_TOOLCHAIN := $(strip $(NDK_TOOLCHAIN))
604ifdef NDK_TOOLCHAIN
605    # check that the toolchain name is supported
606    $(if $(filter-out $(NDK_ALL_TOOLCHAINS),$(NDK_TOOLCHAIN)),\
607      $(call __ndk_info,NDK_TOOLCHAIN is defined to the unsupported value $(NDK_TOOLCHAIN)) \
608      $(call __ndk_info,Please use one of the following values: $(NDK_ALL_TOOLCHAINS))\
609      $(call __ndk_error,Aborting)\
610    ,)
611    $(call ndk_log, Using specific toolchain $(NDK_TOOLCHAIN))
612endif
613
614# Allow the user to define NDK_TOOLCHAIN_VERSION to override the toolchain
615# version number. Unlike NDK_TOOLCHAIN, this only changes the suffix of
616# the toolchain path we're using.
617#
618# For example, if GCC 4.8 is the default, defining NDK_TOOLCHAIN_VERSION=4.9
619# will ensure that ndk-build uses the following toolchains, depending on
620# the target architecture:
621#
622#    arm -> arm-linux-androideabi-4.9
623#    x86 -> x86-android-linux-4.9
624#    mips -> mipsel-linux-android-4.9
625#
626# This is used in setup-toolchain.mk
627#
628NDK_TOOLCHAIN_VERSION := $(strip $(NDK_TOOLCHAIN_VERSION))
629
630$(call ndk_log, This NDK supports the following target architectures and ABIS:)
631$(foreach arch,$(NDK_ALL_ARCHS),\
632    $(call ndk_log, $(space)$(space)$(arch): $(NDK_ARCH.$(arch).abis))\
633)
634$(call ndk_log, This NDK supports the following toolchains and target ABIs:)
635$(foreach tc,$(NDK_ALL_TOOLCHAINS),\
636    $(call ndk_log, $(space)$(space)$(tc):  $(NDK_TOOLCHAIN.$(tc).abis))\
637)
638
639