Home | History | Annotate | Download | only in core
      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 in your environment to display log traces when
     37 # using the build scripts. See also the definition of ndk_log below.
     38 #
     39 NDK_LOG := $(strip $(NDK_LOG))
     40 
     41 # Check that we have at least GNU Make 3.81
     42 # We do this by detecting whether 'lastword' is supported
     43 #
     44 MAKE_TEST := $(lastword a b c d e f)
     45 ifneq ($(MAKE_TEST),f)
     46     $(error Android NDK: GNU Make version $(MAKE_VERSION) is too low (should be >= 3.81))
     47 endif
     48 ifdef NDK_LOG
     49     $(info Android NDK: GNU Make version $(MAKE_VERSION) detected)
     50 endif
     51 
     52 # NDK_ROOT *must* be defined and point to the root of the NDK installation
     53 NDK_ROOT := $(strip $(NDK_ROOT))
     54 ifndef NDK_ROOT
     55     $(error ERROR while including init.mk: NDK_ROOT must be defined !)
     56 endif
     57 ifneq ($(words $(NDK_ROOT)),1)
     58     $(info,The Android NDK installation path contains spaces: '$(NDK_ROOT)')
     59     $(error,Please fix the problem by reinstalling to a different location.)
     60 endif
     61 
     62 # ====================================================================
     63 #
     64 # Define a few useful variables and functions.
     65 # More stuff will follow in definitions.mk.
     66 #
     67 # ====================================================================
     68 
     69 # Used to output warnings and error from the library, it's possible to
     70 # disable any warnings or errors by overriding these definitions
     71 # manually or by setting NDK_NO_WARNINGS or NDK_NO_ERRORS
     72 
     73 __ndk_name    := Android NDK
     74 __ndk_info     = $(info $(__ndk_name): $1 $2 $3 $4 $5)
     75 __ndk_warning  = $(warning $(__ndk_name): $1 $2 $3 $4 $5)
     76 __ndk_error    = $(error $(__ndk_name): $1 $2 $3 $4 $5)
     77 
     78 ifdef NDK_NO_WARNINGS
     79 __ndk_warning :=
     80 endif
     81 ifdef NDK_NO_ERRORS
     82 __ndk_error :=
     83 endif
     84 
     85 # -----------------------------------------------------------------------------
     86 # Function : ndk_log
     87 # Arguments: 1: text to print when NDK_LOG is defined
     88 # Returns  : None
     89 # Usage    : $(call ndk_log,<some text>)
     90 # -----------------------------------------------------------------------------
     91 ifdef NDK_LOG
     92 ndk_log = $(info $(__ndk_name): $1)
     93 else
     94 ndk_log :=
     95 endif
     96 
     97 # ====================================================================
     98 #
     99 # Host system auto-detection.
    100 #
    101 # ====================================================================
    102 
    103 #
    104 # Determine host system and architecture from the environment
    105 #
    106 HOST_OS := $(strip $(HOST_OS))
    107 ifndef HOST_OS
    108     # On all modern variants of Windows (including Cygwin and Wine)
    109     # the OS environment variable is defined to 'Windows_NT'
    110     #
    111     # The value of PROCESSOR_ARCHITECTURE will be x86 or AMD64
    112     #
    113     ifeq ($(OS),Windows_NT)
    114         HOST_OS := windows
    115     else
    116         # For other systems, use the `uname` output
    117         UNAME := $(shell uname -s)
    118         ifneq (,$(findstring Linux,$(UNAME)))
    119             HOST_OS := linux
    120         endif
    121         ifneq (,$(findstring Darwin,$(UNAME)))
    122             HOST_OS := darwin
    123         endif
    124         # We should not be there, but just in case !
    125         ifneq (,$(findstring CYGWIN,$(UNAME)))
    126             HOST_OS := windows
    127         endif
    128         ifeq ($(HOST_OS),)
    129             $(call __ndk_info,Unable to determine HOST_OS from uname -s: $(UNAME))
    130             $(call __ndk_info,Please define HOST_OS in your environment.)
    131             $(call __ndk_error,Aborting.)
    132         endif
    133     endif
    134     $(call ndk_log,Host OS was auto-detected: $(HOST_OS))
    135 else
    136     $(call ndk_log,Host OS from environment: $(HOST_OS))
    137 endif
    138 
    139 # For all systems, we will have HOST_OS_BASE defined as
    140 # $(HOST_OS), except on Cygwin where we will have:
    141 #
    142 #  HOST_OS      == cygwin
    143 #  HOST_OS_BASE == windows
    144 #
    145 # Trying to detect that we're running from Cygwin is tricky
    146 # because we can't use $(OSTYPE): It's a Bash shell variable
    147 # that is not exported to sub-processes, and isn't defined by
    148 # other shells (for those with really weird setups).
    149 #
    150 # Instead, we assume that a program named /bin/uname.exe
    151 # that can be invoked and returns a valid value corresponds
    152 # to a Cygwin installation.
    153 #
    154 HOST_OS_BASE := $(HOST_OS)
    155 
    156 ifeq ($(HOST_OS),windows)
    157     ifneq (,$(strip $(wildcard /bin/uname.exe)))
    158         $(call ndk_log,Found /bin/uname.exe on Windows host, checking for Cygwin)
    159         # NOTE: The 2>NUL here is for the case where we're running inside the
    160         #       native Windows shell. On cygwin, this will create an empty NUL file
    161         #       that we're going to remove later (see below).
    162         UNAME := $(shell /bin/uname.exe -s 2>NUL)
    163         $(call ndk_log,uname -s returned: $(UNAME))
    164         ifneq (,$(filter CYGWIN%,$(UNAME)))
    165             $(call ndk_log,Cygwin detected: $(shell uname -a))
    166             HOST_OS := cygwin
    167             DUMMY := $(shell rm -f NUL) # Cleaning up
    168         else
    169             ifneq (,$(filter MINGW32%,$(UNAME)))
    170                 $(call ndk_log,MSys detected: $(shell uname -a))
    171                 HOST_OS := cygwin
    172             else
    173                 $(call ndk_log,Cygwin *not* detected!)
    174             endif
    175         endif
    176     endif
    177 endif
    178 
    179 ifneq ($(HOST_OS),$(HOST_OS_BASE))
    180     $(call ndk_log, Host operating system detected: $(HOST_OS), base OS: $(HOST_OS_BASE))
    181 else
    182     $(call ndk_log, Host operating system detected: $(HOST_OS))
    183 endif
    184 
    185 HOST_ARCH := $(strip $(HOST_ARCH))
    186 ifndef HOST_ARCH
    187     ifeq ($(HOST_OS_BASE),windows)
    188         HOST_ARCH := $(PROCESSOR_ARCHITECTURE)
    189         ifeq ($(HOST_ARCH),AMD64)
    190             HOST_ARCH := x86
    191         endif
    192     else # HOST_OS_BASE != windows
    193         UNAME := $(shell uname -m)
    194         ifneq (,$(findstring 86,$(UNAME)))
    195             HOST_ARCH := x86
    196         endif
    197         # We should probably should not care at all
    198         ifneq (,$(findstring Power,$(UNAME)))
    199             HOST_ARCH := ppc
    200         endif
    201         ifeq ($(HOST_ARCH),)
    202             $(call __ndk_info,Unsupported host architecture: $(UNAME))
    203             $(call __ndk_error,Aborting)
    204         endif
    205     endif # HOST_OS_BASE != windows
    206     $(call ndk_log,Host CPU was auto-detected: $(HOST_ARCH))
    207 else
    208     $(call ndk_log,Host CPU from environment: $(HOST_ARCH))
    209 endif
    210 
    211 HOST_TAG := $(HOST_OS_BASE)-$(HOST_ARCH)
    212 
    213 # The directory separator used on this host
    214 HOST_DIRSEP := :
    215 ifeq ($(HOST_OS),windows)
    216   HOST_DIRSEP := ;
    217 endif
    218 
    219 # The host executable extension
    220 HOST_EXEEXT :=
    221 ifeq ($(HOST_OS),windows)
    222   HOST_EXEEXT := .exe
    223 endif
    224 
    225 # If we are on Windows, we need to check that we are not running
    226 # Cygwin 1.5, which is deprecated and won't run our toolchain
    227 # binaries properly.
    228 #
    229 ifeq ($(HOST_TAG),windows-x86)
    230     ifeq ($(HOST_OS),cygwin)
    231         # On cygwin, 'uname -r' returns something like 1.5.23(0.225/5/3)
    232         # We recognize 1.5. as the prefix to look for then.
    233         CYGWIN_VERSION := $(shell uname -r)
    234         ifneq ($(filter XX1.5.%,XX$(CYGWIN_VERSION)),)
    235             $(call __ndk_info,You seem to be running Cygwin 1.5, which is not supported.)
    236             $(call __ndk_info,Please upgrade to Cygwin 1.7 or higher.)
    237             $(call __ndk_error,Aborting.)
    238         endif
    239     endif
    240     # special-case the host-tag
    241     HOST_TAG := windows
    242 endif
    243 
    244 $(call ndk_log,HOST_TAG set to $(HOST_TAG))
    245 
    246 # Check for NDK-specific versions of our host tools
    247 HOST_PREBUILT := $(strip $(wildcard $(NDK_ROOT)/prebuilt/$(HOST_TAG)/bin))
    248 ifdef HOST_PREBUILT
    249     $(call ndk_log,Host tools prebuilt directory: $(HOST_PREBUILT))
    250     # The windows prebuilt binaries are for ndk-build.cmd
    251     # On cygwin, we must use the Cygwin version of these tools instead.
    252     ifneq ($(HOST_OS),cygwin)
    253         HOST_AWK := $(wildcard $(HOST_PREBUILT)/awk$(HOST_EXEEXT))
    254         HOST_SED  := $(wildcard $(HOST_PREBUILT)/sed$(HOST_EXEEXT))
    255         HOST_MAKE := $(wildcard $(HOST_PREBUILT)/make$(HOST_EXEEXT))
    256     endif
    257 else
    258     $(call ndk_log,Host tools prebuilt directory not found, using system tools)
    259 endif
    260 
    261 HOST_ECHO := $(strip $(HOST_ECHO))
    262 ifndef HOST_ECHO
    263     # Special case, on Cygwin, always use the host echo, not our prebuilt one
    264     # which adds \r\n at the end of lines.
    265     ifneq ($(HOST_OS),cygwin)
    266         HOST_ECHO := $(strip $(wildcard $(NDK_ROOT)/prebuilt/$(HOST_TAG)/bin/echo$(HOST_EXEEXT)))
    267     endif
    268 endif
    269 ifndef HOST_ECHO
    270     HOST_ECHO := echo
    271 endif
    272 $(call ndk_log,Host 'echo' tool: $(HOST_ECHO))
    273 
    274 # Define HOST_ECHO_N to perform the equivalent of 'echo -n' on all platforms.
    275 ifeq ($(HOST_OS),windows)
    276   # Our custom toolbox echo binary supports -n.
    277   HOST_ECHO_N := $(HOST_ECHO) -n
    278 else
    279   # On Posix, just use bare printf.
    280   HOST_ECHO_N := printf %s
    281 endif
    282 $(call ndk_log,Host 'echo -n' tool: $(HOST_ECHO_N))
    283 
    284 HOST_CMP := $(strip $(HOST_CMP))
    285 ifndef HOST_CMP
    286     HOST_CMP := $(strip $(wildcard $(NDK_ROOT)/prebuilt/$(HOST_TAG)/bin/cmp$(HOST_EXEEXT)))
    287 endif
    288 ifndef HOST_CMP
    289     HOST_CMP := cmp
    290 endif
    291 $(call ndk_log,Host 'cmp' tool: $(HOST_CMP))
    292 
    293 #
    294 # Verify that the 'awk' tool has the features we need.
    295 # Both Nawk and Gawk do.
    296 #
    297 HOST_AWK := $(strip $(HOST_AWK))
    298 ifndef HOST_AWK
    299     HOST_AWK := awk
    300 endif
    301 $(call ndk_log,Host 'awk' tool: $(HOST_AWK))
    302 
    303 # Location of all awk scripts we use
    304 BUILD_AWK := $(NDK_ROOT)/build/awk
    305 
    306 AWK_TEST := $(shell $(HOST_AWK) -f $(BUILD_AWK)/check-awk.awk)
    307 $(call ndk_log,Host 'awk' test returned: $(AWK_TEST))
    308 ifneq ($(AWK_TEST),Pass)
    309     $(call __ndk_info,Host 'awk' tool is outdated. Please define HOST_AWK to point to Gawk or Nawk !)
    310     $(call __ndk_error,Aborting.)
    311 endif
    312 
    313 #
    314 # On Cygwin, define the 'cygwin-to-host-path' function here depending on the
    315 # environment. The rules are the following:
    316 #
    317 # 1/ If "cygpath' is not in your path, do not use it at all. It looks like
    318 #    this allows to build with the NDK from MSys without problems.
    319 #
    320 # 2/ Since invoking 'cygpath -m' from GNU Make for each source file is
    321 #    _very_ slow, try to generate a Make function that performs the mapping
    322 #    from cygwin to host paths through simple substitutions.
    323 #
    324 # 3/ In case we fail horribly, allow the user to define NDK_USE_CYGPATH to '1'
    325 #    in order to use 'cygpath -m' nonetheless. This is only a backup plan in
    326 #    case our automatic substitution function doesn't work (only likely if you
    327 #    have a very weird cygwin setup).
    328 #
    329 # The function for 2/ is generated by an awk script. It's really a series
    330 # of nested patsubst calls, that look like:
    331 #
    332 #     cygwin-to-host-path = $(patsubst /cygdrive/c/%,c:/%,\
    333 #                             $(patsusbt /cygdrive/d/%,d:/%, \
    334 #                              $1)
    335 #
    336 # except that the actual definition is built from the list of mounted
    337 # drives as reported by "mount" and deals with drive letter cases (i.e.
    338 # '/cygdrive/c' and '/cygdrive/C')
    339 #
    340 ifeq ($(HOST_OS),cygwin)
    341     CYGPATH := $(strip $(HOST_CYGPATH))
    342     ifndef CYGPATH
    343         $(call ndk_log, Probing for 'cygpath' program)
    344         CYGPATH := $(strip $(shell which cygpath 2>/dev/null))
    345         ifndef CYGPATH
    346             $(call ndk_log, 'cygpath' was *not* found in your path)
    347         else
    348             $(call ndk_log, 'cygpath' found as: $(CYGPATH))
    349         endif
    350     endif
    351     ifndef CYGPATH
    352         cygwin-to-host-path = $1
    353     else
    354         ifeq ($(NDK_USE_CYGPATH),1)
    355             $(call ndk_log, Forced usage of 'cygpath -m' through NDK_USE_CYGPATH=1)
    356             cygwin-to-host-path = $(strip $(shell $(CYGPATH) -m $1))
    357         else
    358             # Call an awk script to generate a Makefile fragment used to define a function
    359             WINDOWS_HOST_PATH_FRAGMENT := $(shell mount | $(HOST_AWK) -f $(BUILD_AWK)/gen-windows-host-path.awk)
    360             ifeq ($(NDK_LOG),1)
    361                 $(info Using cygwin substitution rules:)
    362                 $(eval $(shell mount | $(HOST_AWK) -f $(BUILD_AWK)/gen-windows-host-path.awk -vVERBOSE=1))
    363             endif
    364             $(eval cygwin-to-host-path = $(WINDOWS_HOST_PATH_FRAGMENT))
    365         endif
    366     endif
    367 endif # HOST_OS == cygwin
    368 
    369 # The location of the build system files
    370 BUILD_SYSTEM := $(NDK_ROOT)/build/core
    371 
    372 # Include common definitions
    373 include $(BUILD_SYSTEM)/definitions.mk
    374 
    375 # ====================================================================
    376 #
    377 # Read all toolchain-specific configuration files.
    378 #
    379 # Each toolchain must have a corresponding config.mk file located
    380 # in build/toolchains/<name>/ that will be included here.
    381 #
    382 # Each one of these files should define the following variables:
    383 #   TOOLCHAIN_NAME   toolchain name (e.g. arm-linux-androideabi-4.4.3)
    384 #   TOOLCHAIN_ABIS   list of target ABIs supported by the toolchain.
    385 #
    386 # Then, it should include $(ADD_TOOLCHAIN) which will perform
    387 # book-keeping for the build system.
    388 #
    389 # ====================================================================
    390 
    391 # the build script to include in each toolchain config.mk
    392 ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
    393 
    394 # the list of all toolchains in this NDK
    395 NDK_ALL_TOOLCHAINS :=
    396 NDK_ALL_ABIS       :=
    397 NDK_ALL_ARCHS      :=
    398 
    399 TOOLCHAIN_CONFIGS := $(wildcard $(NDK_ROOT)/toolchains/*/config.mk)
    400 $(foreach _config_mk,$(TOOLCHAIN_CONFIGS),\
    401   $(eval include $(BUILD_SYSTEM)/add-toolchain.mk)\
    402 )
    403 
    404 NDK_ALL_TOOLCHAINS   := $(sort $(NDK_ALL_TOOLCHAINS))
    405 NDK_ALL_ABIS         := $(sort $(NDK_ALL_ABIS))
    406 NDK_ALL_ARCHS        := $(sort $(NDK_ALL_ARCHS))
    407 
    408 # Check that each ABI has a single architecture definition
    409 $(foreach _abi,$(strip $(NDK_ALL_ABIS)),\
    410   $(if $(filter-out 1,$(words $(NDK_ABI.$(_abi).arch))),\
    411     $(call __ndk_info,INTERNAL ERROR: The $(_abi) ABI should have exactly one architecture definitions. Found: '$(NDK_ABI.$(_abi).arch)')\
    412     $(call __ndk_error,Aborting...)\
    413   )\
    414 )
    415 
    416 # Allow the user to define NDK_TOOLCHAIN to a custom toolchain name.
    417 # This is normally used when the NDK release comes with several toolchains
    418 # for the same architecture (generally for backwards-compatibility).
    419 #
    420 NDK_TOOLCHAIN := $(strip $(NDK_TOOLCHAIN))
    421 ifdef NDK_TOOLCHAIN
    422     # check that the toolchain name is supported
    423     $(if $(filter-out $(NDK_ALL_TOOLCHAINS),$(NDK_TOOLCHAIN)),\
    424       $(call __ndk_info,NDK_TOOLCHAIN is defined to the unsupported value $(NDK_TOOLCHAIN)) \
    425       $(call __ndk_info,Please use one of the following values: $(NDK_ALL_TOOLCHAINS))\
    426       $(call __ndk_error,Aborting)\
    427     ,)
    428     $(call ndk_log, Using specific toolchain $(NDK_TOOLCHAIN))
    429 endif
    430 
    431 # Allow the user to define NDK_TOOLCHAIN_VERSION to override the toolchain
    432 # version number. Unlike NDK_TOOLCHAIN, this only changes the suffix of
    433 # the toolchain path we're using.
    434 #
    435 # For example, if GCC 4.6 is the default, defining NDK_TOOLCHAIN_VERSION=4.4.3
    436 # will ensure that ndk-build uses the following toolchains, depending on
    437 # the target architecture:
    438 #
    439 #    arm -> arm-linux-androideabi-4.4.3
    440 #    x86 -> x86-android-linux-4.4.3
    441 #    mips -> mipsel-linux-android-4.4.3
    442 #
    443 # This is used in setup-toolchain.mk
    444 #
    445 NDK_TOOLCHAIN_VERSION := $(strip $(NDK_TOOLCHAIN_VERSION))
    446 
    447 
    448 $(call ndk_log, This NDK supports the following target architectures and ABIS:)
    449 $(foreach arch,$(NDK_ALL_ARCHS),\
    450     $(call ndk_log, $(space)$(space)$(arch): $(NDK_ARCH.$(arch).abis))\
    451 )
    452 $(call ndk_log, This NDK supports the following toolchains and target ABIs:)
    453 $(foreach tc,$(NDK_ALL_TOOLCHAINS),\
    454     $(call ndk_log, $(space)$(space)$(tc):  $(NDK_TOOLCHAIN.$(tc).abis))\
    455 )
    456 
    457 # ====================================================================
    458 #
    459 # Read all platform-specific configuration files.
    460 #
    461 # Each platform must be located in build/platforms/android-<apilevel>
    462 # where <apilevel> corresponds to an API level number, with:
    463 #   3 -> Android 1.5
    464 #   4 -> next platform release
    465 #
    466 # ====================================================================
    467 
    468 # The platform files were moved in the Android source tree from
    469 # $TOP/ndk/build/platforms to $TOP/development/ndk/platforms. However,
    470 # the official NDK release packages still place them under the old
    471 # location for now, so deal with this here
    472 #
    473 NDK_PLATFORMS_ROOT := $(strip $(NDK_PLATFORMS_ROOT))
    474 ifndef NDK_PLATFORMS_ROOT
    475     NDK_PLATFORMS_ROOT := $(strip $(wildcard $(NDK_ROOT)/platforms))
    476     ifndef NDK_PLATFORMS_ROOT
    477         NDK_PLATFORMS_ROOT := $(strip $(wildcard $(NDK_ROOT)/build/platforms))
    478     endif
    479 
    480     ifndef NDK_PLATFORMS_ROOT
    481         $(call __ndk_info,Could not find platform files (headers and libraries))
    482         $(if $(strip $(wildcard $(NDK_ROOT)/RELEASE.TXT)),\
    483             $(call __ndk_info,Please define NDK_PLATFORMS_ROOT to point to a valid directory.)\
    484         ,\
    485             $(call __ndk_info,Please run build/tools/build-platforms.sh to build the corresponding directory.)\
    486         )
    487         $(call __ndk_error,Aborting)
    488     endif
    489 
    490     $(call ndk_log,Found platform root directory: $(NDK_PLATFORMS_ROOT))
    491 endif
    492 ifeq ($(strip $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)),)
    493     $(call __ndk_info,Your NDK_PLATFORMS_ROOT points to an invalid directory)
    494     $(call __ndk_info,Current value: $(NDK_PLATFORMS_ROOT))
    495     $(call __ndk_error,Aborting)
    496 endif
    497 
    498 NDK_ALL_PLATFORMS := $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)))
    499 $(call ndk_log,Found supported platforms: $(NDK_ALL_PLATFORMS))
    500 
    501 $(foreach _platform,$(NDK_ALL_PLATFORMS),\
    502   $(eval include $(BUILD_SYSTEM)/add-platform.mk)\
    503 )
    504 
    505 # we're going to find the maximum platform number of the form android-<number>
    506 # ignore others, which could correspond to special and experimental cases
    507 NDK_ALL_PLATFORM_LEVELS := $(filter android-%,$(NDK_ALL_PLATFORMS))
    508 NDK_ALL_PLATFORM_LEVELS := $(patsubst android-%,%,$(NDK_ALL_PLATFORM_LEVELS))
    509 $(call ndk_log,Found stable platform levels: $(NDK_ALL_PLATFORM_LEVELS))
    510 
    511 NDK_MAX_PLATFORM_LEVEL := 3
    512 $(foreach level,$(NDK_ALL_PLATFORM_LEVELS),\
    513   $(eval NDK_MAX_PLATFORM_LEVEL := $$(call max,$$(NDK_MAX_PLATFORM_LEVEL),$$(level)))\
    514 )
    515 $(call ndk_log,Found max platform level: $(NDK_MAX_PLATFORM_LEVEL))
    516 
    517