aboutsummaryrefslogtreecommitdiff
path: root/build/core/main.mk
blob: 92c2ea2beb2be46521902fe5a0f74e940585931c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# ====================================================================
#
# Define a few useful variables and functions.
# More stuff will follow in definitions.mk.
#
# ====================================================================

# Used to output warnings and error from the library, it's possible to
# disable any warnings or errors by overriding these definitions
# manually or by setting NDK_NO_WARNINGS or NDK_NO_ERRORS

__ndk_name    := Android NDK
__ndk_info     = $(info $(__ndk_name): $1 $2 $3 $4 $5)
__ndk_warning  = $(warning $(__ndk_name): $1 $2 $3 $4 $5)
__ndk_error    = $(error $(__ndk_name): $1 $2 $3 $4 $5)

ifdef NDK_NO_WARNINGS
__ndk_warning :=
endif
ifdef NDK_NO_ERRORS
__ndk_error :=
endif

# -----------------------------------------------------------------------------
# Function : ndk_log
# Arguments: 1: text to print when NDK_LOG is defined
# Returns  : None
# Usage    : $(call ndk_log,<some text>)
# -----------------------------------------------------------------------------
ifdef NDK_LOG
ndk_log = $(info $(__ndk_name): $1)
else
ndk_log :=
endif

# ====================================================================
#
# Define the main configuration variables, and read the host-specific
# configuration file that is normally generated by build/host-setup.sh
#
# ====================================================================

# Detect the NDK installation path by processing this Makefile's location.
# This assumes we are located under $NDK_ROOT/build/core/main.mk
#
NDK_ROOT := $(lastword $(MAKEFILE_LIST))
NDK_ROOT := $(strip $(NDK_ROOT:%build/core/main.mk=%))
ifeq ($(NDK_ROOT),)
    # for the case when we're invoked from the NDK install path
    NDK_ROOT := .
else
    # get rid of trailing slash
    NDK_ROOT := $(NDK_ROOT:%/=%)
endif
$(call ndk_log,NDK installation path auto-detected: '$(NDK_ROOT)')

# The location of the build system files
BUILD_SYSTEM := $(NDK_ROOT)/build/core

# Include common definitions
include $(BUILD_SYSTEM)/definitions.mk

# Where all generated files will be stored during a build
NDK_OUT := $(NDK_ROOT)/out

HOST_PREBUILT_TAG := $(HOST_TAG)

# Location where all prebuilt binaries for a given host architectures
# will be stored.
HOST_PREBUILT := $(NDK_ROOT)/build/prebuilt/$(HOST_TAG)

# Where all app-specific generated files will be stored
NDK_APP_OUT := $(NDK_OUT)/apps

# Where all host-specific generated files will be stored
NDK_HOST_OUT := $(NDK_OUT)/host/$(HOST_TAG)

# ====================================================================
#
# Read all toolchain-specific configuration files.
#
# Each toolchain must have a corresponding config.mk file located
# in build/toolchains/<name>/ that will be included here.
#
# Each one of these files should define the following variables:
#   TOOLCHAIN_NAME   toolchain name (e.g. arm-eabi-4.2.1)
#   TOOLCHAIN_ABIS   list of target ABIs supported by the toolchain.
#
# Then, it should include $(ADD_TOOLCHAIN) which will perform
# book-keeping for the build system.
#
# ====================================================================

# the build script to include in each toolchain config.mk
ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk

# the list of all toolchains in this NDK
NDK_ALL_TOOLCHAINS :=
NDK_ALL_ABIS       :=

