Summary: Now that the buck java flavour is fully deployed, the genrule-based integrations for java can be removed. We also remove the combined (clang+java) integration as this will be reimplemented using flavours in the future. Also, remove a bunch of deprecated arguments linked to these integrations. Reviewed By: jvillard Differential Revision: D26104384 fbshipit-source-id: 6b0059407master
parent
e04f0a0ffa
commit
7e4dc9477e
@ -1,185 +0,0 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
module F = Format
|
||||
module L = Logging
|
||||
|
||||
(* example build report json output
|
||||
[
|
||||
{
|
||||
"success" : true,
|
||||
"results" : {
|
||||
"//annotations:annotations_infer" : {
|
||||
"success" : true,
|
||||
"type" : "BUILT_LOCALLY",
|
||||
"output" : "buck-out/gen/annotations/annotations_infer/infer_out"
|
||||
},
|
||||
"//module2:module2_infer" : {
|
||||
"success" : true,
|
||||
"type" : "BUILT_LOCALLY",
|
||||
"output" : "buck-out/gen/module2/module2_infer/infer_out"
|
||||
},
|
||||
"//module1:module1_infer" : {
|
||||
"success" : true,
|
||||
"type" : "BUILT_LOCALLY",
|
||||
"output" : "buck-out/gen/module1/module1_infer/infer_out"
|
||||
},
|
||||
"//module3:module1_infer" : {
|
||||
"success" : "SUCCESS",
|
||||
"type" : "BUILT_LOCALLY",
|
||||
"outputs" : {
|
||||
"DEFAULT" : [ "buck-out/gen/module1/module3_infer/infer_out" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"failures" : { }
|
||||
}%
|
||||
]
|
||||
*)
|
||||
|
||||
(** Read the build report json file buck produced, and parse into a list of pairs
|
||||
[(target, output-path)]. NB contrary to what buck documentation says, the output path is always
|
||||
present even when the target is locally cached. *)
|
||||
let read_and_parse_report build_report =
|
||||
let get_json_field fieldname = function
|
||||
| `Assoc fields ->
|
||||
List.Assoc.find fields ~equal:String.equal fieldname
|
||||
| _ ->
|
||||
None
|
||||
in
|
||||
let parse_target (target, json) =
|
||||
let path_opt =
|
||||
match get_json_field "output" json with
|
||||
| Some (`String str) ->
|
||||
Some str
|
||||
| _ -> (
|
||||
match get_json_field "outputs" json |> Option.bind ~f:(get_json_field "DEFAULT") with
|
||||
| Some (`List [`String str]) ->
|
||||
Some str
|
||||
| _ ->
|
||||
None )
|
||||
in
|
||||
match path_opt with
|
||||
| None ->
|
||||
L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ;
|
||||
None
|
||||
| Some path ->
|
||||
Some (target, path)
|
||||
in
|
||||
let parse_results = function
|
||||
| `Assoc results ->
|
||||
(* NB this will simply skip unparseable targets *)
|
||||
List.filter_map results ~f:parse_target |> Option.some
|
||||
| _ ->
|
||||
None
|
||||
in
|
||||
Yojson.Basic.from_file build_report |> get_json_field "results" |> Option.bind ~f:parse_results
|
||||
|
||||
|
||||
(** Function for processing paths in a buck build report and generating an [infer-deps.txt] file.
|
||||
Given a pair [(buck_target, output_path)],
|
||||
|
||||
- if [output_path] contains a capture DB, then generate the appropriate deps line;
|
||||
- if [output_path] contains an [infer-deps.txt] file, expand and inline it;
|
||||
- if [output_path] is a dummy target used in the combined genrule integration for clang targets,
|
||||
read its contents, parse them as an output directory path and apply the above two tests to
|
||||
that *)
|
||||
let expand_target acc (target, target_path) =
|
||||
let expand_dir acc (target, target_path) =
|
||||
(* invariant: [target_path] is absolute *)
|
||||
let db_file = ResultsDirEntryName.get_path ~results_dir:target_path CaptureDB in
|
||||
match Sys.file_exists db_file with
|
||||
| `Yes ->
|
||||
(* there is a capture DB at this path, so terminate expansion and generate deps line *)
|
||||
let line = Printf.sprintf "%s\t-\t%s" target target_path in
|
||||
line :: acc
|
||||
| `No | `Unknown -> (
|
||||
(* no capture DB was found, so look for, and inline, an [infer-deps.txt] file *)
|
||||
let infer_deps =
|
||||
ResultsDirEntryName.get_path ~results_dir:target_path CaptureDependencies
|
||||
in
|
||||
match Sys.file_exists infer_deps with
|
||||
| `Yes ->
|
||||
Utils.with_file_in infer_deps
|
||||
~f:(In_channel.fold_lines ~init:acc ~f:(fun acc line -> line :: acc))
|
||||
| `No | `Unknown ->
|
||||
L.internal_error "No capture DB or infer-deps file in %s@." target_path ;
|
||||
acc )
|
||||
in
|
||||
let target_path =
|
||||
if Filename.is_absolute target_path then target_path else Config.project_root ^/ target_path
|
||||
in
|
||||
match Sys.is_directory target_path with
|
||||
| `Yes ->
|
||||
(* output path is directory, so should contain either a capture DB or an [infer-deps.txt] file *)
|
||||
expand_dir acc (target, target_path)
|
||||
| `No | `Unknown -> (
|
||||
(* output path is not a directory, so assume it's an intermediate genrule output containing the
|
||||
output path of the underlying capture target *)
|
||||
match Utils.read_file target_path with
|
||||
| Ok [new_target_path] ->
|
||||
expand_dir acc (target, new_target_path)
|
||||
| Ok _ ->
|
||||
L.internal_error "Couldn't parse intermediate deps file %s@." target_path ;
|
||||
acc
|
||||
| Error error ->
|
||||
L.internal_error "Error %s@\nCouldn't read intermediate deps file %s@." error target_path ;
|
||||
acc )
|
||||
|
||||
|
||||
let infer_deps_of_build_report build_report =
|
||||
match read_and_parse_report build_report with
|
||||
| None ->
|
||||
L.die InternalError "Couldn't parse buck build report: %s@." build_report
|
||||
| Some target_path_list ->
|
||||
let infer_deps_lines =
|
||||
List.fold target_path_list ~init:[] ~f:expand_target
|
||||
|> List.dedup_and_sort ~compare:String.compare
|
||||
in
|
||||
let infer_deps = ResultsDir.get_path CaptureDependencies in
|
||||
Utils.with_file_out infer_deps ~f:(fun out_channel ->
|
||||
Out_channel.output_lines out_channel infer_deps_lines )
|
||||
|
||||
|
||||
let run_buck_capture cmd =
|
||||
let path_var = "PATH" in
|
||||
let new_path =
|
||||
Sys.getenv path_var
|
||||
|> Option.value_map ~default:Config.bin_dir ~f:(fun old_path -> Config.bin_dir ^ ":" ^ old_path)
|
||||
in
|
||||
let extend_env = [(path_var, new_path)] in
|
||||
Buck.wrap_buck_call ~extend_env ~label:"build" cmd |> ignore
|
||||
|
||||
|
||||
let capture buck_mode build_cmd =
|
||||
let prog, buck_cmd = (List.hd_exn build_cmd, List.tl_exn build_cmd) in
|
||||
L.progress "Querying buck for genrule capture targets...@." ;
|
||||
let time0 = Mtime_clock.counter () in
|
||||
let command, args, targets = Buck.parse_command_and_targets buck_mode buck_cmd in
|
||||
L.progress "Found %d genrule capture targets in %a.@." (List.length targets) Mtime.Span.pp
|
||||
(Mtime_clock.count time0) ;
|
||||
let all_args = List.rev_append args targets in
|
||||
let build_report_file =
|
||||
Filename.temp_file ~in_dir:(ResultsDir.get_path Temporary) "buck_build_report" ".json"
|
||||
in
|
||||
let updated_buck_cmd =
|
||||
(* make buck tell us where in buck-out are the capture directories for merging *)
|
||||
(prog :: command :: "--build-report" :: build_report_file :: Buck.config buck_mode)
|
||||
@ Config.buck_build_args_no_inline
|
||||
@ Buck.store_args_in_file ~identifier:"genrule_build" all_args
|
||||
in
|
||||
L.(debug Capture Quiet)
|
||||
"Processed buck command '%a'@." (Pp.seq F.pp_print_string) updated_buck_cmd ;
|
||||
if List.is_empty targets then L.external_warning "WARNING: found no buck targets to analyze.@."
|
||||
else
|
||||
let time0 = Mtime_clock.counter () in
|
||||
run_buck_capture updated_buck_cmd ;
|
||||
infer_deps_of_build_report build_report_file ;
|
||||
L.progress "Genrule capture took %a.@." Mtime.Span.pp (Mtime_clock.count time0) ;
|
||||
ResultsDir.RunState.set_merge_capture true ;
|
||||
()
|
@ -1,14 +0,0 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
|
||||
val infer_deps_of_build_report : string -> unit
|
||||
(** parse a buck build report and construct resulting [infer-deps.txt] *)
|
||||
|
||||
val capture : BuckMode.t -> string list -> unit
|
||||
(** do genrule capture with the given buck command line *)
|
@ -1 +0,0 @@
|
||||
../../../../.buck-java8
|
@ -1,2 +0,0 @@
|
||||
[buildfile]
|
||||
includes = //DEFS
|
@ -1,91 +0,0 @@
|
||||
import os
|
||||
|
||||
original_cxx_library = cxx_library
|
||||
original_java_library = java_library
|
||||
|
||||
infer_clang_flavor = "infer-capture-all"
|
||||
|
||||
def _cxx_infer_capture_genrule(name):
|
||||
cmd = "echo $(location :{}#{}) > $OUT".format(name, infer_clang_flavor)
|
||||
|
||||
genrule(
|
||||
name = name + "_infer",
|
||||
out = "dummy_out",
|
||||
cmd = cmd,
|
||||
)
|
||||
|
||||
def cxx_library(name, **kwargs):
|
||||
_cxx_infer_capture_genrule(name)
|
||||
new_kwargs = dict(kwargs, labels=kwargs.get("labels", []) + ["infer_enabled"])
|
||||
|
||||
original_cxx_library(
|
||||
name=name,
|
||||
**new_kwargs
|
||||
)
|
||||
|
||||
|
||||
def _get_project_root():
|
||||
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/buck_combined"
|
||||
|
||||
def _infer_capture_genrule(
|
||||
name,
|
||||
srcs
|
||||
):
|
||||
|
||||
args = [
|
||||
"--jobs",
|
||||
"1",
|
||||
"--genrule-mode",
|
||||
"--quiet",
|
||||
"--no-progress-bar",
|
||||
"--results-dir",
|
||||
"$OUT",
|
||||
"--sourcepath",
|
||||
"$SRCDIR",
|
||||
"--project-root",
|
||||
_get_project_root(),
|
||||
"--classpath",
|
||||
"$(classpath :{})".format(name),
|
||||
"--generated-classes",
|
||||
"$(location :{})".format(name),
|
||||
"capture",
|
||||
]
|
||||
|
||||
args_file = os.path.join("$TMP", "args.txt")
|
||||
subcommands = [
|
||||
"echo {} >> {}".format(arg, args_file)
|
||||
for arg in args
|
||||
] + [
|
||||
"infer @" + args_file
|
||||
]
|
||||
|
||||
genrule(
|
||||
name = name + "_infer",
|
||||
srcs = srcs,
|
||||
cmd = " && ".join(subcommands),
|
||||
out = "infer_out",
|
||||
labels = ["infer_genrule"],
|
||||
)
|
||||
|
||||
|
||||
def _make_infer_capture_genrule(name, kwargs):
|
||||
java_sources = [
|
||||
f
|
||||
for f in kwargs.get("srcs", [])
|
||||
if f.endswith(".java")
|
||||
]
|
||||
|
||||
if java_sources != []:
|
||||
_infer_capture_genrule(name, java_sources)
|
||||
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def java_library(name, **kwargs):
|
||||
new_kwargs = _make_infer_capture_genrule(name, kwargs)
|
||||
|
||||
original_java_library(
|
||||
name=name,
|
||||
**new_kwargs
|
||||
)
|
@ -1,26 +0,0 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
TESTS_DIR = ../..
|
||||
ROOT_DIR = $(TESTS_DIR)/../..
|
||||
|
||||
BUCK_TARGET = //clang:hello //java:hello
|
||||
SOURCES = clang/hello.c clang/hello2.c
|
||||
OBJECTS = buck-out/gen/clang/hello\#compile-hello.c.o1f717d69,default/hello.c.o
|
||||
INFER_OPTIONS = --report-custom-error --developer-mode --no-linters --buck-combined
|
||||
INFERPRINT_OPTIONS = --issues-tests
|
||||
CLEAN_EXTRA = buck-out
|
||||
|
||||
include $(TESTS_DIR)/infer.make
|
||||
|
||||
$(OBJECTS): $(SOURCES)
|
||||
$(QUIET)$(call silent_on_success,Compiling Buck flavors tests,\
|
||||
$(BUCK) build --no-cache $(BUCK_TARGET))
|
||||
|
||||
infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(MAKEFILE_LIST)
|
||||
$(QUIET)$(BUCK) clean
|
||||
$(call silent_on_success,Testing infer-run Buck combined genrule integration,\
|
||||
$(INFER_BIN) $(INFER_OPTIONS) run --results-dir $(CURDIR)/infer-out -- \
|
||||
$(BUCK) build --no-cache $(BUCK_TARGET))
|
@ -1,6 +0,0 @@
|
||||
cxx_library(
|
||||
name = 'hello',
|
||||
srcs = [
|
||||
'hello.c', 'hello2.c',
|
||||
],
|
||||
)
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void test() {
|
||||
int* s = NULL;
|
||||
*s = 42;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void test2() {
|
||||
int* s = NULL;
|
||||
*s = 42;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
clang/hello.c, test, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test()]
|
||||
clang/hello2.c, test2, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test2()]
|
||||
java/NullDeref.java, NullDeref.callToStringWithNullBad():java.lang.String, 1, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure callToStringWithNullBad(),start of procedure myToString(...),Skipping toString(): unknown method]
|
@ -1,6 +0,0 @@
|
||||
java_library(
|
||||
name='hello',
|
||||
srcs=glob(["*.java"]),
|
||||
deps=[],
|
||||
visibility=['PUBLIC'],
|
||||
)
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
public class NullDeref {
|
||||
private static String myToString(Object foo) {
|
||||
return foo.toString();
|
||||
}
|
||||
|
||||
public String callToStringWithNullBad() {
|
||||
return myToString(null);
|
||||
}
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
|
||||
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]
|
||||
module2/Class2.java, buck_java_flavor.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
|
||||
module2/Class2.java, buck_java_flavor.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]
|
||||
|
@ -1 +0,0 @@
|
||||
../../../../.buck-java8
|
@ -1,9 +0,0 @@
|
||||
[buildfile]
|
||||
includes = //DEFS
|
||||
|
||||
[project]
|
||||
ignore = .git, .ml, .mli
|
||||
|
||||
[java]
|
||||
source_level = 8
|
||||
target_level = 8
|
@ -1,78 +0,0 @@
|
||||
import os
|
||||
|
||||
original_java_library = java_library
|
||||
original_android_library = android_library
|
||||
|
||||
def _get_project_root():
|
||||
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/genrulecapture"
|
||||
|
||||
def _infer_capture_genrule(
|
||||
name,
|
||||
srcs
|
||||
):
|
||||
|
||||
args = [
|
||||
"--jobs",
|
||||
"1",
|
||||
"--genrule-mode",
|
||||
"--quiet",
|
||||
"--no-progress-bar",
|
||||
"--results-dir",
|
||||
"$OUT",
|
||||
"--sourcepath",
|
||||
"$SRCDIR",
|
||||
"--project-root",
|
||||
_get_project_root(),
|
||||
"--classpath",
|
||||
"$(classpath :{})".format(name),
|
||||
"--generated-classes",
|
||||
"$(location :{})".format(name),
|
||||
"capture",
|
||||
]
|
||||
|
||||
args_file = os.path.join("$TMP", "args.txt")
|
||||
subcommands = [
|
||||
"echo {} >> {}".format(arg, args_file)
|
||||
for arg in args
|
||||
] + [
|
||||
"infer @" + args_file
|
||||
]
|
||||
|
||||
genrule(
|
||||
name = name + "_infer",
|
||||
srcs = srcs,
|
||||
cmd = " && ".join(subcommands),
|
||||
out = "infer_out",
|
||||
labels = ["infer_genrule"],
|
||||
)
|
||||
|
||||
|
||||
def _make_infer_capture_genrule(name, kwargs):
|
||||
java_sources = [
|
||||
f
|
||||
for f in kwargs.get("srcs", [])
|
||||
if f.endswith(".java")
|
||||
]
|
||||
|
||||
if java_sources != []:
|
||||
_infer_capture_genrule(name, java_sources)
|
||||
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def java_library(name, **kwargs):
|
||||
new_kwargs = _make_infer_capture_genrule(name, kwargs)
|
||||
|
||||
original_java_library(
|
||||
name=name,
|
||||
**new_kwargs
|
||||
)
|
||||
|
||||
def android_library(name, **kwargs):
|
||||
new_kwargs = _make_infer_capture_genrule(name, kwargs)
|
||||
|
||||
original_android_library(
|
||||
name=name,
|
||||
**new_kwargs
|
||||
)
|
@ -1,21 +0,0 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
TESTS_DIR = ../..
|
||||
|
||||
BUCK_TARGET = //module2:module2
|
||||
CLEAN_EXTRA = buck-out
|
||||
SOURCES = $(shell find . -name '*.java')
|
||||
|
||||
INFERPRINT_OPTIONS = --issues-tests
|
||||
INFER_OPTIONS = --buck-java --debug-exceptions
|
||||
|
||||
include $(TESTS_DIR)/infer.make
|
||||
|
||||
$(INFER_OUT)/report.json: $(MAKEFILE_LIST) $(SOURCES)
|
||||
$(QUIET)$(BUCK) clean
|
||||
$(call silent_on_success,Testing genrule capture integration in $(TEST_REL_DIR),\
|
||||
$(INFER_BIN) --results-dir $(@D) $(INFER_OPTIONS) -- \
|
||||
$(BUCK) build --no-cache $(BUCK_TARGET))
|
@ -1,7 +0,0 @@
|
||||
java_library(
|
||||
name='annotations',
|
||||
srcs=['ThreadSafe.java'],
|
||||
visibility=[
|
||||
'PUBLIC'
|
||||
],
|
||||
)
|
@ -1,9 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package genrulecapture.annotations;
|
||||
|
||||
public @interface ThreadSafe {}
|
@ -1,2 +0,0 @@
|
||||
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
|
||||
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]
|
@ -1,10 +0,0 @@
|
||||
java_library(
|
||||
name='module1',
|
||||
srcs=glob(["*.java"]),
|
||||
deps=[
|
||||
'//annotations:annotations',
|
||||
],
|
||||
visibility=[
|
||||
'PUBLIC'
|
||||
],
|
||||
)
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package genrulecapture.module1;
|
||||
|
||||
public class Class1 {
|
||||
int x;
|
||||
|
||||
public void set(int d) {
|
||||
x = d;
|
||||
}
|
||||
|
||||
public int get() {
|
||||
return x;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
java_library(
|
||||
name='module2',
|
||||
srcs=glob(["*.java"]),
|
||||
deps=[
|
||||
'//module1:module1',
|
||||
'//annotations:annotations',
|
||||
'//module3:module3',
|
||||
]
|
||||
)
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package genrulecapture.module2;
|
||||
|
||||
import genrulecapture.annotations.ThreadSafe;
|
||||
import genrulecapture.module1.Class1;
|
||||
|
||||
@ThreadSafe
|
||||
public class Class2 {
|
||||
Class1 c;
|
||||
|
||||
void set(int x) {
|
||||
c.set(x);
|
||||
}
|
||||
|
||||
int get() {
|
||||
return c.get();
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
cxx_library(
|
||||
name = 'module3',
|
||||
visibility = [
|
||||
'PUBLIC',
|
||||
],
|
||||
srcs = [
|
||||
'some_c_code.c',
|
||||
],
|
||||
)
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void some_c_func() {
|
||||
int* s = NULL;
|
||||
*s = 42;
|
||||
}
|
Loading…
Reference in new issue