1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage cc 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "path/filepath" 19*333d2b36SAndroid Build Coastguard Worker 20*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 23*333d2b36SAndroid Build Coastguard Worker) 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Workervar ( 26*333d2b36SAndroid Build Coastguard Worker preprocessNdkHeader = pctx.AndroidStaticRule("preprocessNdkHeader", 27*333d2b36SAndroid Build Coastguard Worker blueprint.RuleParams{ 28*333d2b36SAndroid Build Coastguard Worker Command: "$preprocessor -o $out $in", 29*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"$preprocessor"}, 30*333d2b36SAndroid Build Coastguard Worker }, 31*333d2b36SAndroid Build Coastguard Worker "preprocessor") 32*333d2b36SAndroid Build Coastguard Worker) 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Worker// Returns the NDK base include path for use with sdk_version current. Usable with -I. 35*333d2b36SAndroid Build Coastguard Workerfunc getCurrentIncludePath(ctx android.PathContext) android.OutputPath { 36*333d2b36SAndroid Build Coastguard Worker return getNdkSysrootBase(ctx).Join(ctx, "usr/include") 37*333d2b36SAndroid Build Coastguard Worker} 38*333d2b36SAndroid Build Coastguard Worker 39*333d2b36SAndroid Build Coastguard Workertype headerProperties struct { 40*333d2b36SAndroid Build Coastguard Worker // Base directory of the headers being installed. As an example: 41*333d2b36SAndroid Build Coastguard Worker // 42*333d2b36SAndroid Build Coastguard Worker // ndk_headers { 43*333d2b36SAndroid Build Coastguard Worker // name: "foo", 44*333d2b36SAndroid Build Coastguard Worker // from: "include", 45*333d2b36SAndroid Build Coastguard Worker // to: "", 46*333d2b36SAndroid Build Coastguard Worker // srcs: ["include/foo/bar/baz.h"], 47*333d2b36SAndroid Build Coastguard Worker // } 48*333d2b36SAndroid Build Coastguard Worker // 49*333d2b36SAndroid Build Coastguard Worker // Will install $SYSROOT/usr/include/foo/bar/baz.h. If `from` were instead 50*333d2b36SAndroid Build Coastguard Worker // "include/foo", it would have installed $SYSROOT/usr/include/bar/baz.h. 51*333d2b36SAndroid Build Coastguard Worker From *string 52*333d2b36SAndroid Build Coastguard Worker 53*333d2b36SAndroid Build Coastguard Worker // Install path within the sysroot. This is relative to usr/include. 54*333d2b36SAndroid Build Coastguard Worker To *string 55*333d2b36SAndroid Build Coastguard Worker 56*333d2b36SAndroid Build Coastguard Worker // List of headers to install. Glob compatible. Common case is "include/**/*.h". 57*333d2b36SAndroid Build Coastguard Worker Srcs []string `android:"path"` 58*333d2b36SAndroid Build Coastguard Worker 59*333d2b36SAndroid Build Coastguard Worker // Source paths that should be excluded from the srcs glob. 60*333d2b36SAndroid Build Coastguard Worker Exclude_srcs []string `android:"path"` 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Worker // Path to the NOTICE file associated with the headers. 63*333d2b36SAndroid Build Coastguard Worker License *string `android:"path"` 64*333d2b36SAndroid Build Coastguard Worker 65*333d2b36SAndroid Build Coastguard Worker // Set to true if the headers installed by this module should skip 66*333d2b36SAndroid Build Coastguard Worker // verification. This step ensures that each header is self-contained (can 67*333d2b36SAndroid Build Coastguard Worker // be #included alone) and is valid C. This should not be disabled except in 68*333d2b36SAndroid Build Coastguard Worker // rare cases. Outside bionic and external, if you're using this option 69*333d2b36SAndroid Build Coastguard Worker // you've probably made a mistake. 70*333d2b36SAndroid Build Coastguard Worker Skip_verification *bool 71*333d2b36SAndroid Build Coastguard Worker} 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Workertype headerModule struct { 74*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Worker properties headerProperties 77*333d2b36SAndroid Build Coastguard Worker 78*333d2b36SAndroid Build Coastguard Worker srcPaths android.Paths 79*333d2b36SAndroid Build Coastguard Worker installPaths android.Paths 80*333d2b36SAndroid Build Coastguard Worker licensePath android.Path 81*333d2b36SAndroid Build Coastguard Worker} 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard Workerfunc getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string, 84*333d2b36SAndroid Build Coastguard Worker to string) android.OutputPath { 85*333d2b36SAndroid Build Coastguard Worker // Output path is the sysroot base + "usr/include" + to directory + directory component 86*333d2b36SAndroid Build Coastguard Worker // of the file without the leading from directory stripped. 87*333d2b36SAndroid Build Coastguard Worker // 88*333d2b36SAndroid Build Coastguard Worker // Given: 89*333d2b36SAndroid Build Coastguard Worker // sysroot base = "ndk/sysroot" 90*333d2b36SAndroid Build Coastguard Worker // from = "include/foo" 91*333d2b36SAndroid Build Coastguard Worker // to = "bar" 92*333d2b36SAndroid Build Coastguard Worker // header = "include/foo/woodly/doodly.h" 93*333d2b36SAndroid Build Coastguard Worker // output path = "ndk/sysroot/usr/include/bar/woodly/doodly.h" 94*333d2b36SAndroid Build Coastguard Worker 95*333d2b36SAndroid Build Coastguard Worker // full/platform/path/to/include/foo 96*333d2b36SAndroid Build Coastguard Worker fullFromPath := android.PathForModuleSrc(ctx, from) 97*333d2b36SAndroid Build Coastguard Worker 98*333d2b36SAndroid Build Coastguard Worker // full/platform/path/to/include/foo/woodly 99*333d2b36SAndroid Build Coastguard Worker headerDir := filepath.Dir(header.String()) 100*333d2b36SAndroid Build Coastguard Worker 101*333d2b36SAndroid Build Coastguard Worker // woodly 102*333d2b36SAndroid Build Coastguard Worker strippedHeaderDir, err := filepath.Rel(fullFromPath.String(), headerDir) 103*333d2b36SAndroid Build Coastguard Worker if err != nil { 104*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s", headerDir, 105*333d2b36SAndroid Build Coastguard Worker fullFromPath.String(), err) 106*333d2b36SAndroid Build Coastguard Worker } 107*333d2b36SAndroid Build Coastguard Worker 108*333d2b36SAndroid Build Coastguard Worker // full/platform/path/to/sysroot/usr/include/bar/woodly 109*333d2b36SAndroid Build Coastguard Worker installDir := getCurrentIncludePath(ctx).Join(ctx, to, strippedHeaderDir) 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Worker // full/platform/path/to/sysroot/usr/include/bar/woodly/doodly.h 112*333d2b36SAndroid Build Coastguard Worker return installDir 113*333d2b36SAndroid Build Coastguard Worker} 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Workerfunc (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 116*333d2b36SAndroid Build Coastguard Worker if String(m.properties.License) == "" { 117*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("license", "field is required") 118*333d2b36SAndroid Build Coastguard Worker } 119*333d2b36SAndroid Build Coastguard Worker 120*333d2b36SAndroid Build Coastguard Worker m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License)) 121*333d2b36SAndroid Build Coastguard Worker 122*333d2b36SAndroid Build Coastguard Worker m.srcPaths = android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs) 123*333d2b36SAndroid Build Coastguard Worker for _, header := range m.srcPaths { 124*333d2b36SAndroid Build Coastguard Worker installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), 125*333d2b36SAndroid Build Coastguard Worker String(m.properties.To)) 126*333d2b36SAndroid Build Coastguard Worker installPath := installDir.Join(ctx, header.Base()) 127*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 128*333d2b36SAndroid Build Coastguard Worker Rule: android.Cp, 129*333d2b36SAndroid Build Coastguard Worker Input: header, 130*333d2b36SAndroid Build Coastguard Worker Output: installPath, 131*333d2b36SAndroid Build Coastguard Worker }) 132*333d2b36SAndroid Build Coastguard Worker m.installPaths = append(m.installPaths, installPath) 133*333d2b36SAndroid Build Coastguard Worker } 134*333d2b36SAndroid Build Coastguard Worker 135*333d2b36SAndroid Build Coastguard Worker if len(m.installPaths) == 0 { 136*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("srcs %q matched zero files", m.properties.Srcs) 137*333d2b36SAndroid Build Coastguard Worker } 138*333d2b36SAndroid Build Coastguard Worker} 139*333d2b36SAndroid Build Coastguard Worker 140*333d2b36SAndroid Build Coastguard Worker// ndk_headers installs the sets of ndk headers defined in the srcs property 141*333d2b36SAndroid Build Coastguard Worker// to the sysroot base + "usr/include" + to directory + directory component. 142*333d2b36SAndroid Build Coastguard Worker// ndk_headers requires the license file to be specified. Example: 143*333d2b36SAndroid Build Coastguard Worker// 144*333d2b36SAndroid Build Coastguard Worker// Given: 145*333d2b36SAndroid Build Coastguard Worker// sysroot base = "ndk/sysroot" 146*333d2b36SAndroid Build Coastguard Worker// from = "include/foo" 147*333d2b36SAndroid Build Coastguard Worker// to = "bar" 148*333d2b36SAndroid Build Coastguard Worker// header = "include/foo/woodly/doodly.h" 149*333d2b36SAndroid Build Coastguard Worker// output path = "ndk/sysroot/usr/include/bar/woodly/doodly.h" 150*333d2b36SAndroid Build Coastguard Workerfunc NdkHeadersFactory() android.Module { 151*333d2b36SAndroid Build Coastguard Worker module := &headerModule{} 152*333d2b36SAndroid Build Coastguard Worker module.AddProperties(&module.properties) 153*333d2b36SAndroid Build Coastguard Worker android.InitAndroidModule(module) 154*333d2b36SAndroid Build Coastguard Worker return module 155*333d2b36SAndroid Build Coastguard Worker} 156*333d2b36SAndroid Build Coastguard Worker 157*333d2b36SAndroid Build Coastguard Worker// preprocessed_ndk_header { 158*333d2b36SAndroid Build Coastguard Worker// 159*333d2b36SAndroid Build Coastguard Worker// name: "foo", 160*333d2b36SAndroid Build Coastguard Worker// preprocessor: "foo.sh", 161*333d2b36SAndroid Build Coastguard Worker// srcs: [...], 162*333d2b36SAndroid Build Coastguard Worker// to: "android", 163*333d2b36SAndroid Build Coastguard Worker// 164*333d2b36SAndroid Build Coastguard Worker// } 165*333d2b36SAndroid Build Coastguard Worker// 166*333d2b36SAndroid Build Coastguard Worker// Will invoke the preprocessor as: 167*333d2b36SAndroid Build Coastguard Worker// 168*333d2b36SAndroid Build Coastguard Worker// $preprocessor -o $SYSROOT/usr/include/android/needs_preproc.h $src 169*333d2b36SAndroid Build Coastguard Worker// 170*333d2b36SAndroid Build Coastguard Worker// For each src in srcs. 171*333d2b36SAndroid Build Coastguard Workertype preprocessedHeadersProperties struct { 172*333d2b36SAndroid Build Coastguard Worker // The preprocessor to run. Must be a program inside the source directory 173*333d2b36SAndroid Build Coastguard Worker // with no dependencies. 174*333d2b36SAndroid Build Coastguard Worker Preprocessor *string 175*333d2b36SAndroid Build Coastguard Worker 176*333d2b36SAndroid Build Coastguard Worker // Source path to the files to be preprocessed. 177*333d2b36SAndroid Build Coastguard Worker Srcs []string 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker // Source paths that should be excluded from the srcs glob. 180*333d2b36SAndroid Build Coastguard Worker Exclude_srcs []string 181*333d2b36SAndroid Build Coastguard Worker 182*333d2b36SAndroid Build Coastguard Worker // Install path within the sysroot. This is relative to usr/include. 183*333d2b36SAndroid Build Coastguard Worker To *string 184*333d2b36SAndroid Build Coastguard Worker 185*333d2b36SAndroid Build Coastguard Worker // Path to the NOTICE file associated with the headers. 186*333d2b36SAndroid Build Coastguard Worker License *string 187*333d2b36SAndroid Build Coastguard Worker 188*333d2b36SAndroid Build Coastguard Worker // Set to true if the headers installed by this module should skip 189*333d2b36SAndroid Build Coastguard Worker // verification. This step ensures that each header is self-contained (can 190*333d2b36SAndroid Build Coastguard Worker // be #included alone) and is valid C. This should not be disabled except in 191*333d2b36SAndroid Build Coastguard Worker // rare cases. Outside bionic and external, if you're using this option 192*333d2b36SAndroid Build Coastguard Worker // you've probably made a mistake. 193*333d2b36SAndroid Build Coastguard Worker Skip_verification *bool 194*333d2b36SAndroid Build Coastguard Worker} 195*333d2b36SAndroid Build Coastguard Worker 196*333d2b36SAndroid Build Coastguard Workertype preprocessedHeadersModule struct { 197*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 198*333d2b36SAndroid Build Coastguard Worker 199*333d2b36SAndroid Build Coastguard Worker properties preprocessedHeadersProperties 200*333d2b36SAndroid Build Coastguard Worker 201*333d2b36SAndroid Build Coastguard Worker srcPaths android.Paths 202*333d2b36SAndroid Build Coastguard Worker installPaths android.Paths 203*333d2b36SAndroid Build Coastguard Worker licensePath android.Path 204*333d2b36SAndroid Build Coastguard Worker} 205*333d2b36SAndroid Build Coastguard Worker 206*333d2b36SAndroid Build Coastguard Workerfunc (m *preprocessedHeadersModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 207*333d2b36SAndroid Build Coastguard Worker if String(m.properties.License) == "" { 208*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("license", "field is required") 209*333d2b36SAndroid Build Coastguard Worker } 210*333d2b36SAndroid Build Coastguard Worker 211*333d2b36SAndroid Build Coastguard Worker preprocessor := android.PathForModuleSrc(ctx, String(m.properties.Preprocessor)) 212*333d2b36SAndroid Build Coastguard Worker m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License)) 213*333d2b36SAndroid Build Coastguard Worker 214*333d2b36SAndroid Build Coastguard Worker m.srcPaths = android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs) 215*333d2b36SAndroid Build Coastguard Worker installDir := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To)) 216*333d2b36SAndroid Build Coastguard Worker for _, src := range m.srcPaths { 217*333d2b36SAndroid Build Coastguard Worker installPath := installDir.Join(ctx, src.Base()) 218*333d2b36SAndroid Build Coastguard Worker m.installPaths = append(m.installPaths, installPath) 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 221*333d2b36SAndroid Build Coastguard Worker Rule: preprocessNdkHeader, 222*333d2b36SAndroid Build Coastguard Worker Description: "preprocess " + src.Rel(), 223*333d2b36SAndroid Build Coastguard Worker Input: src, 224*333d2b36SAndroid Build Coastguard Worker Output: installPath, 225*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 226*333d2b36SAndroid Build Coastguard Worker "preprocessor": preprocessor.String(), 227*333d2b36SAndroid Build Coastguard Worker }, 228*333d2b36SAndroid Build Coastguard Worker }) 229*333d2b36SAndroid Build Coastguard Worker } 230*333d2b36SAndroid Build Coastguard Worker 231*333d2b36SAndroid Build Coastguard Worker if len(m.installPaths) == 0 { 232*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("srcs %q matched zero files", m.properties.Srcs) 233*333d2b36SAndroid Build Coastguard Worker } 234*333d2b36SAndroid Build Coastguard Worker} 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker// preprocessed_ndk_headers preprocesses all the ndk headers listed in the srcs 237*333d2b36SAndroid Build Coastguard Worker// property by executing the command defined in the preprocessor property. 238*333d2b36SAndroid Build Coastguard Workerfunc preprocessedNdkHeadersFactory() android.Module { 239*333d2b36SAndroid Build Coastguard Worker module := &preprocessedHeadersModule{} 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Worker module.AddProperties(&module.properties) 242*333d2b36SAndroid Build Coastguard Worker 243*333d2b36SAndroid Build Coastguard Worker android.InitAndroidModule(module) 244*333d2b36SAndroid Build Coastguard Worker 245*333d2b36SAndroid Build Coastguard Worker return module 246*333d2b36SAndroid Build Coastguard Worker} 247