TOOLCHAIN_CONFIGS := $(wildcard $(NDK_ROOT)/build/toolchains/*/config.mk)
$(foreach _config_mk,$(TOOLCHAIN_CONFIGS),\
  $(eval include $(BUILD_SYSTEM)/add-toolchain.mk)\
)

NDK_ALL_TOOLCHAINS   := $(call uniq,$(NDK_ALL_TOOLCHAINS))
NDK_ALL_ABIS         := $(call uniq,$(NDK_ALL_ABIS))

# The default toolchain is now arm-eabi-4.4.0, however its
# C++ compiler is a tad bit more pedantic with certain
# constructs (e.g. templates) so allow users to switch back
# to the old 4.2.1 instead if they really want to.
#
# NOTE: you won't get armeabi-v7a support though !
#
NDK_TOOLCHAIN := $(strip $(NDK_TOOLCHAIN))
ifdef NDK_TOOLCHAIN
    # check that the toolchain name is supported
    $(if $(filter-out $(NDK_ALL_TOOLCHAINS),$(NDK_TOOLCHAIN)),\
      $(call __ndk_info,NDK_TOOLCHAIN is defined to the unsupported value $(NDK_TOOLCHAIN)) \
      $(call __ndk_info,Please use one of the following values: $(NDK_ALL_TOOLCHAINS))\
      $(call __ndk_error,Aborting)\
    ,)
    $(call ndk_log, Using specific toolchain $(NDK_TOOLCHAIN))
endif

$(call ndk_log, This NDK supports the following toolchains and target ABIs:)
$(foreach tc,$(NDK_ALL_TOOLCHAINS),\
    $(call ndk_log, $(space)$(space)$(tc):  $(NDK_TOOLCHAIN.$(tc).abis))\
)

# ====================================================================
#
# Read all platform-specific configuration files.
#
# Each platform must be located in build/platforms/android-<apilevel>
# where <apilevel> corresponds to an API level number, with:
#   3 -> Android 1.5
#   4 -> next platform release
#
# ====================================================================

NDK_PLATFORMS_ROOT := $(NDK_ROOT)/build/platforms
NDK_ALL_PLATFORMS := $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)))
$(call ndk_log,Found supported platforms: $(NDK_ALL_PLATFORMS))

$(foreach _platform,$(NDK_ALL_PLATFORMS),\
  $(eval include $(BUILD_SYSTEM)/add-platform.mk)\
)

# we're going to find the maximum platform number of the form android-<number>
# ignore others, which could correspond to special and experimental cases
NDK_ALL_PLATFORM_LEVELS := $(filter android-%,$(NDK_ALL_PLATFORMS))
NDK_ALL_PLATFORM_LEVELS := $(patsubst android-%,%,$(NDK_ALL_PLATFORM_LEVELS))
$(call ndk_log,Found stable platform levels: $(NDK_ALL_PLATFORM_LEVELS))

NDK_MAX_PLATFORM_LEVEL := 3
$(foreach level,$(NDK_ALL_PLATFORM_LEVELS),\
  $(eval NDK_MAX_PLATFORM_LEVEL := $$(call max,$$(NDK_MAX_PLATFORM_LEVEL),$$(level)))\
)
$(call ndk_log,Found max platform level: $(NDK_MAX_PLATFORM_LEVEL))

# ====================================================================
#
# Read all application configuration files
#
# Each 'application' must have a corresponding Application.mk file
# located in apps/<name> where <name> is a liberal name that doesn't
# contain any space in it, used to uniquely identify the
#
# See docs/ANDROID-MK.TXT for their specification.
#
# ====================================================================

NDK_ALL_APPS :=
NDK_APPS_ROOT := $(NDK_ROOT)/apps

# Get the list of apps listed under apps/*
NDK_APPLICATIONS := $(wildcard $(NDK_APPS_ROOT)/*)
NDK_ALL_APPS     := $(NDK_APPLICATIONS:$(NDK_APPS_ROOT)/%=%)

# Check that APP is not empty
APP := $(strip $(APP))
ifndef APP
  $(call __ndk_info,\
    The APP variable is undefined or empty.)
  $(call __ndk_info,\
    Please define it to one of: $(NDK_ALL_APPS))
  $(call __ndk_info,\
    You can also add new applications by writing an Application.mk file.)
  $(call __ndk_info,\
    See docs/APPLICATION-MK.TXT for details.)
  $(call __ndk_error, Aborting)
endif

# Check that all apps listed in APP do exist
_bad_apps := $(strip $(filter-out $(NDK_ALL_APPS),$(APP)))
ifdef _bad_apps
  $(call __ndk_info,\
    APP variable defined to unknown applications: $(_bad_apps))
  $(call __ndk_info,\
    You might want to use one of the following: $(NDK_ALL_APPS))
  $(call __ndk_error, Aborting)
endif

# Check that all apps listed in APP have an Application.mk

$(foreach _app,$(APP),\
  $(eval _application_mk := $(strip $(wildcard $(NDK_ROOT)/apps/$(_app)/Application.mk))) \
  $(call ndk_log,Parsing $(_application_mk))\
  $(if $(_application_mk),\
    $(eval include $(BUILD_SYSTEM)/add-application.mk)\
  ,\
    $(call __ndk_info,\
      Missing file: apps/$(_app)/Application.mk !)\
    $(call __ndk_error, Aborting)\
  )\
)

# clean up environment, just to be safe
$(call clear-vars, $(NDK_APP_VARS))

ifeq ($(strip $(NDK_ALL_APPS)),)
  $(call __ndk_info,\
    The NDK could not find a proper application description under apps/*/Application.mk)
  $(call __ndk_info,\
    Please follow the instructions in docs/NDK-APPS.TXT to write one.)
  $(call __ndk_error, Aborting)
