Home | History | Annotate | Download | only in cc
      1 // Copyright 2015 Google Inc. All rights reserved.
      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 package cc
     16 
     17 import (
     18 	"fmt"
     19 	"io"
     20 	"path/filepath"
     21 	"strings"
     22 
     23 	"android/soong/android"
     24 )
     25 
     26 var (
     27 	vendorSuffix = ".vendor"
     28 )
     29 
     30 type AndroidMkContext interface {
     31 	Target() android.Target
     32 	subAndroidMk(*android.AndroidMkData, interface{})
     33 	useVndk() bool
     34 }
     35 
     36 type subAndroidMkProvider interface {
     37 	AndroidMk(AndroidMkContext, *android.AndroidMkData)
     38 }
     39 
     40 func (c *Module) subAndroidMk(data *android.AndroidMkData, obj interface{}) {
     41 	if c.subAndroidMkOnce == nil {
     42 		c.subAndroidMkOnce = make(map[subAndroidMkProvider]bool)
     43 	}
     44 	if androidmk, ok := obj.(subAndroidMkProvider); ok {
     45 		if !c.subAndroidMkOnce[androidmk] {
     46 			c.subAndroidMkOnce[androidmk] = true
     47 			androidmk.AndroidMk(c, data)
     48 		}
     49 	}
     50 }
     51 
     52 func (c *Module) AndroidMk() android.AndroidMkData {
     53 	if c.Properties.HideFromMake {
     54 		return android.AndroidMkData{
     55 			Disabled: true,
     56 		}
     57 	}
     58 
     59 	ret := android.AndroidMkData{
     60 		OutputFile: c.outputFile,
     61 		Extra: []android.AndroidMkExtraFunc{
     62 			func(w io.Writer, outputFile android.Path) {
     63 				if len(c.Properties.Logtags) > 0 {
     64 					fmt.Fprintln(w, "LOCAL_LOGTAGS_FILES :=", strings.Join(c.Properties.Logtags, " "))
     65 				}
     66 				fmt.Fprintln(w, "LOCAL_SANITIZE := never")
     67 				if len(c.Properties.AndroidMkSharedLibs) > 0 {
     68 					fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
     69 				}
     70 				if c.Target().Os == android.Android &&
     71 					String(c.Properties.Sdk_version) != "" && !c.useVndk() {
     72 					fmt.Fprintln(w, "LOCAL_SDK_VERSION := "+String(c.Properties.Sdk_version))
     73 					fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
     74 				} else {
     75 					// These are already included in LOCAL_SHARED_LIBRARIES
     76 					fmt.Fprintln(w, "LOCAL_CXX_STL := none")
     77 				}
     78 				if c.useVndk() {
     79 					fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
     80 				}
     81 			},
     82 		},
     83 	}
     84 
     85 	for _, feature := range c.features {
     86 		c.subAndroidMk(&ret, feature)
     87 	}
     88 
     89 	c.subAndroidMk(&ret, c.compiler)
     90 	c.subAndroidMk(&ret, c.linker)
     91 	if c.sanitize != nil {
     92 		c.subAndroidMk(&ret, c.sanitize)
     93 	}
     94 	c.subAndroidMk(&ret, c.installer)
     95 
     96 	if c.useVndk() && c.hasVendorVariant() {
     97 		// .vendor suffix is added only when we will have two variants: core and vendor.
     98 		// The suffix is not added for vendor-only module.
     99 		ret.SubName += vendorSuffix
    100 	}
    101 
    102 	return ret
    103 }
    104 
    105 func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, ret *android.AndroidMkData) {
    106 	var testFiles []string
    107 	for _, d := range data {
    108 		rel := d.Rel()
    109 		path := d.String()
    110 		if !strings.HasSuffix(path, rel) {
    111 			panic(fmt.Errorf("path %q does not end with %q", path, rel))
    112 		}
    113 		path = strings.TrimSuffix(path, rel)
    114 		testFiles = append(testFiles, path+":"+rel)
    115 	}
    116 	if len(testFiles) > 0 {
    117 		ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    118 			fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " "))
    119 		})
    120 	}
    121 }
    122 
    123 func (library *libraryDecorator) androidMkWriteExportedFlags(w io.Writer) {
    124 	exportedFlags := library.exportedFlags()
    125 	if len(exportedFlags) > 0 {
    126 		fmt.Fprintln(w, "LOCAL_EXPORT_CFLAGS :=", strings.Join(exportedFlags, " "))
    127 	}
    128 	exportedFlagsDeps := library.exportedFlagsDeps()
    129 	if len(exportedFlagsDeps) > 0 {
    130 		fmt.Fprintln(w, "LOCAL_EXPORT_C_INCLUDE_DEPS :=", strings.Join(exportedFlagsDeps.Strings(), " "))
    131 	}
    132 }
    133 
    134 func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    135 	if library.static() {
    136 		ret.Class = "STATIC_LIBRARIES"
    137 	} else if library.shared() {
    138 		ctx.subAndroidMk(ret, &library.stripper)
    139 		ctx.subAndroidMk(ret, &library.relocationPacker)
    140 
    141 		ret.Class = "SHARED_LIBRARIES"
    142 	} else if library.header() {
    143 		ret.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
    144 			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
    145 			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
    146 			fmt.Fprintln(w, "LOCAL_MODULE :=", name+data.SubName)
    147 
    148 			archStr := ctx.Target().Arch.ArchType.String()
    149 			var host bool
    150 			switch ctx.Target().Os.Class {
    151 			case android.Host:
    152 				fmt.Fprintln(w, "LOCAL_MODULE_HOST_ARCH := ", archStr)
    153 				host = true
    154 			case android.HostCross:
    155 				fmt.Fprintln(w, "LOCAL_MODULE_HOST_CROSS_ARCH := ", archStr)
    156 				host = true
    157 			case android.Device:
    158 				fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH := ", archStr)
    159 			}
    160 
    161 			if host {
    162 				makeOs := ctx.Target().Os.String()
    163 				if ctx.Target().Os == android.Linux || ctx.Target().Os == android.LinuxBionic {
    164 					makeOs = "linux"
    165 				}
    166 				fmt.Fprintln(w, "LOCAL_MODULE_HOST_OS :=", makeOs)
    167 				fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
    168 			} else if ctx.useVndk() {
    169 				fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
    170 			}
    171 
    172 			library.androidMkWriteExportedFlags(w)
    173 			fmt.Fprintln(w, "include $(BUILD_HEADER_LIBRARY)")
    174 		}
    175 
    176 		return
    177 	}
    178 
    179 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    180 		library.androidMkWriteExportedFlags(w)
    181 		fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := ")
    182 		if library.sAbiOutputFile.Valid() {
    183 			fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES += ", library.sAbiOutputFile.String())
    184 			if library.sAbiDiff.Valid() && !library.static() {
    185 				fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES += ", library.sAbiDiff.String())
    186 				fmt.Fprintln(w, "HEADER_ABI_DIFFS += ", library.sAbiDiff.String())
    187 			}
    188 		}
    189 
    190 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext())
    191 
    192 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    193 
    194 		if library.coverageOutputFile.Valid() {
    195 			fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", library.coverageOutputFile.String())
    196 		}
    197 	})
    198 
    199 	if library.shared() {
    200 		ctx.subAndroidMk(ret, library.baseInstaller)
    201 	}
    202 }
    203 
    204 func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    205 	ret.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
    206 		out := ret.OutputFile.Path()
    207 
    208 		fmt.Fprintln(w, "\n$("+prefix+"OUT_INTERMEDIATE_LIBRARIES)/"+name+data.SubName+objectExtension+":", out.String())
    209 		fmt.Fprintln(w, "\t$(copy-file-to-target)")
    210 	}
    211 }
    212 
    213 func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    214 	ctx.subAndroidMk(ret, binary.baseInstaller)
    215 	ctx.subAndroidMk(ret, &binary.stripper)
    216 
    217 	ret.Class = "EXECUTABLES"
    218 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    219 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    220 		if Bool(binary.Properties.Static_executable) {
    221 			fmt.Fprintln(w, "LOCAL_FORCE_STATIC_EXECUTABLE := true")
    222 		}
    223 
    224 		if len(binary.symlinks) > 0 {
    225 			fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(binary.symlinks, " "))
    226 		}
    227 
    228 		if binary.coverageOutputFile.Valid() {
    229 			fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", binary.coverageOutputFile.String())
    230 		}
    231 
    232 		if len(binary.Properties.Overrides) > 0 {
    233 			fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(binary.Properties.Overrides, " "))
    234 		}
    235 	})
    236 }
    237 
    238 func (benchmark *benchmarkDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    239 	ctx.subAndroidMk(ret, benchmark.binaryDecorator)
    240 	ret.Class = "NATIVE_TESTS"
    241 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    242 		if len(benchmark.Properties.Test_suites) > 0 {
    243 			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
    244 				strings.Join(benchmark.Properties.Test_suites, " "))
    245 		}
    246 	})
    247 
    248 	androidMkWriteTestData(benchmark.data, ctx, ret)
    249 }
    250 
    251 func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    252 	ctx.subAndroidMk(ret, test.binaryDecorator)
    253 	ret.Class = "NATIVE_TESTS"
    254 	if Bool(test.Properties.Test_per_src) {
    255 		ret.SubName = "_" + String(test.binaryDecorator.Properties.Stem)
    256 	}
    257 
    258 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    259 		if len(test.Properties.Test_suites) > 0 {
    260 			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
    261 				strings.Join(test.Properties.Test_suites, " "))
    262 		}
    263 	})
    264 
    265 	androidMkWriteTestData(test.data, ctx, ret)
    266 }
    267 
    268 func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    269 	ctx.subAndroidMk(ret, test.libraryDecorator)
    270 }
    271 
    272 func (library *toolchainLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    273 	ret.Class = "STATIC_LIBRARIES"
    274 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    275 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())
    276 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    277 	})
    278 }
    279 
    280 func (stripper *stripper) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    281 	// Make only supports stripping target modules
    282 	if ctx.Target().Os != android.Android {
    283 		return
    284 	}
    285 
    286 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    287 		if Bool(stripper.StripProperties.Strip.None) {
    288 
    289 			fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
    290 		} else if Bool(stripper.StripProperties.Strip.Keep_symbols) {
    291 			fmt.Fprintln(w, "LOCAL_STRIP_MODULE := keep_symbols")
    292 		} else {
    293 			fmt.Fprintln(w, "LOCAL_STRIP_MODULE := mini-debug-info")
    294 		}
    295 	})
    296 }
    297 
    298 func (packer *relocationPacker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    299 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    300 		if packer.Properties.PackingRelocations {
    301 			fmt.Fprintln(w, "LOCAL_PACK_MODULE_RELOCATIONS := true")
    302 		}
    303 	})
    304 }
    305 
    306 func (installer *baseInstaller) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    307 	// Soong installation is only supported for host modules. Have Make
    308 	// installation trigger Soong installation.
    309 	if ctx.Target().Os.Class == android.Host {
    310 		ret.OutputFile = android.OptionalPathForPath(installer.path)
    311 	}
    312 
    313 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    314 		path := installer.path.RelPathString()
    315 		dir, file := filepath.Split(path)
    316 		stem := strings.TrimSuffix(file, filepath.Ext(file))
    317 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file))
    318 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
    319 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
    320 	})
    321 }
    322 
    323 func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    324 	ret.SubName = ndkLibrarySuffix + "." + c.properties.ApiLevel
    325 	ret.Class = "SHARED_LIBRARIES"
    326 
    327 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    328 		path, file := filepath.Split(c.installPath.String())
    329 		stem := strings.TrimSuffix(file, filepath.Ext(file))
    330 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    331 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())
    332 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
    333 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
    334 		fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
    335 
    336 		// Prevent make from installing the libraries to obj/lib (since we have
    337 		// dozens of libraries with the same name, they'll clobber each other
    338 		// and the real versions of the libraries from the platform).
    339 		fmt.Fprintln(w, "LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES := false")
    340 	})
    341 }
    342 
    343 func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    344 	ret.Class = "SHARED_LIBRARIES"
    345 	ret.SubName = ".vendor"
    346 
    347 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    348 		c.libraryDecorator.androidMkWriteExportedFlags(w)
    349 
    350 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext())
    351 		fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
    352 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    353 		fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
    354 		fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
    355 		fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
    356 	})
    357 }
    358 
    359 func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    360 	ret.Class = "SHARED_LIBRARIES"
    361 
    362 	ret.SubName = c.NameSuffix()
    363 
    364 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    365 		c.libraryDecorator.androidMkWriteExportedFlags(w)
    366 
    367 		path := c.path.RelPathString()
    368 		dir, file := filepath.Split(path)
    369 		stem := strings.TrimSuffix(file, filepath.Ext(file))
    370 		fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
    371 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    372 		fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
    373 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext())
    374 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file))
    375 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
    376 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
    377 	})
    378 }
    379 
    380 func (c *ndkPrebuiltStlLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    381 	ret.Class = "SHARED_LIBRARIES"
    382 
    383 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    384 		// Prevent make from installing the libraries to obj/lib (since we have
    385 		// dozens of libraries with the same name, they'll clobber each other
    386 		// and the real versions of the libraries from the platform).
    387 		fmt.Fprintln(w, "LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES := false")
    388 	})
    389 }
    390 
    391 func (c *vendorPublicLibraryStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
    392 	ret.Class = "SHARED_LIBRARIES"
    393 	ret.SubName = vendorPublicLibrarySuffix
    394 
    395 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
    396 		c.libraryDecorator.androidMkWriteExportedFlags(w)
    397 
    398 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+outputFile.Ext())
    399 		fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
    400 		fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
    401 		fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
    402 		fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
    403 	})
    404 }
    405