AOSP Foundations
3 min read

CLEAR_VARS and Variable Scope

Learn why variable pollution happens in GNU Make and how AOSP uses CLEAR_VARS to maintain modularity.

One of the most dangerous architectural flaws of GNU Make is that all variables live in a single, global namespace. Because AOSP aggregates thousands of Android.mk files into one massive execution script, managing variable scope is a critical security and stability concern.

The Global Namespace Problem

Imagine you write an Android.mk file to compile a simple C++ app, and you define a custom compiler flag:

LOCAL_PATH := $(call my-dir)
LOCAL_MODULE := my_first_app
LOCAL_SRC_FILES := app1.cpp
LOCAL_CFLAGS := -Werror
include $(BUILD_EXECUTABLE)

The build system parses your file. The global variable LOCAL_CFLAGS is now set to -Werror.

Now, the build system moves on to parse the next Android.mk file in a completely different directory, written by a completely different developer:

LOCAL_PATH := $(call my-dir)
LOCAL_MODULE := my_second_app
LOCAL_SRC_FILES := app2.cpp
include $(BUILD_EXECUTABLE)

Notice that the second developer did not define LOCAL_CFLAGS. However, because Make uses a global namespace, my_second_app will inherit the -Werror flag from my_first_app. This variable pollution causes unpredictable build failures that are incredibly difficult to debug.

The Solution: CLEAR_VARS

To solve this, AOSP mandates the use of a special script called CLEAR_VARS.

Before defining the variables for any module, you must always include this line:

include $(CLEAR_VARS)

CLEAR_VARS is essentially a giant script located in build/make/core/clear_vars.mk. When you include it, the script manually deletes the values of hundreds of known LOCAL_ variables.

The Correct Implementation

By using CLEAR_VARS, you guarantee a clean slate before defining your module:

LOCAL_PATH := $(call my-dir)

# Erase everything from previous files parsed globally
include $(CLEAR_VARS)

LOCAL_MODULE := my_secure_app
LOCAL_SRC_FILES := app.cpp
LOCAL_CFLAGS := -O3

include $(BUILD_EXECUTABLE)

Common Pitfalls

Even senior developers make mistakes with variable scope in AOSP legacy codebases.

  1. Forgetting CLEAR_VARS: This is the most common mistake. If you omit it, your module will inherit flags, source files, and dependencies from whichever Android.mk happened to be parsed immediately before yours.
  2. Using Non-LOCAL Variables: The CLEAR_VARS script only clears variables that begin with LOCAL_ (like LOCAL_SRC_FILES or LOCAL_MODULE). If you define a custom variable in your file (like MY_CUSTOM_FLAG := true), CLEAR_VARS will not touch it. That variable will leak out and pollute the global build space. If you absolutely must use custom variables, you should undefine them manually at the end of your file.
# Example of manually cleaning up a custom variable
MY_CUSTOM_FLAG := true
# ... module definition ...
MY_CUSTOM_FLAG :=