endif

# now check that APP doesn't contain an unknown app name
# if it does, we ignore them if there is at least one known
# app name in the list. Otherwise, abort with an error message
#
_unknown_apps := $(filter-out $(NDK_ALL_APPS),$(APP))
_known_apps   := $(filter     $(NDK_ALL_APPS),$(APP))

NDK_APPS := $(APP)

$(if $(_unknown_apps),\
  $(if $(_known_apps),\
    $(call __ndk_info,WARNING:\
        Removing unknown names from APP variable: $(_unknown_apps))\
    $(eval NDK_APPS := $(_known_apps))\
   ,\
    $(call __ndk_info,\
        The APP variable contains unknown app names: $(_unknown_apps))\
    $(call __ndk_info,\
        Please use one of: $(NDK_ALL_APPS))\
    $(call __ndk_error, Aborting)\
  )\
)

$(call __ndk_info,Building for application '$(NDK_APPS)')

# ====================================================================
#
# Prepare the build for parsing Android.mk files
#
# ====================================================================

# These phony targets are used to control various stages of the build
.PHONY: all \
        host_libraries host_executables \
        installed_modules \
        executables libraries static_libraries shared_libraries \
        clean clean-config clean-objs-dir \
        clean-executables clean-libraries \
        clean-installed-modules \
        clean-installed-binaries

# These macros are used in Android.mk to include the corresponding
# build script that will parse the LOCAL_XXX variable definitions.
#
CLEAR_VARS                := $(BUILD_SYSTEM)/clear-vars.mk
BUILD_HOST_EXECUTABLE     := $(BUILD_SYSTEM)/build-host-executable.mk
BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-host-static-library.mk
BUILD_STATIC_LIBRARY      := $(BUILD_SYSTEM)/build-static-library.mk
BUILD_SHARED_LIBRARY      := $(BUILD_SYSTEM)/build-shared-library.mk
BUILD_EXECUTABLE          := $(BUILD_SYSTEM)/build-executable.mk

ANDROID_MK_INCLUDED := \
  $(CLEAR_VARS) \
  $(BUILD_HOST_EXECUTABLE) \
  $(BUILD_HOST_STATIC_LIBRARY) \
  $(BUILD_STATIC_LIBRARY) \
  $(BUILD_SHARED_LIBRARY) \
  $(BUILD_EXECUTABLE) \


# this is the list of directories containing dependency information
# generated during the build. It will be updated by build scripts
# when module definitions are parsed.
#
ALL_DEPENDENCY_DIRS :=

# this is the list of all generated files that we would need to clean
ALL_HOST_EXECUTABLES      :=
ALL_HOST_STATIC_LIBRARIES :=
ALL_STATIC_LIBRARIES      :=
ALL_SHARED_LIBRARIES      :=
ALL_EXECUTABLES           :=
ALL_INSTALLED_MODULES     :=

# the first rule
all: installed_modules host_libraries host_executables


$(foreach _app,$(NDK_APPS),\
  $(eval include $(BUILD_SYSTEM)/setup-app.mk)\
)

# ====================================================================
#
# Now finish the build preparation with a few rules that depend on
# what has been effectively parsed and recorded previously
#
# ====================================================================

clean: clean-intermediates clean-installed-modules clean-installed-binaries

distclean: clean clean-config

installed_modules: libraries $(ALL_INSTALLED_MODULES)
host_libraries: $(HOST_STATIC_LIBRARIES)
host_executables: $(HOST_EXECUTABLES)

static_libraries: $(STATIC_LIBRARIES)
shared_libraries: $(SHARED_LIBRARIES)
executables: $(EXECUTABLES)

libraries: static_libraries shared_libraries

clean-host-intermediates:
	$(hide) rm -rf $(HOST_EXECUTABLES) $(HOST_STATIC_LIBRARIES)

clean-intermediates: clean-host-intermediates
	$(hide) rm -rf $(EXECUTABLES) $(STATIC_LIBRARIES) $(SHARED_LIBRARIES)

clean-installed-modules:
	$(hide) rm -rf $(ALL_INSTALLED_MODULES)

clean-config:
	$(hide) rm -f $(CONFIG_MAKE) $(CONFIG_H)

# include dependency information
ALL_DEPENDENCY_DIRS := $(sort $(ALL_DEPENDENCY_DIRS))
-include $(wildcard $(ALL_DEPENDENCY_DIRS:%=%/*.d))