diff --git a/Android.bp b/Android.bp index 2a4653a13..e83b5841a 100644 --- a/Android.bp +++ b/Android.bp @@ -207,6 +207,7 @@ bootstrap_go_package { "cc/binary_sdk_member.go", "cc/fuzz.go", "cc/library.go", + "cc/library_headers.go", "cc/library_sdk_member.go", "cc/object.go", "cc/test.go", @@ -232,6 +233,7 @@ bootstrap_go_package { "cc/compiler_test.go", "cc/gen_test.go", "cc/genrule_test.go", + "cc/library_headers_test.go", "cc/library_test.go", "cc/object_test.go", "cc/prebuilt_test.go", diff --git a/cc/library.go b/cc/library.go index bca9a9680..6ffb7fc1e 100644 --- a/cc/library.go +++ b/cc/library.go @@ -183,7 +183,6 @@ func RegisterLibraryBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_library", LibraryFactory) ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory) ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory) - ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory) } // cc_library creates both static and/or shared libraries for a device and/or @@ -233,16 +232,6 @@ func LibraryHostSharedFactory() android.Module { return module.Init() } -// cc_library_headers contains a set of c/c++ headers which are imported by -// other soong cc modules using the header_libs property. For best practices, -// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for -// Make. -func LibraryHeaderFactory() android.Module { - module, library := NewLibrary(android.HostAndDeviceSupported) - library.HeaderOnly() - return module.Init() -} - type flagExporter struct { Properties FlagExporterProperties @@ -1314,22 +1303,28 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) { if cc_prebuilt { library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface) - // Always create both the static and shared variants for prebuilt libraries, and then disable the one - // that is not being used. This allows them to share the name of a cc_library module, which requires that - // all the variants of the cc_library also exist on the prebuilt. - modules := mctx.CreateLocalVariations("static", "shared") - static := modules[0].(*Module) - shared := modules[1].(*Module) + // Differentiate between header only and building an actual static/shared library + if library.buildStatic() || library.buildShared() { + // Always create both the static and shared variants for prebuilt libraries, and then disable the one + // that is not being used. This allows them to share the name of a cc_library module, which requires that + // all the variants of the cc_library also exist on the prebuilt. + modules := mctx.CreateLocalVariations("static", "shared") + static := modules[0].(*Module) + shared := modules[1].(*Module) - static.linker.(prebuiltLibraryInterface).setStatic() - shared.linker.(prebuiltLibraryInterface).setShared() + static.linker.(prebuiltLibraryInterface).setStatic() + shared.linker.(prebuiltLibraryInterface).setShared() - if !library.buildStatic() { - static.linker.(prebuiltLibraryInterface).disablePrebuilt() - } - if !library.buildShared() { - shared.linker.(prebuiltLibraryInterface).disablePrebuilt() + if !library.buildStatic() { + static.linker.(prebuiltLibraryInterface).disablePrebuilt() + } + if !library.buildShared() { + shared.linker.(prebuiltLibraryInterface).disablePrebuilt() + } + } else { + // Header only } + } else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() { // Non-cc.Modules may need an empty variant for their mutators. diff --git a/cc/library_headers.go b/cc/library_headers.go new file mode 100644 index 000000000..c7edb9a6d --- /dev/null +++ b/cc/library_headers.go @@ -0,0 +1,43 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// 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. + +package cc + +import "android/soong/android" + +func init() { + RegisterLibraryHeadersBuildComponents(android.InitRegistrationContext) +} + +func RegisterLibraryHeadersBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory) + ctx.RegisterModuleType("cc_prebuilt_library_headers", prebuiltLibraryHeaderFactory) +} + +// cc_library_headers contains a set of c/c++ headers which are imported by +// other soong cc modules using the header_libs property. For best practices, +// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for +// Make. +func LibraryHeaderFactory() android.Module { + module, library := NewLibrary(android.HostAndDeviceSupported) + library.HeaderOnly() + return module.Init() +} + +// cc_prebuilt_library_headers is a prebuilt version of cc_library_headers +func prebuiltLibraryHeaderFactory() android.Module { + module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) + library.HeaderOnly() + return module.Init() +} diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go new file mode 100644 index 000000000..564ef61fb --- /dev/null +++ b/cc/library_headers_test.go @@ -0,0 +1,62 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// 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. + +package cc + +import ( + "strings" + "testing" +) + +func TestLibraryHeaders(t *testing.T) { + ctx := testCc(t, ` + cc_library_headers { + name: "headers", + export_include_dirs: ["my_include"], + } + cc_library_static { + name: "lib", + srcs: ["foo.c"], + header_libs: ["headers"], + } + `) + + // test if header search paths are correctly added + cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc") + cflags := cc.Args["cFlags"] + if !strings.Contains(cflags, " -Imy_include ") { + t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags) + } +} + +func TestPrebuiltLibraryHeaders(t *testing.T) { + ctx := testCc(t, ` + cc_prebuilt_library_headers { + name: "headers", + export_include_dirs: ["my_include"], + } + cc_library_static { + name: "lib", + srcs: ["foo.c"], + header_libs: ["headers"], + } + `) + + // test if header search paths are correctly added + cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc") + cflags := cc.Args["cFlags"] + if !strings.Contains(cflags, " -Imy_include ") { + t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags) + } +} diff --git a/cc/prebuilt.go b/cc/prebuilt.go index b0cf4890e..2c18ac3a2 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -87,15 +87,16 @@ func (p *prebuiltLibraryLinker) linkerProps() []interface{} { func (p *prebuiltLibraryLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { + + p.libraryDecorator.exportIncludes(ctx) + p.libraryDecorator.reexportDirs(deps.ReexportedDirs...) + p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...) + p.libraryDecorator.reexportFlags(deps.ReexportedFlags...) + p.libraryDecorator.reexportDeps(deps.ReexportedDeps...) + p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) + // TODO(ccross): verify shared library dependencies if len(p.properties.Srcs) > 0 { - p.libraryDecorator.exportIncludes(ctx) - p.libraryDecorator.reexportDirs(deps.ReexportedDirs...) - p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...) - p.libraryDecorator.reexportFlags(deps.ReexportedFlags...) - p.libraryDecorator.reexportDeps(deps.ReexportedDeps...) - p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) - builderFlags := flagsToBuilderFlags(flags) in := p.Prebuilt.SingleSourcePath(ctx) diff --git a/cc/testing.go b/cc/testing.go index 368580f23..a22763a92 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -25,6 +25,7 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterCCBuildComponents(ctx) RegisterBinaryBuildComponents(ctx) RegisterLibraryBuildComponents(ctx) + RegisterLibraryHeadersBuildComponents(ctx) ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory) ctx.RegisterModuleType("llndk_library", LlndkLibraryFactory)