xref: /aosp_15_r20/build/soong/cc/cc_preprocess_no_configuration.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2024 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	"android/soong/android"
19*333d2b36SAndroid Build Coastguard Worker	"slices"
20*333d2b36SAndroid Build Coastguard Worker	"strings"
21*333d2b36SAndroid Build Coastguard Worker)
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Workerfunc init() {
24*333d2b36SAndroid Build Coastguard Worker	RegisterCCPreprocessNoConfiguration(android.InitRegistrationContext)
25*333d2b36SAndroid Build Coastguard Worker}
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Workerfunc RegisterCCPreprocessNoConfiguration(ctx android.RegistrationContext) {
28*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("cc_preprocess_no_configuration", ccPreprocessNoConfigurationFactory)
29*333d2b36SAndroid Build Coastguard Worker}
30*333d2b36SAndroid Build Coastguard Worker
31*333d2b36SAndroid Build Coastguard Worker// cc_preprocess_no_configuration modules run the c preprocessor on a single input source file.
32*333d2b36SAndroid Build Coastguard Worker// They also have "no configuration", meaning they don't have an arch or os associated with them,
33*333d2b36SAndroid Build Coastguard Worker// they should be thought of as pure textual transformations of the input file. In some cases this
34*333d2b36SAndroid Build Coastguard Worker// is good, in others you might want to do different transformations depending on what arch the
35*333d2b36SAndroid Build Coastguard Worker// result will be compiled in, in which case you can use cc_object instead of this module.
36*333d2b36SAndroid Build Coastguard Workerfunc ccPreprocessNoConfigurationFactory() android.Module {
37*333d2b36SAndroid Build Coastguard Worker	m := &ccPreprocessNoConfiguration{}
38*333d2b36SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
39*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidModule(m)
40*333d2b36SAndroid Build Coastguard Worker	return m
41*333d2b36SAndroid Build Coastguard Worker}
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Workertype ccPreprocessNoConfigurationProps struct {
44*333d2b36SAndroid Build Coastguard Worker	// Called Srcs for consistency with the other cc module types, but only accepts 1 input source
45*333d2b36SAndroid Build Coastguard Worker	// file.
46*333d2b36SAndroid Build Coastguard Worker	Srcs []string `android:"path"`
47*333d2b36SAndroid Build Coastguard Worker	// The flags to pass to the c compiler. Must include -E in order to enable preprocessing-only
48*333d2b36SAndroid Build Coastguard Worker	// mode.
49*333d2b36SAndroid Build Coastguard Worker	Cflags []string `android:"path"`
50*333d2b36SAndroid Build Coastguard Worker}
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Workertype ccPreprocessNoConfiguration struct {
53*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
54*333d2b36SAndroid Build Coastguard Worker	properties ccPreprocessNoConfigurationProps
55*333d2b36SAndroid Build Coastguard Worker}
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Workerfunc (m *ccPreprocessNoConfiguration) GenerateAndroidBuildActions(ctx android.ModuleContext) {
58*333d2b36SAndroid Build Coastguard Worker	srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
59*333d2b36SAndroid Build Coastguard Worker	if len(srcs) != 1 {
60*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("Srcs", "cc_preprocess_no_configuration only accepts 1 source file, found: %v", srcs.Strings())
61*333d2b36SAndroid Build Coastguard Worker		return
62*333d2b36SAndroid Build Coastguard Worker	}
63*333d2b36SAndroid Build Coastguard Worker	src := srcs[0]
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Worker	hasE := false
66*333d2b36SAndroid Build Coastguard Worker	for _, cflag := range m.properties.Cflags {
67*333d2b36SAndroid Build Coastguard Worker		if cflag == "-E" {
68*333d2b36SAndroid Build Coastguard Worker			hasE = true
69*333d2b36SAndroid Build Coastguard Worker			break
70*333d2b36SAndroid Build Coastguard Worker		} else if cflag == "-P" || strings.HasPrefix(cflag, "-D") {
71*333d2b36SAndroid Build Coastguard Worker			// do nothing, allow it
72*333d2b36SAndroid Build Coastguard Worker		} else {
73*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("Cflags", "cc_preprocess_no_configuration only allows -D and -P flags, found: %q", cflag)
74*333d2b36SAndroid Build Coastguard Worker			return
75*333d2b36SAndroid Build Coastguard Worker		}
76*333d2b36SAndroid Build Coastguard Worker	}
77*333d2b36SAndroid Build Coastguard Worker	if !hasE {
78*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("Cflags", "cc_preprocess_no_configuration must have a -E cflag")
79*333d2b36SAndroid Build Coastguard Worker		return
80*333d2b36SAndroid Build Coastguard Worker	}
81*333d2b36SAndroid Build Coastguard Worker
82*333d2b36SAndroid Build Coastguard Worker	cflags := slices.Clone(m.properties.Cflags)
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Worker	// Match behavior of other cc modules:
85*333d2b36SAndroid Build Coastguard Worker	// https://cs.android.com/android/platform/superproject/main/+/main:build/soong/cc/compiler.go;l=422;drc=7297f05ee8cda422ccb32c4af4d9d715d6bac10e
86*333d2b36SAndroid Build Coastguard Worker	cflags = append(cflags, "-I"+ctx.ModuleDir())
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Worker	var ccCmd string
89*333d2b36SAndroid Build Coastguard Worker	switch src.Ext() {
90*333d2b36SAndroid Build Coastguard Worker	case ".c":
91*333d2b36SAndroid Build Coastguard Worker		ccCmd = "clang"
92*333d2b36SAndroid Build Coastguard Worker	case ".cpp", ".cc", ".cxx", ".mm":
93*333d2b36SAndroid Build Coastguard Worker		ccCmd = "clang++"
94*333d2b36SAndroid Build Coastguard Worker	default:
95*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("srcs", "File %s has unknown extension. Supported extensions: .c, .cpp, .cc, .cxx, .mm", src)
96*333d2b36SAndroid Build Coastguard Worker		return
97*333d2b36SAndroid Build Coastguard Worker	}
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Worker	ccCmd = "${config.ClangBin}/" + ccCmd
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker	outFile := android.PathForModuleOut(ctx, src.Base())
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
104*333d2b36SAndroid Build Coastguard Worker		Rule:        cc,
105*333d2b36SAndroid Build Coastguard Worker		Description: ccCmd + " " + src.Rel(),
106*333d2b36SAndroid Build Coastguard Worker		Output:      outFile,
107*333d2b36SAndroid Build Coastguard Worker		Input:       src,
108*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
109*333d2b36SAndroid Build Coastguard Worker			"cFlags": strings.Join(cflags, " "),
110*333d2b36SAndroid Build Coastguard Worker			"ccCmd":  ccCmd,
111*333d2b36SAndroid Build Coastguard Worker		},
112*333d2b36SAndroid Build Coastguard Worker	})
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles([]android.Path{outFile}, "")
115*333d2b36SAndroid Build Coastguard Worker}
116