• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17// This file contains utility functions to check for bad or illegal cflags
18// specified by a module
19
20import (
21	"path/filepath"
22	"strings"
23
24	"android/soong/cc/config"
25)
26
27// Check for invalid c/conly/cpp/asflags and suggest alternatives. Only use this
28// for flags explicitly passed by the user, since these flags may be used internally.
29func CheckBadCompilerFlags(ctx BaseModuleContext, prop string, flags []string) {
30	for _, flag := range flags {
31		flag = strings.TrimSpace(flag)
32
33		if !strings.HasPrefix(flag, "-") {
34			ctx.PropertyErrorf(prop, "Flag `%s` must start with `-`", flag)
35		} else if strings.HasPrefix(flag, "-I") || strings.HasPrefix(flag, "-isystem") {
36			ctx.PropertyErrorf(prop, "Bad flag `%s`, use local_include_dirs or include_dirs instead", flag)
37		} else if inList(flag, config.IllegalFlags) {
38			ctx.PropertyErrorf(prop, "Illegal flag `%s`", flag)
39		} else if flag == "--coverage" {
40			ctx.PropertyErrorf(prop, "Bad flag: `%s`, use native_coverage instead", flag)
41		} else if strings.Contains(flag, " ") {
42			args := strings.Split(flag, " ")
43			if args[0] == "-include" {
44				if len(args) > 2 {
45					ctx.PropertyErrorf(prop, "`-include` only takes one argument: `%s`", flag)
46				}
47				path := filepath.Clean(args[1])
48				if strings.HasPrefix("/", path) {
49					ctx.PropertyErrorf(prop, "Path must not be an absolute path: %s", flag)
50				} else if strings.HasPrefix("../", path) {
51					ctx.PropertyErrorf(prop, "Path must not start with `../`: `%s`. Use include_dirs to -include from a different directory", flag)
52				}
53			} else {
54				ctx.PropertyErrorf(prop, "Bad flag: `%s` is not an allowed multi-word flag. Should it be split into multiple flags?", flag)
55			}
56		}
57	}
58}
59
60// Check for bad ldflags and suggest alternatives. Only use this for flags
61// explicitly passed by the user, since these flags may be used internally.
62func CheckBadLinkerFlags(ctx BaseModuleContext, prop string, flags []string) {
63	for _, flag := range flags {
64		flag = strings.TrimSpace(flag)
65
66		if !strings.HasPrefix(flag, "-") {
67			ctx.PropertyErrorf(prop, "Flag `%s` must start with `-`", flag)
68		} else if strings.HasPrefix(flag, "-l") {
69			if ctx.Host() {
70				ctx.PropertyErrorf(prop, "Bad flag: `%s`, use shared_libs or host_ldlibs instead", flag)
71			} else {
72				ctx.PropertyErrorf(prop, "Bad flag: `%s`, use shared_libs instead", flag)
73			}
74		} else if strings.HasPrefix(flag, "-L") {
75			ctx.PropertyErrorf(prop, "Bad flag: `%s` is not allowed", flag)
76		} else if strings.HasPrefix(flag, "-Wl,--version-script") {
77			ctx.PropertyErrorf(prop, "Bad flag: `%s`, use version_script instead", flag)
78		} else if flag == "--coverage" {
79			ctx.PropertyErrorf(prop, "Bad flag: `%s`, use native_coverage instead", flag)
80		} else if strings.Contains(flag, " ") {
81			args := strings.Split(flag, " ")
82			if args[0] == "-z" {
83				if len(args) > 2 {
84					ctx.PropertyErrorf(prop, "`-z` only takes one argument: `%s`", flag)
85				}
86			} else {
87				ctx.PropertyErrorf(prop, "Bad flag: `%s` is not an allowed multi-word flag. Should it be split into multiple flags?", flag)
88			}
89		}
90	}
91}
92
93// Check for bad host_ldlibs
94func CheckBadHostLdlibs(ctx ModuleContext, prop string, flags []string) {
95	allowed_ldlibs := ctx.toolchain().AvailableLibraries()
96
97	if !ctx.Host() {
98		panic("Invalid call to CheckBadHostLdlibs")
99	}
100
101	for _, flag := range flags {
102		flag = strings.TrimSpace(flag)
103
104		// TODO: Probably should just redo this property to prefix -l in Soong
105		if !strings.HasPrefix(flag, "-l") && !strings.HasPrefix(flag, "-framework") {
106			ctx.PropertyErrorf(prop, "Invalid flag: `%s`, must start with `-l` or `-framework`", flag)
107		} else if !inList(flag, allowed_ldlibs) {
108			ctx.PropertyErrorf(prop, "Host library `%s` not available", flag)
109		}
110	}
111}
112
113// Check for bad clang tidy flags
114func CheckBadTidyFlags(ctx ModuleContext, prop string, flags []string) {
115	for _, flag := range flags {
116		flag = strings.TrimSpace(flag)
117
118		if !strings.HasPrefix(flag, "-") {
119			ctx.PropertyErrorf(prop, "Flag `%s` must start with `-`", flag)
120		} else if strings.HasPrefix(flag, "-fix") {
121			ctx.PropertyErrorf(prop, "Flag `%s` is not allowed, since it could cause multiple writes to the same source file", flag)
122		} else if strings.HasPrefix(flag, "-checks=") {
123			ctx.PropertyErrorf(prop, "Flag `%s` is not allowed, use `tidy_checks` property instead", flag)
124		} else if strings.Contains(flag, " ") {
125			ctx.PropertyErrorf(prop, "Bad flag: `%s` is not an allowed multi-word flag. Should it be split into multiple flags?", flag)
126		}
127	}
128}
129
130// Check for bad clang tidy checks
131func CheckBadTidyChecks(ctx ModuleContext, prop string, checks []string) {
132	for _, check := range checks {
133		if strings.Contains(check, " ") {
134			ctx.PropertyErrorf("tidy_checks", "Check `%s` invalid, cannot contain spaces", check)
135		} else if strings.Contains(check, ",") {
136			ctx.PropertyErrorf("tidy_checks", "Check `%s` invalid, cannot contain commas. Split each entry into it's own string instead", check)
137		}
138	}
139}
140