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