-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for layering_check (#325)
This feature currently applies to C/C++ compiles. It validates that for every header you import you have a corresponding target in your deps that surfaces that header. Bazel handles a lot of this logic internally in the CC rules but it's up to us to provide a system-level modulemap file that contains all system headers, so that non-system headers that aren't in your deps are correctly flagged as a layering check violation. To do this we use find to discover all headers in the current DEVELOPER_DIR. There are a few potential caching issues surfaced with this: 1. If the paths were absolute, the Xcode path would be an input. We avoid this by storing relative paths, and then using a vfsoverlay to make it "look" like the modulemap is inside of Xcode itself, which is the only way to make relative paths work in modulemaps. 2. If different Xcode versions have different headers, and you support multiple Xcode versions in your build, the modulemap file is an input and will cause caching issues. I think the future solution to this would be allow users to provide their own modulemap with a constant set of headers, since you likely won't care about the new or removed ones (and if you do you have to only support 1 of the Xcode verisons) This is currently disabled by default and can be enabled with `--repo_env=APPLE_SUPPORT_LAYERING_CHECK_BETA=1`. This is primarily because of the issues above, and that generating the modulemap file takes ~5 seconds.
- Loading branch information
Showing
13 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/bin/bash | ||
|
||
set -euo pipefail | ||
|
||
cd "$(xcode-select -p)" | ||
|
||
echo 'module "crosstool" [system] {' | ||
|
||
find . -type f \( -name "*.h" -o -name "*.def" -o -path "*/c++/*" \) \ | ||
| LANG=C sort -u | while read -r header; do | ||
echo " textual header \"${header}\"" | ||
done | ||
|
||
echo "}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
load("@bazel_skylib//rules:build_test.bzl", "build_test") | ||
|
||
package(features = ["layering_check"]) | ||
|
||
cc_library( | ||
name = "a", | ||
hdrs = ["a.h"], | ||
) | ||
|
||
cc_library( | ||
name = "b", | ||
hdrs = ["b.h"], | ||
deps = [":a"], | ||
) | ||
|
||
cc_test( | ||
name = "bad_layering_check", | ||
srcs = ["c.cpp"], | ||
deps = [":b"], | ||
) | ||
|
||
cc_test( | ||
name = "disabled_bad_layering_check", | ||
srcs = ["c.cpp"], | ||
features = ["-layering_check"], | ||
deps = [":b"], | ||
) | ||
|
||
cc_test( | ||
name = "good_layering_check", | ||
srcs = ["c.cpp"], | ||
deps = [ | ||
":a", | ||
":b", | ||
], | ||
) | ||
|
||
objc_library( | ||
name = "bad_layering_check_objc", | ||
srcs = ["c.m"], | ||
tags = ["manual"], | ||
deps = [":b"], | ||
) | ||
|
||
build_test( | ||
name = "bad_layering_check_objc_test", | ||
targets = [":bad_layering_check_objc"], | ||
) | ||
|
||
objc_library( | ||
name = "disabled_bad_layering_check_objc", | ||
srcs = ["c.m"], | ||
features = ["-layering_check"], | ||
deps = [":b"], | ||
) | ||
|
||
build_test( | ||
name = "disabled_bad_layering_check_objc_test", | ||
targets = [":disabled_bad_layering_check_objc"], | ||
) | ||
|
||
objc_library( | ||
name = "good_layering_check_objc", | ||
srcs = ["c.m"], | ||
deps = [ | ||
":a", | ||
":b", | ||
], | ||
) | ||
|
||
build_test( | ||
name = "good_layering_check_objc_test", | ||
targets = [":good_layering_check_objc"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
int from_a_library = 1; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
int from_b_library = 2; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "a.h" | ||
#include "b.h" | ||
#include <iostream> | ||
|
||
int main() { | ||
std::cout << from_a_library << from_b_library << std::endl; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#include "a.h" | ||
#include "b.h" | ||
#import <Foundation/Foundation.h> | ||
#include <stdio.h> | ||
|
||
int main() { | ||
NSLog(@"%d %d", from_a_library, from_b_library); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/bin/bash | ||
|
||
set -euo pipefail | ||
|
||
script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
source "$script_path"/unittest.bash | ||
|
||
bazel="${BAZEL:-bazel}" | ||
|
||
function test_good_layering_checks() { | ||
"$bazel" test --repo_env=APPLE_SUPPORT_LAYERING_CHECK_BETA=1 -- //test/layering_check/... -//test/layering_check:bad_layering_check -//test/layering_check:bad_layering_check_objc_test &>"$TEST_log" | ||
} | ||
|
||
function test_bad_layering_checks() { | ||
! "$bazel" test --repo_env=APPLE_SUPPORT_LAYERING_CHECK_BETA=1 -- //test/layering_check:bad_layering_check &> "$TEST_log" || fail "Expected build failure" | ||
|
||
expect_log_once "does not depend on a module exporting" | ||
expect_log "test/layering_check/c.cpp:1:10: error: module //test/layering_check:bad_layering_check does not depend on a module exporting 'a.h'" "failed wrong layering_check" | ||
} | ||
|
||
function test_bad_layering_checks_objc() { | ||
! "$bazel" test --repo_env=APPLE_SUPPORT_LAYERING_CHECK_BETA=1 -- //test/layering_check:bad_layering_check_objc_test &> "$TEST_log" || fail "Expected build failure" | ||
|
||
expect_log_once "does not depend on a module exporting" | ||
expect_log "test/layering_check/c.m:1:10: error: module //test/layering_check:bad_layering_check_objc does not depend on a module exporting 'a.h'" "failed wrong layering_check" | ||
} | ||
|
||
run_suite "layering_check tests" |