Skip to content

Commit ad2eacf

Browse files
authored
Merge pull request github#16117 from github/redsun82/kotlin
Kotlin: build extractor with bazel
2 parents 60970ff + b7e16ca commit ad2eacf

File tree

66 files changed

+2840
-190
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2840
-190
lines changed

.gitattributes

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,36 +50,37 @@
5050
*.dll -text
5151
*.pdb -text
5252

53-
java/ql/test/stubs/**/*.java linguist-generated=true
54-
java/ql/test/experimental/stubs/**/*.java linguist-generated=true
53+
/java/ql/test/stubs/**/*.java linguist-generated=true
54+
/java/ql/test/experimental/stubs/**/*.java linguist-generated=true
55+
/java/kotlin-extractor/deps/*.jar filter=lfs diff=lfs merge=lfs -text
5556

5657
# Force git not to modify line endings for go or html files under the go/ql directory
57-
go/ql/**/*.go -text
58-
go/ql/**/*.html -text
58+
/go/ql/**/*.go -text
59+
/go/ql/**/*.html -text
5960
# Force git not to modify line endings for go dbschemes
60-
go/*.dbscheme -text
61+
/go/*.dbscheme -text
6162
# Preserve unusual line ending from codeql-go merge
62-
go/extractor/opencsv/CSVReader.java -text
63+
/go/extractor/opencsv/CSVReader.java -text
6364

6465
# For some languages, upgrade script testing references really old dbscheme
6566
# files from legacy upgrades that have CRLF line endings. Since upgrade
6667
# resolution relies on object hashes, we must suppress line ending conversion
6768
# for those testing dbscheme files.
68-
*/ql/lib/upgrades/initial/*.dbscheme -text
69+
/*/ql/lib/upgrades/initial/*.dbscheme -text
6970

7071
# Auto-generated modeling for Python
71-
python/ql/lib/semmle/python/frameworks/data/internal/subclass-capture/*.yml linguist-generated=true
72+
/python/ql/lib/semmle/python/frameworks/data/internal/subclass-capture/*.yml linguist-generated=true
7273

7374
# auto-generated bazel lock file
74-
ruby/extractor/cargo-bazel-lock.json linguist-generated=true
75-
ruby/extractor/cargo-bazel-lock.json -merge
75+
/ruby/extractor/cargo-bazel-lock.json linguist-generated=true
76+
/ruby/extractor/cargo-bazel-lock.json -merge
7677

7778
# auto-generated files for the C# build
78-
csharp/paket.lock linguist-generated=true
79-
# needs eol=crlf, as `paket` touches this file and saves it als crlf
80-
csharp/.paket/Paket.Restore.targets linguist-generated=true eol=crlf
81-
csharp/paket.main.bzl linguist-generated=true
82-
csharp/paket.main_extension.bzl linguist-generated=true
79+
/csharp/paket.lock linguist-generated=true
80+
# needs eol=crlf, as `paket` touches this file and saves it as crlf
81+
/csharp/.paket/Paket.Restore.targets linguist-generated=true eol=crlf
82+
/csharp/paket.main.bzl linguist-generated=true
83+
/csharp/paket.main_extension.bzl linguist-generated=true
8384

8485
# ripunzip tool
8586
/misc/bazel/internal/ripunzip/ripunzip-* filter=lfs diff=lfs merge=lfs -text

.github/workflows/kotlin-build.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: "Kotlin Build"
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "java/kotlin-extractor/**"
7+
- "misc/bazel/**"
8+
- "misc/codegen/**"
9+
- "*.bazel*"
10+
- .github/workflows/kotlin-build.yml
11+
branches:
12+
- main
13+
- rc/*
14+
- codeql-cli-*
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
- run: |
25+
bazel query //java/kotlin-extractor/...
26+
# only build the default version as a quick check that we can build from `codeql`
27+
# the full official build will be checked by QLucie
28+
bazel build //java/kotlin-extractor

.lfsconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
# codeql is publicly forked by many users, and we don't want any LFS file polluting their working
33
# copies. We therefore exclude everything by default.
44
# For files required by bazel builds, use rules in `misc/bazel/lfs.bzl` to download them on demand.
5+
# we go for `fetchinclude` to something not exsiting rather than `fetchexclude = *` because the
6+
# former is easier to override (with `git -c` or a local git config) to fetch something specific
57
fetchinclude = /nothing

MODULE.bazel

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ bazel_dep(name = "bazel_skylib", version = "1.5.0")
2222
bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
2323
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
2424
bazel_dep(name = "fmt", version = "10.0.0")
25+
bazel_dep(name = "rules_kotlin", version = "1.9.4-codeql.1")
2526
bazel_dep(name = "gazelle", version = "0.36.0")
2627
bazel_dep(name = "rules_dotnet", version = "0.15.1")
2728
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
@@ -65,6 +66,51 @@ node.toolchain(
6566
)
6667
use_repo(node, "nodejs", "nodejs_toolchains")
6768

69+
kotlin_extractor_deps = use_extension("//java/kotlin-extractor:deps.bzl", "kotlin_extractor_deps")
70+
71+
# following list can be kept in sync by running `bazel mod tidy` in `codeql`
72+
use_repo(
73+
kotlin_extractor_deps,
74+
"codeql_kotlin_defaults",
75+
"codeql_kotlin_embeddable",
76+
"kotlin-compiler-1.5.0",
77+
"kotlin-compiler-1.5.10",
78+
"kotlin-compiler-1.5.20",
79+
"kotlin-compiler-1.5.30",
80+
"kotlin-compiler-1.6.0",
81+
"kotlin-compiler-1.6.20",
82+
"kotlin-compiler-1.7.0",
83+
"kotlin-compiler-1.7.20",
84+
"kotlin-compiler-1.8.0",
85+
"kotlin-compiler-1.9.0-Beta",
86+
"kotlin-compiler-1.9.20-Beta",
87+
"kotlin-compiler-2.0.0-RC1",
88+
"kotlin-compiler-embeddable-1.5.0",
89+
"kotlin-compiler-embeddable-1.5.10",
90+
"kotlin-compiler-embeddable-1.5.20",
91+
"kotlin-compiler-embeddable-1.5.30",
92+
"kotlin-compiler-embeddable-1.6.0",
93+
"kotlin-compiler-embeddable-1.6.20",
94+
"kotlin-compiler-embeddable-1.7.0",
95+
"kotlin-compiler-embeddable-1.7.20",
96+
"kotlin-compiler-embeddable-1.8.0",
97+
"kotlin-compiler-embeddable-1.9.0-Beta",
98+
"kotlin-compiler-embeddable-1.9.20-Beta",
99+
"kotlin-compiler-embeddable-2.0.0-RC1",
100+
"kotlin-stdlib-1.5.0",
101+
"kotlin-stdlib-1.5.10",
102+
"kotlin-stdlib-1.5.20",
103+
"kotlin-stdlib-1.5.30",
104+
"kotlin-stdlib-1.6.0",
105+
"kotlin-stdlib-1.6.20",
106+
"kotlin-stdlib-1.7.0",
107+
"kotlin-stdlib-1.7.20",
108+
"kotlin-stdlib-1.8.0",
109+
"kotlin-stdlib-1.9.0-Beta",
110+
"kotlin-stdlib-1.9.20-Beta",
111+
"kotlin-stdlib-2.0.0-RC1",
112+
)
113+
68114
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
69115
go_sdk.download(version = "1.22.2")
70116

java/downgrades/BUILD.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
2+
3+
pkg_files(
4+
name = "downgrades",
5+
srcs = glob(
6+
["**"],
7+
exclude = ["BUILD.bazel"],
8+
),
9+
prefix = "downgrades",
10+
strip_prefix = strip_prefix.from_pkg(),
11+
visibility = ["//visibility:public"],
12+
)

java/kotlin-extractor/BUILD.bazel

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
"""
2+
# Usage overview
3+
Building the extractor can be done with bazel. If building from the internal repository, it is recommended to use
4+
`tools/bazel` from there.
5+
6+
A specific kotlin extractor variant can be built with
7+
```
8+
bazel build @codeql//java/kotlin-extractor:codeql-extractor-kotlin-<variant>-<version>
9+
```
10+
where `<variant>` is either `standalone` or `embeddable`, and `<version>` is one of the supported versions.
11+
```
12+
bazel build @codeql//java/kotlin-extractor
13+
```
14+
will build a default variant:
15+
* standalone, unless `CODEQL_KOTLIN_SINGLE_VERSION_EMBEDDABLE` is set to true, in which case it will go for embeddable
16+
* the version will be taken as the last supported version less than the version of the currently installed `kotlinc`
17+
* if `CODEQL_KOTLIN_SINGLE_VERSION` is set, that will be used instead
18+
* if `kotlinc` is not installed, `1.9.20-Beta` will be used
19+
20+
If `kotlinc` is updated, bazel won't be aware of it and will therefore keep the same default version. Possible workarounds for that:
21+
* `bazel clean`
22+
* `bazel fetch --force @codeql//java/kotlin-extractor`
23+
* `bazel fetch --force @codeql_kotlin_defaults//:all` (only from `codeql`)
24+
25+
If building from the `codeql` repository, `@codeql` can be skipped.
26+
"""
27+
28+
# This file is used in the `@codeql_kotlin_embeddable` external repo, which means we need to
29+
# reference explicitly @codeql
30+
load(
31+
"@codeql//java/kotlin-extractor:versions.bzl",
32+
"VERSIONS",
33+
"get_compatilibity_sources",
34+
"get_language_version",
35+
"version_less",
36+
)
37+
load("@rules_kotlin//kotlin:core.bzl", "kt_javac_options", "kt_kotlinc_options")
38+
load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
39+
40+
package(default_visibility = ["//java/kotlin-extractor:__subpackages__"])
41+
42+
_for_embeddable = repo_name().endswith("codeql_kotlin_embeddable")
43+
44+
_common_extractor_name_prefix = "codeql-extractor-kotlin"
45+
46+
_extractor_name_prefix = "%s-%s" % (
47+
_common_extractor_name_prefix,
48+
"embeddable" if _for_embeddable else "standalone",
49+
)
50+
51+
py_binary(
52+
name = "generate_dbscheme",
53+
srcs = ["generate_dbscheme.py"],
54+
)
55+
56+
_resources = [
57+
(
58+
r,
59+
r[len("src/main/resources/"):],
60+
)
61+
for r in glob(["src/main/resources/**"])
62+
]
63+
64+
kt_javac_options(
65+
name = "javac-options",
66+
release = "8",
67+
)
68+
69+
[
70+
(
71+
kt_kotlinc_options(
72+
name = "kotlinc-options-%s" % v,
73+
include_stdlibs = "none",
74+
jvm_target = "1.8",
75+
language_version = get_language_version(v),
76+
warn = "error",
77+
x_optin = [
78+
"kotlin.RequiresOptIn",
79+
"org.jetbrains.kotlin.ir.symbols.%s" %
80+
("IrSymbolInternals" if version_less(v, "2.0.0") else "UnsafeDuringIrConstructionAPI"),
81+
],
82+
x_suppress_version_warnings = True,
83+
),
84+
# * extractor.name is different for each version, so we need to put it in different output dirs
85+
# * in order to put it in `resources`, we need to define `resource_strip_prefix` to strip this version
86+
# * `resource_strip_prefix` is unique per jar, so we must also put other resources under the same version prefix
87+
genrule(
88+
name = "resources-%s" % v,
89+
srcs = [src for src, _ in _resources],
90+
outs = [
91+
"%s/com/github/codeql/extractor.name" % v,
92+
] + [
93+
"%s/%s" % (v, target)
94+
for _, target in _resources
95+
],
96+
cmd = "\n".join([
97+
"echo %s-%s > $(RULEDIR)/%s/com/github/codeql/extractor.name" % (_extractor_name_prefix, v, v),
98+
] + [
99+
"cp $(execpath %s) $(RULEDIR)/%s/%s" % (source, v, target)
100+
for source, target in _resources
101+
]),
102+
),
103+
kt_jvm_library(
104+
name = "%s-%s" % (_extractor_name_prefix, v),
105+
srcs =
106+
["@codeql//java/kotlin-extractor:generated-dbscheme"] +
107+
glob(
108+
[
109+
"src/**/*.kt",
110+
"src/**/*.java",
111+
],
112+
exclude = ["src/main/kotlin/utils/versions/**"],
113+
) + get_compatilibity_sources(v, "src/main/kotlin/utils/versions"),
114+
javac_opts = ":javac-options",
115+
kotlinc_opts = ":kotlinc-options-%s" % v,
116+
module_name = "codeql-kotlin-extractor",
117+
# resource_strip_prefix is very nit-picky: the following makes it work from
118+
# `codeql`, `@codeql_kotlin_embeddable` and `semmle-code`
119+
resource_strip_prefix = (
120+
("../%s/" % repo_name() if repo_name() else "") +
121+
("%s/" % package_name() if package_name() else "") +
122+
v
123+
),
124+
resources = [
125+
":resources-%s" % v,
126+
],
127+
visibility = ["//visibility:public"],
128+
deps = [
129+
"@kotlin-compiler%s-%s" % (
130+
"-embeddable" if _for_embeddable else "",
131+
v,
132+
),
133+
"@kotlin-stdlib-%s" % v,
134+
],
135+
),
136+
# if in main repository, alias the embeddable versions from the modified @codeql_kotlin_embeddable repo
137+
alias(
138+
name = "%s-embeddable-%s" % (_common_extractor_name_prefix, v),
139+
actual = "@codeql_kotlin_embeddable//:%s-embeddable-%s" % (_common_extractor_name_prefix, v),
140+
visibility = ["//visibility:public"],
141+
) if not _for_embeddable else None,
142+
)
143+
for v in VERSIONS
144+
]
145+
146+
(
147+
genrule(
148+
name = "generated-dbscheme",
149+
srcs = ["@codeql//java:dbscheme"],
150+
outs = ["KotlinExtractorDbScheme.kt"],
151+
cmd = "$(execpath :generate_dbscheme) $< $@",
152+
tools = [":generate_dbscheme"],
153+
visibility = ["@codeql_kotlin_embeddable//:__pkg__"],
154+
),
155+
[
156+
alias(
157+
name = n,
158+
actual = "//java/kotlin-extractor/defaults:%s" % n,
159+
visibility = ["//visibility:public"],
160+
)
161+
for n in (
162+
"%s-standalone" % _common_extractor_name_prefix,
163+
"%s-embeddable" % _common_extractor_name_prefix,
164+
_common_extractor_name_prefix,
165+
)
166+
],
167+
alias(
168+
name = "kotlin-extractor",
169+
actual = _common_extractor_name_prefix,
170+
visibility = ["//visibility:public"],
171+
),
172+
filegroup(
173+
name = "many",
174+
srcs = ["%s-%s-%s" % (
175+
_common_extractor_name_prefix,
176+
variant,
177+
version,
178+
) for variant in ("standalone", "embeddable") for version in VERSIONS],
179+
visibility = ["//visibility:public"],
180+
),
181+
sh_binary(
182+
name = "print-default-version",
183+
srcs = ["//java/kotlin-extractor/defaults:default-version-printer"],
184+
),
185+
) if not _for_embeddable else None
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python3
2+
3+
import subprocess
4+
import re
5+
import shutil
6+
7+
kotlinc = shutil.which('kotlinc')
8+
if kotlinc is None:
9+
raise Exception("kotlinc not found")
10+
res = subprocess.run([kotlinc, "-version"], text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
11+
if res.returncode != 0:
12+
raise Exception(f"kotlinc -version failed: {res.stderr}")
13+
m = re.match(r'.* kotlinc-jvm ([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z][a-zA-Z0-9]*)?) .*', res.stderr)
14+
if m is None:
15+
raise Exception(f'Cannot detect version of kotlinc (got {res.stderr})')
16+
print(m[1])

0 commit comments

Comments
 (0)