Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e228f8e9 authored by Cole Faust's avatar Cole Faust Committed by Gerrit Code Review
Browse files

Merge "Add cc_preprocess_no_configuration modules" into main

parents 1947f2e4 c9885681
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ bootstrap_go_package {
        "builder.go",
        "cc.go",
        "ccdeps.go",
        "cc_preprocess_no_configuration.go",
        "check.go",
        "coverage.go",
        "gen.go",
@@ -88,6 +89,7 @@ bootstrap_go_package {
    testSrcs: [
        "afdo_test.go",
        "binary_test.go",
        "cc_preprocess_no_configuration_test.go",
        "cc_test.go",
        "cc_test_only_property_test.go",
        "cmake_snapshot_test.go",
+108 −0
Original line number Diff line number Diff line
// Copyright 2024 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"
	"strings"
)

func init() {
	RegisterCCPreprocessNoConfiguration(android.InitRegistrationContext)
}

func RegisterCCPreprocessNoConfiguration(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("cc_preprocess_no_configuration", ccPreprocessNoConfigurationFactory)
}

// cc_preprocess_no_configuration modules run the c preprocessor on a single input source file.
// They also have "no configuration", meaning they don't have an arch or os associated with them,
// they should be thought of as pure textual transformations of the input file. In some cases this
// is good, in others you might want to do different transformations depending on what arch the
// result will be compiled in, in which case you can use cc_object instead of this module.
func ccPreprocessNoConfigurationFactory() android.Module {
	m := &ccPreprocessNoConfiguration{}
	m.AddProperties(&m.properties)
	android.InitAndroidModule(m)
	return m
}

type ccPreprocessNoConfigurationProps struct {
	// Called Srcs for consistency with the other cc module types, but only accepts 1 input source
	// file.
	Srcs []string `android:"path"`
	// The flags to pass to the c compiler. Must include -E in order to enable preprocessing-only
	// mode.
	Cflags []string `android:"path"`
}

type ccPreprocessNoConfiguration struct {
	android.ModuleBase
	properties ccPreprocessNoConfigurationProps
}

func (m *ccPreprocessNoConfiguration) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
	if len(srcs) != 1 {
		ctx.PropertyErrorf("Srcs", "cc_preprocess_no_configuration only accepts 1 source file, found: %v", srcs.Strings())
		return
	}
	src := srcs[0]

	hasE := false
	for _, cflag := range m.properties.Cflags {
		if cflag == "-E" {
			hasE = true
			break
		} else if cflag == "-P" || strings.HasPrefix(cflag, "-D") {
			// do nothing, allow it
		} else {
			ctx.PropertyErrorf("Cflags", "cc_preprocess_no_configuration only allows -D and -P flags, found: %q", cflag)
			return
		}
	}
	if !hasE {
		ctx.PropertyErrorf("Cflags", "cc_preprocess_no_configuration must have a -E cflag")
		return
	}

	var ccCmd string
	switch src.Ext() {
	case ".c":
		ccCmd = "clang"
	case ".cpp", ".cc", ".cxx", ".mm":
		ccCmd = "clang++"
	default:
		ctx.PropertyErrorf("srcs", "File %s has unknown extension. Supported extensions: .c, .cpp, .cc, .cxx, .mm", src)
		return
	}

	ccCmd = "${config.ClangBin}/" + ccCmd

	outFile := android.PathForModuleOut(ctx, src.Base())

	ctx.Build(pctx, android.BuildParams{
		Rule:        cc,
		Description: ccCmd + " " + src.Rel(),
		Output:      outFile,
		Input:       src,
		Args: map[string]string{
			"cFlags": strings.Join(m.properties.Cflags, " "),
			"ccCmd":  ccCmd,
		},
	})

	ctx.SetOutputFiles([]android.Path{outFile}, "")
}
+40 −0
Original line number Diff line number Diff line
// Copyright 2019 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"
	"testing"
)

func TestCcPreprocessNoConfiguration(t *testing.T) {
	fixture := android.GroupFixturePreparers(
		android.PrepareForIntegrationTestWithAndroid,
		android.FixtureRegisterWithContext(RegisterCCPreprocessNoConfiguration),
	)

	result := fixture.RunTestWithBp(t, `
cc_preprocess_no_configuration {
	name: "foo",
	srcs: ["main.cc"],
	cflags: ["-E", "-DANDROID"],
}
`)

	foo := result.ModuleForTests("foo", "")
	actual := foo.Rule("cc").Args["cFlags"]
	expected := "-E -DANDROID"
	android.AssertStringEquals(t, "cflags should be correct", expected, actual)
}