diff --git a/Android.bp b/Android.bp index 03071d1d3..62e276ac8 100644 --- a/Android.bp +++ b/Android.bp @@ -97,10 +97,12 @@ bootstrap_go_package { "cc/config/arm_device.go", "cc/config/arm64_device.go", + "cc/config/arm64_fuchsia_device.go", "cc/config/mips_device.go", "cc/config/mips64_device.go", "cc/config/x86_device.go", "cc/config/x86_64_device.go", + "cc/config/x86_64_fuchsia_device.go", "cc/config/x86_darwin_host.go", "cc/config/x86_linux_host.go", diff --git a/android/config.go b/android/config.go index 106f245c3..6d81a3898 100644 --- a/android/config.go +++ b/android/config.go @@ -224,6 +224,22 @@ func TestConfig(buildDir string, env map[string]string) Config { return Config{config} } +func TestArchConfigFuchsia(buildDir string, env map[string]string) Config { + testConfig := TestConfig(buildDir, env) + config := testConfig.config + + config.Targets = map[OsType][]Target{ + Fuchsia: []Target{ + {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Native: true}}, + }, + BuildOs: []Target{ + {BuildOs, Arch{ArchType: X86_64}}, + }, + } + + return testConfig +} + // TestConfig returns a Config object suitable for using for tests that need to run the arch mutator func TestArchConfig(buildDir string, env map[string]string) Config { testConfig := TestConfig(buildDir, env) diff --git a/cc/binary.go b/cc/binary.go index c9e6cab50..9d0cf60be 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -196,7 +196,7 @@ func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) { if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() { binary.Properties.Static_executable = BoolPtr(true) } - } else { + } else if !ctx.Fuchsia() { // Static executables are not supported on Darwin or Windows binary.Properties.Static_executable = nil } diff --git a/cc/cc.go b/cc/cc.go index 5111bd2a7..ee6cd4e5b 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -599,7 +599,7 @@ func (ctx *moduleContextImpl) staticBinary() bool { } func (ctx *moduleContextImpl) useSdk() bool { - if ctx.ctx.Device() && !ctx.useVndk() && !ctx.inRecovery() { + if ctx.ctx.Device() && !ctx.useVndk() && !ctx.inRecovery() && !ctx.ctx.Fuchsia() { return String(ctx.mod.Properties.Sdk_version) != "" } return false @@ -668,6 +668,11 @@ func (ctx *moduleContextImpl) shouldCreateVndkSourceAbiDump() bool { if ctx.ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") { return false } + + if ctx.ctx.Fuchsia() { + return false + } + if sanitize := ctx.mod.sanitize; sanitize != nil { if !sanitize.isVariantOnProductionDevice() { return false diff --git a/cc/cc_test.go b/cc/cc_test.go index 96233a10e..dc23620e7 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -51,29 +51,8 @@ func TestMain(m *testing.M) { os.Exit(run()) } -func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext { - ctx := android.NewTestArchContext() - ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory)) - ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory)) - ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory)) - ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory)) - ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory)) - ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(LlndkLibraryFactory)) - ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory)) - ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory)) - ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory)) - ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) - ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("image", ImageMutator).Parallel() - ctx.BottomUp("link", LinkageMutator).Parallel() - ctx.BottomUp("vndk", VndkMutator).Parallel() - ctx.BottomUp("version", VersionMutator).Parallel() - ctx.BottomUp("begin", BeginMutator).Parallel() - }) - ctx.Register() - - // add some modules that are required by the compiler and/or linker - bp = bp + ` +func gatherRequiredDeps(os android.OsType) string { + ret := ` toolchain_library { name: "libatomic", vendor_available: true, @@ -215,8 +194,45 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. cc_library { name: "libprotobuf-cpp-lite", } + ` + if os == android.Fuchsia { + ret += ` + cc_library { + name: "libbioniccompat", + stl: "none", + } + cc_library { + name: "libcompiler_rt", + stl: "none", + } + ` + } + return ret +} -` +func createTestContext(t *testing.T, config android.Config, bp string, os android.OsType) *android.TestContext { + ctx := android.NewTestArchContext() + ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory)) + ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory)) + ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory)) + ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory)) + ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory)) + ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(LlndkLibraryFactory)) + ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory)) + ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory)) + ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory)) + ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) + ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("image", ImageMutator).Parallel() + ctx.BottomUp("link", LinkageMutator).Parallel() + ctx.BottomUp("vndk", VndkMutator).Parallel() + ctx.BottomUp("version", VersionMutator).Parallel() + ctx.BottomUp("begin", BeginMutator).Parallel() + }) + ctx.Register() + + // add some modules that are required by the compiler and/or linker + bp = bp + gatherRequiredDeps(os) ctx.MockFileSystem(map[string][]byte{ "Android.bp": []byte(bp), @@ -232,8 +248,12 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. } func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext { + return testCcWithConfigForOs(t, bp, config, android.Android) +} + +func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext { t.Helper() - ctx := createTestContext(t, config, bp) + ctx := createTestContext(t, config, bp, os) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) android.FailIfErrored(t, errs) @@ -266,7 +286,7 @@ func testCcError(t *testing.T, pattern string, bp string) { config.TestProductVariables.DeviceVndkVersion = StringPtr("current") config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := createTestContext(t, config, bp) + ctx := createTestContext(t, config, bp, android.Android) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) if len(errs) > 0 { @@ -289,6 +309,69 @@ const ( recoveryVariant = "android_arm64_armv8-a_recovery_shared" ) +func TestFuchsiaDeps(t *testing.T) { + t.Helper() + + bp := ` + cc_library { + name: "libTest", + srcs: ["foo.c"], + target: { + fuchsia: { + srcs: ["bar.c"], + }, + }, + }` + + config := android.TestArchConfigFuchsia(buildDir, nil) + ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia) + + rt := false + fb := false + + ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld") + implicits := ld.Implicits + for _, lib := range implicits { + if strings.Contains(lib.Rel(), "libcompiler_rt") { + rt = true + } + + if strings.Contains(lib.Rel(), "libbioniccompat") { + fb = true + } + } + + if !rt || !fb { + t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat") + } +} + +func TestFuchsiaTargetDecl(t *testing.T) { + t.Helper() + + bp := ` + cc_library { + name: "libTest", + srcs: ["foo.c"], + target: { + fuchsia: { + srcs: ["bar.c"], + }, + }, + }` + + config := android.TestArchConfigFuchsia(buildDir, nil) + ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia) + ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld") + var objs []string + for _, o := range ld.Inputs { + objs = append(objs, o.Base()) + } + if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" { + t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs) + } +} + func TestVendorSrc(t *testing.T) { ctx := testCc(t, ` cc_library { diff --git a/cc/config/arm64_fuchsia_device.go b/cc/config/arm64_fuchsia_device.go new file mode 100644 index 000000000..02c0c14d7 --- /dev/null +++ b/cc/config/arm64_fuchsia_device.go @@ -0,0 +1,101 @@ +// Copyright 2018 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 config + +import ( + "android/soong/android" +) + +var fuchsiaArm64SysRoot string = "prebuilts/fuchsia_sdk/arch/arm64/sysroot" +var fuchsiaArm64PrebuiltLibsRoot string = "fuchsia/prebuilt_libs/" + +type toolchainFuchsiaArm64 struct { + toolchain64Bit + toolchainFuchsia +} + +func (t *toolchainFuchsiaArm64) Name() string { + return "arm64" +} + +func (t *toolchainFuchsiaArm64) GccRoot() string { + return "${config.Arm64GccRoot}" +} + +func (t *toolchainFuchsiaArm64) GccTriple() string { + return "aarch64-linux-android" +} + +func (t *toolchainFuchsiaArm64) GccVersion() string { + return arm64GccVersion +} + +func (t *toolchainFuchsiaArm64) Cflags() string { + return "" +} + +func (t *toolchainFuchsiaArm64) Cppflags() string { + return "" +} + +func (t *toolchainFuchsiaArm64) Ldflags() string { + return "-Wl,--fix-cortex-a53-843419" +} + +func (t *toolchainFuchsiaArm64) IncludeFlags() string { + return "" +} + +func (t *toolchainFuchsiaArm64) ToolchainCflags() string { + return "-mcpu=cortex-a53" +} + +func (t *toolchainFuchsiaArm64) ClangTriple() string { + return "arm64-fuchsia-android" +} + +func (t *toolchainFuchsiaArm64) ClangCppflags() string { + return "-Wno-error=deprecated-declarations" +} + +func (t *toolchainFuchsiaArm64) ClangLdflags() string { + return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/" +} + +func (t *toolchainFuchsiaArm64) ClangLldflags() string { + return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/" +} + +func (t *toolchainFuchsiaArm64) ClangCflags() string { + return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -I" + fuchsiaArm64SysRoot + "/include" +} + +func (t *toolchainFuchsiaArm64) Bionic() bool { + return false +} + +func (t *toolchainFuchsiaArm64) ToolchainClangCflags() string { + return "-march=armv8-a" +} + +var toolchainArm64FuchsiaSingleton Toolchain = &toolchainFuchsiaArm64{} + +func arm64FuchsiaToolchainFactory(arch android.Arch) Toolchain { + return toolchainArm64FuchsiaSingleton +} + +func init() { + registerToolchainFactory(android.Fuchsia, android.Arm64, arm64FuchsiaToolchainFactory) +} diff --git a/cc/config/global.go b/cc/config/global.go index 5d98d67bc..ff11a8a65 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -150,8 +150,13 @@ func init() { pctx.StaticVariable("CommonClangGlobalCflags", strings.Join(append(ClangFilterUnknownCflags(commonGlobalCflags), "${ClangExtraCflags}"), " ")) - pctx.StaticVariable("DeviceClangGlobalCflags", - strings.Join(append(ClangFilterUnknownCflags(deviceGlobalCflags), "${ClangExtraTargetCflags}"), " ")) + pctx.VariableFunc("DeviceClangGlobalCflags", func(ctx android.PackageVarContext) string { + if ctx.Config().Fuchsia() { + return strings.Join(ClangFilterUnknownCflags(deviceGlobalCflags), " ") + } else { + return strings.Join(append(ClangFilterUnknownCflags(deviceGlobalCflags), "${ClangExtraTargetCflags}"), " ") + } + }) pctx.StaticVariable("HostClangGlobalCflags", strings.Join(ClangFilterUnknownCflags(hostGlobalCflags), " ")) pctx.StaticVariable("NoOverrideClangGlobalCflags", diff --git a/cc/config/x86_64_fuchsia_device.go b/cc/config/x86_64_fuchsia_device.go new file mode 100644 index 000000000..79af00c5c --- /dev/null +++ b/cc/config/x86_64_fuchsia_device.go @@ -0,0 +1,106 @@ +// Copyright 2018 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 config + +import ( + "android/soong/android" +) + +var fuchsiaSysRoot string = "prebuilts/fuchsia_sdk/arch/x64/sysroot" +var fuchsiaPrebuiltLibsRoot string = "fuchsia/prebuilt_libs" + +type toolchainFuchsia struct { + cFlags, ldFlags string +} + +type toolchainFuchsiaX8664 struct { + toolchain64Bit + toolchainFuchsia +} + +func (t *toolchainFuchsiaX8664) Name() string { + return "x86_64" +} + +func (t *toolchainFuchsiaX8664) GccRoot() string { + return "${config.X86_64GccRoot}" +} + +func (t *toolchainFuchsiaX8664) GccTriple() string { + return "x86_64-linux-android" +} + +func (t *toolchainFuchsiaX8664) GccVersion() string { + return x86_64GccVersion +} + +func (t *toolchainFuchsiaX8664) Cflags() string { + return "" +} + +func (t *toolchainFuchsiaX8664) Cppflags() string { + return "" +} + +func (t *toolchainFuchsiaX8664) Ldflags() string { + return "" +} + +func (t *toolchainFuchsiaX8664) IncludeFlags() string { + return "" +} + +func (t *toolchainFuchsiaX8664) ClangTriple() string { + return "x86_64-fuchsia-android" +} + +func (t *toolchainFuchsiaX8664) ClangCppflags() string { + return "-Wno-error=deprecated-declarations" +} + +func (t *toolchainFuchsiaX8664) ClangLdflags() string { + return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/" + +} + +func (t *toolchainFuchsiaX8664) ClangLldflags() string { + return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/" +} + +func (t *toolchainFuchsiaX8664) ClangCflags() string { + return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -I" + fuchsiaSysRoot + "/include" +} + +func (t *toolchainFuchsiaX8664) Bionic() bool { + return false +} + +func (t *toolchainFuchsiaX8664) YasmFlags() string { + return "-f elf64 -m amd64" +} + +func (t *toolchainFuchsiaX8664) ToolchainClangCflags() string { + return "-DUSE_SSSE3 -mssse3" +} + +var toolchainFuchsiaSingleton Toolchain = &toolchainFuchsiaX8664{} + +func fuchsiaToolchainFactory(arch android.Arch) Toolchain { + return toolchainFuchsiaSingleton +} + +func init() { + registerToolchainFactory(android.Fuchsia, android.X86_64, fuchsiaToolchainFactory) +} diff --git a/cc/linker.go b/cc/linker.go index cda392db9..dbdcd578e 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -270,6 +270,18 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.LateSharedLibs = append(deps.LateSharedLibs, systemSharedLibs...) } + if ctx.Fuchsia() { + if ctx.ModuleName() != "libbioniccompat" && + ctx.ModuleName() != "libcompiler_rt-extras" && + ctx.ModuleName() != "libcompiler_rt" { + deps.StaticLibs = append(deps.StaticLibs, "libbioniccompat") + } + if ctx.ModuleName() != "libcompiler_rt" && ctx.ModuleName() != "libcompiler_rt-extras" { + deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt") + } + + } + if ctx.Windows() { deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") } @@ -360,7 +372,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags()) } - if !ctx.toolchain().Bionic() { + if !ctx.toolchain().Bionic() && !ctx.Fuchsia() { CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...) @@ -379,6 +391,10 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { } } + if ctx.Fuchsia() { + flags.LdFlags = append(flags.LdFlags, "-lfdio", "-lzircon") + } + CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags) flags.LdFlags = append(flags.LdFlags, proptools.NinjaAndShellEscape(linker.Properties.Ldflags)...) diff --git a/cc/sanitize.go b/cc/sanitize.go index d19e54a34..79fbd4707 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -167,6 +167,11 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { s.Never = BoolPtr(true) } + // Sanitizers do not work on Fuchsia yet. + if ctx.Fuchsia() { + s.Never = BoolPtr(true) + } + // Never always wins. if Bool(s.Never) { return diff --git a/cc/stl.go b/cc/stl.go index 487087015..5e61e1e69 100644 --- a/cc/stl.go +++ b/cc/stl.go @@ -91,6 +91,26 @@ func (stl *stl) begin(ctx BaseModuleContext) { ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s) return "" } + } else if ctx.Fuchsia() { + switch s { + case "c++_static": + return "libc++_static" + case "c++_shared": + return "libc++" + case "libc++", "libc++_static": + return s + case "none": + return "" + case "": + if ctx.static() { + return "libc++_static" + } else { + return "libc++" + } + default: + ctx.ModuleErrorf("stl: %q is not a supported STL on Fuchsia", s) + return "" + } } else { switch s { case "libc++", "libc++_static": @@ -248,8 +268,9 @@ var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string func init() { hostDynamicGccLibs = map[android.OsType][]string{ - android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"}, - android.Darwin: []string{"-lc", "-lSystem"}, + android.Fuchsia: []string{"-lc", "-lunwind"}, + android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"}, + android.Darwin: []string{"-lc", "-lSystem"}, android.Windows: []string{"-Wl,--start-group", "-lmingw32", "-lgcc", "-lgcc_eh", "-lmoldname", "-lmingwex", "-lmsvcrt", "-lucrt", "-lpthread", "-ladvapi32", "-lshell32", "-luser32", "-lkernel32", "-lpsapi",