parent
10bcf894dc
commit
09fba4a0b5
@ -1,9 +0,0 @@
|
|||||||
[buildfile]
|
|
||||||
includes = //DEFS
|
|
||||||
|
|
||||||
[project]
|
|
||||||
ignore = .git, .ml, .mli
|
|
||||||
|
|
||||||
[java]
|
|
||||||
source_level = 8
|
|
||||||
target_level = 8
|
|
@ -1,47 +0,0 @@
|
|||||||
---
|
|
||||||
AccessModifierOffset: -1
|
|
||||||
AlignEscapedNewlinesLeft: true
|
|
||||||
AlignTrailingComments: false
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
|
||||||
AlwaysBreakTemplateDeclarations: true
|
|
||||||
BinPackArguments: false
|
|
||||||
BinPackParameters: false
|
|
||||||
BreakBeforeBinaryOperators: false
|
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
ColumnLimit: 80
|
|
||||||
CommentPragmas: '^@atd'
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
|
||||||
ConstructorInitializerIndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
ExperimentalAutoDetectBinPacking: true
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentFunctionDeclarationAfterType: false
|
|
||||||
IndentWidth: 2
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: None
|
|
||||||
ObjCSpaceBeforeProtocolList: false
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 10
|
|
||||||
PenaltyBreakComment: 1000
|
|
||||||
PenaltyBreakFirstLessLess: 20
|
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyExcessCharacter: 1000000
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 200
|
|
||||||
PointerAlignment: Left
|
|
||||||
SortIncludes: false
|
|
||||||
SpaceAfterControlStatementKeyword: true
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 1
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
Standard: Cpp11
|
|
||||||
TabWidth: 8
|
|
||||||
UseTab: Never
|
|
||||||
...
|
|
@ -1 +0,0 @@
|
|||||||
website/** linguist-documentation
|
|
@ -1,49 +0,0 @@
|
|||||||
name: Deploy
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "master"
|
|
||||||
paths:
|
|
||||||
- "website/**"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
if: github.repository == 'facebook/infer'
|
|
||||||
|
|
||||||
env:
|
|
||||||
working-directory: website
|
|
||||||
node-version: 14.x
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ env.node-version }}
|
|
||||||
uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: ${{ env.node-version }}
|
|
||||||
|
|
||||||
- name: Get yarn cache directory
|
|
||||||
id: yarn
|
|
||||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
|
||||||
|
|
||||||
- name: Restore yarn cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ${{ steps.yarn.outputs.dir }}
|
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('website/yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Install packages
|
|
||||||
working-directory: ${{ env.working-directory }}
|
|
||||||
run: yarn --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
working-directory: ${{ env.working-directory }}
|
|
||||||
run: |
|
|
||||||
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
|
|
||||||
git config --global user.name "${GITHUB_ACTOR}"
|
|
||||||
echo "machine github.com login ${GITHUB_ACTOR} password ${{ secrets.GITHUB_TOKEN }}" > ~/.netrc
|
|
||||||
GIT_USER=${GITHUB_ACTOR} yarn deploy
|
|
@ -1,189 +0,0 @@
|
|||||||
name: Install
|
|
||||||
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
create-release:
|
|
||||||
name: Create release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
upload-url: ${{ steps.create-release.outputs.upload_url }}
|
|
||||||
steps:
|
|
||||||
- name: Create Release
|
|
||||||
id: create-release
|
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: Infer version ${{ github.ref }}
|
|
||||||
draft: true
|
|
||||||
prerelease: false
|
|
||||||
body: |
|
|
||||||
BEFORE PUBLISHING CHECKLIST:
|
|
||||||
1. From the commit tagged on GitHub, create and push a new version of the website with "make new-website-version" (see website/README.md for how to test).
|
|
||||||
2. Consider deleting the oldest documentation version (see Docusaurus 2 documentation for details).
|
|
||||||
3. Fill in the changelog below to go on GitHub.
|
|
||||||
4. Download the release tarballs and test that the binaries works.
|
|
||||||
5. Fill in the shasums by running the command at the end of the release text.
|
|
||||||
--- PUBLISH GITHUB RELEASE HERE ---
|
|
||||||
6. At some point, copy the GitHub changelog to Changelog.md in the repo.
|
|
||||||
7. Tweet.
|
|
||||||
--- DELETE EVERYTHING ABOVE THIS LINE ---
|
|
||||||
|
|
||||||
This is a binary release of Infer for Linux and MacOS. To use it follow these [instructions](http://fbinfer.com/docs/getting-started).
|
|
||||||
|
|
||||||
- new feature 1
|
|
||||||
- new feature 2
|
|
||||||
|
|
||||||
The sha256 checksums of the tarballs are:
|
|
||||||
```
|
|
||||||
$ shasum -a 256 infer-*-v<VERSION GOES HERE>.tar.xz
|
|
||||||
DOWNLOAD BOTH TARBALLS AND PUT RESULT OF THE ABOVE COMMAND HERE BEFORE PUBLISHING
|
|
||||||
```
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: Build Infer
|
|
||||||
needs: create-release
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- macOS-latest
|
|
||||||
- ubuntu-latest
|
|
||||||
ocaml-version:
|
|
||||||
- 4.12.0
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Install Required Apt Packages for Ubuntu
|
|
||||||
run: |
|
|
||||||
sudo apt install libmpfr-dev libsqlite3-dev ninja-build
|
|
||||||
sudo apt clean
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
|
|
||||||
- name: Install Required Brew Packages for MacOS
|
|
||||||
run: brew install automake jq ninja pkg-config lzlib
|
|
||||||
if: runner.os == 'macOS'
|
|
||||||
|
|
||||||
- name: Compute hash of clang installation
|
|
||||||
id: clang-hash
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=value::$(./facebook-clang-plugins/clang/setup.sh --clang-hash)"
|
|
||||||
|
|
||||||
- name: Attempt to get clang from the cache
|
|
||||||
id: cache-clang
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: facebook-clang-plugins/clang/install
|
|
||||||
key: clang-${{ runner.os }}-${{ steps.clang-hash.outputs.value }}
|
|
||||||
|
|
||||||
- name: Record that the clang cache was hit
|
|
||||||
if: steps.cache-clang.outputs.cache-hit == 'true'
|
|
||||||
run: ./facebook-clang-plugins/clang/setup.sh --only-record-install
|
|
||||||
|
|
||||||
- name: Build clang on cache misses
|
|
||||||
if: steps.cache-clang.outputs.cache-hit != 'true'
|
|
||||||
run: |
|
|
||||||
./facebook-clang-plugins/clang/src/prepare_clang_src.sh
|
|
||||||
./facebook-clang-plugins/clang/setup.sh --ninja --sequential-link
|
|
||||||
|
|
||||||
- name: Attempt to get opam tree from the cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ~/.opam
|
|
||||||
key: opam-${{ runner.os }}-${{ hashFiles('opam/infer.opam.locked') }}
|
|
||||||
|
|
||||||
- name: Use OCaml ${{ matrix.ocaml-version }}
|
|
||||||
uses: avsm/setup-ocaml@v1
|
|
||||||
with:
|
|
||||||
ocaml-version: ${{ matrix.ocaml-version }}
|
|
||||||
|
|
||||||
- run: ./build-infer.sh --yes all
|
|
||||||
|
|
||||||
- run: make install BUILD_MODE=opt
|
|
||||||
if: runner.os == 'macOS'
|
|
||||||
|
|
||||||
- run: |
|
|
||||||
sudo make install BUILD_MODE=opt
|
|
||||||
# restore permissions after root build
|
|
||||||
sudo chown $USER: -R .
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
|
|
||||||
- name: Test infer
|
|
||||||
run: |
|
|
||||||
eval $(opam env)
|
|
||||||
|
|
||||||
{
|
|
||||||
echo 'class FailingTest {'
|
|
||||||
echo ' String mayReturnNull(int i) {'
|
|
||||||
echo ' if (i > 0) {'
|
|
||||||
echo ' return "Hello, Infer!";'
|
|
||||||
echo ' }'
|
|
||||||
echo ' return null;'
|
|
||||||
echo ' }'
|
|
||||||
echo ' int mayCauseNPE() {'
|
|
||||||
echo ' String s = mayReturnNull(0);'
|
|
||||||
echo ' return s.length();'
|
|
||||||
echo ' }'
|
|
||||||
echo '}'
|
|
||||||
} > FailingTest.java
|
|
||||||
|
|
||||||
{
|
|
||||||
echo " class PassingTest {"
|
|
||||||
echo " String mayReturnNull(int i) {"
|
|
||||||
echo " if (i > 0) {"
|
|
||||||
echo ' return "Hello, Infer!";'
|
|
||||||
echo " }"
|
|
||||||
echo " return null;"
|
|
||||||
echo " }"
|
|
||||||
echo " int mayCauseNPE() {"
|
|
||||||
echo " String s = mayReturnNull(0);"
|
|
||||||
echo " return s == null ? 0 : s.length();"
|
|
||||||
echo " }"
|
|
||||||
echo " }"
|
|
||||||
} > PassingTest.java
|
|
||||||
|
|
||||||
# first command should exit with status 2
|
|
||||||
infer --fail-on-issue -P -- javac FailingTest.java || if [[ $? -ne 2 ]]; then exit 1; fi
|
|
||||||
infer --fail-on-issue -P -- javac PassingTest.java
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "#include <stdio.h>"
|
|
||||||
echo "int main()"
|
|
||||||
echo "{ int *s = NULL; *s = 42; return 0; } "
|
|
||||||
} > FailingTest.c
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "#include <stdio.h>"
|
|
||||||
echo "int main()"
|
|
||||||
echo "{ int *s = NULL; if (s != NULL) { *s = 42; } return 0; }"
|
|
||||||
} > PassingTest.c
|
|
||||||
|
|
||||||
# first command should exit with status 2
|
|
||||||
infer --fail-on-issue -P -- clang -c FailingTest.c || if [[ $? -ne 2 ]]; then exit 1; fi
|
|
||||||
infer --fail-on-issue -P -- clang -c PassingTest.c
|
|
||||||
|
|
||||||
- name: Build release tarball
|
|
||||||
id: build-release
|
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
|
||||||
run: |
|
|
||||||
./scripts/create_binary_release.sh "$(echo '${{ github.ref }}' | rev | cut -d / -f 1 | rev)"
|
|
||||||
|
|
||||||
- name: Upload Release Asset
|
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ needs.create-release.outputs.upload-url }}
|
|
||||||
asset_path: ${{ steps.build-release.outputs.tarball-path }}
|
|
||||||
asset_name: ${{ steps.build-release.outputs.tarball-path }}
|
|
||||||
asset_content_type: application/x-gtar
|
|
@ -1,216 +0,0 @@
|
|||||||
# Generated files #
|
|
||||||
###################
|
|
||||||
*.pyc
|
|
||||||
*.specs
|
|
||||||
*.cm*
|
|
||||||
*.o
|
|
||||||
*~
|
|
||||||
*.swp
|
|
||||||
*.annot
|
|
||||||
*.class
|
|
||||||
*.log
|
|
||||||
*.orig
|
|
||||||
*.rej
|
|
||||||
.#*
|
|
||||||
|
|
||||||
# generated by build and tests
|
|
||||||
/_build
|
|
||||||
/_build_logs
|
|
||||||
/infer/lib/erlang/infer_parse_transform/_build
|
|
||||||
/infer/tests/codetoanalyze/java/*/codetoanalyze
|
|
||||||
_build_infer
|
|
||||||
*.exp.test*
|
|
||||||
*.dot.test
|
|
||||||
*.test.dot
|
|
||||||
*.test.txt
|
|
||||||
duplicates.txt
|
|
||||||
*.ast.sh
|
|
||||||
*.ast.bdump
|
|
||||||
*.ast.biniou
|
|
||||||
/infer/tests/build_systems/buck_flavors_deterministic/capture_hash-*.sha
|
|
||||||
/infer/tests/build_systems/buck_flavors_diff/src/hello.c
|
|
||||||
/infer/tests/build_systems/buck_clang_test_determinator/diff.mod.test
|
|
||||||
/infer/tests/build_systems/buck_export_changed_functions/diff.mod.test
|
|
||||||
/infer/tests/build_systems/clang_compilation_db_escaped/compile_commands.json
|
|
||||||
/infer/tests/build_systems/clang_compilation_db_relpath/compile_commands.json
|
|
||||||
/infer/tests/build_systems/clang_test_determinator/*.test
|
|
||||||
/infer/tests/build_systems/export_changed_functions/*.test
|
|
||||||
/infer/tests/build_systems/clang_with_MD_flag/hello.d
|
|
||||||
/infer/tests/build_systems/codetoanalyze/mvn/**/target/
|
|
||||||
/infer/tests/build_systems/codetoanalyze/ndk-build/hello_app/libs/
|
|
||||||
/infer/tests/build_systems/codetoanalyze/ndk-build/hello_app/obj/
|
|
||||||
/infer/tests/build_systems/codetoanalyze/path with spaces/
|
|
||||||
/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/_build
|
|
||||||
/infer/tests/build_systems/codetoanalyze/utf8_*n_pwd
|
|
||||||
/infer/tests/build_systems/codetoanalyze/xcodebuild/simple_app/app_built
|
|
||||||
/infer/tests/build_systems/codetoanalyze/xcodebuild/simple_app/build/
|
|
||||||
/infer/tests/build_systems/diff/src
|
|
||||||
/infer/tests/build_systems/diff_*/src
|
|
||||||
/infer/tests/build_systems/differential_*/**/*.class
|
|
||||||
/infer/tests/build_systems/differential_*/**/Diff*.java
|
|
||||||
/infer/tests/build_systems/differential_*/**/Diff*.m
|
|
||||||
/infer/tests/build_systems/fb_differential_*/**/Diff*.java
|
|
||||||
/infer/tests/build_systems/fb_differential_*/**/Diff*.m
|
|
||||||
/infer/tests/build_systems/incremental_analysis_remove_file/src
|
|
||||||
/infer/tests/build_systems/incremental_analysis_cost_change/src
|
|
||||||
/infer/tests/build_systems/incremental_analysis_add_procedure/src
|
|
||||||
/infer/tests/build_systems/java_test_determinator/*.test
|
|
||||||
/infer/tests/build_systems/java_source_parser/*.test
|
|
||||||
/infer/tests/codetoanalyze/dotnet/*/*.json
|
|
||||||
/infer/tests/codetoanalyze/erlang/**/_build
|
|
||||||
/_release
|
|
||||||
/infer-source
|
|
||||||
|
|
||||||
# Docusaurus
|
|
||||||
/website/.docusaurus/
|
|
||||||
/website/node_modules
|
|
||||||
/website/build/
|
|
||||||
|
|
||||||
# generated by oUnit
|
|
||||||
/oUnit-all.cache
|
|
||||||
|
|
||||||
# autoconf-generated stuff
|
|
||||||
/acinclude.m4
|
|
||||||
/aclocal.m4
|
|
||||||
/autom4te.cache
|
|
||||||
/config.status
|
|
||||||
/m4/__GENERATED__*.m4
|
|
||||||
/configure
|
|
||||||
/Makefile.autoconf
|
|
||||||
/.buckversion
|
|
||||||
/.buck-java11
|
|
||||||
/.buckjavaversion
|
|
||||||
/*/.gitignore
|
|
||||||
/*/*/.gitignore
|
|
||||||
|
|
||||||
# IntelliJ files
|
|
||||||
/scripts/.idea/
|
|
||||||
/infer/tests/.idea/dictionaries
|
|
||||||
/infer/tests/.idea/inspectionProfiles
|
|
||||||
/infer/tests/.idea/tasks.xml
|
|
||||||
/infer/tests/.idea/uiDesigner.xml
|
|
||||||
/infer/tests/.idea/workspace.xml
|
|
||||||
/infer/tests/.idea/runConfigurations
|
|
||||||
/infer/tests/.idea/copyright/profiles_settings.xml
|
|
||||||
|
|
||||||
# VS code
|
|
||||||
.vscode/
|
|
||||||
.lsp-buck-out/
|
|
||||||
.lsp.buckd/
|
|
||||||
|
|
||||||
# Eclipse settings files
|
|
||||||
ocaml.prefs
|
|
||||||
/infer/.paths
|
|
||||||
/infer/src/.paths
|
|
||||||
org.eclipse.core.resources.prefs
|
|
||||||
|
|
||||||
# Arcanist
|
|
||||||
/arcanist/.phutil_module_cache
|
|
||||||
|
|
||||||
# MacOS generated files
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Directories and files generated by Infer
|
|
||||||
infer-sources.tar.gz
|
|
||||||
infer-osx-*.tar.xz
|
|
||||||
infer-linux64-*.tar.xz
|
|
||||||
infer-out*
|
|
||||||
|
|
||||||
# Directories generated by buck
|
|
||||||
buck-out/
|
|
||||||
.buckd/
|
|
||||||
|
|
||||||
#other
|
|
||||||
/infer/man/man1/*.1
|
|
||||||
/infer/man/man1/*.1.gz
|
|
||||||
|
|
||||||
/infer/src/base/Version.ml
|
|
||||||
/infer/models/java/models/
|
|
||||||
/infer/models/models.jar
|
|
||||||
/infer/lib/java/models.jar
|
|
||||||
/infer/lib/models.sql
|
|
||||||
/infer/models/java/bootclasspath
|
|
||||||
/infer/models/c/out/
|
|
||||||
/infer/models/cpp/out/
|
|
||||||
/infer/models/objc/out/
|
|
||||||
/infer/lib/specs/c_models
|
|
||||||
/infer/lib/specs/clang_models
|
|
||||||
/infer/lib/specs/cpp_models
|
|
||||||
/infer/lib/specs/objc_models
|
|
||||||
/infer/lib/specs/clean_models
|
|
||||||
/infer/etc/clang_ast.dict
|
|
||||||
/infer/src/toplevel.mlpack
|
|
||||||
|
|
||||||
/external_repo
|
|
||||||
|
|
||||||
# atdgen generated files
|
|
||||||
/infer/src/atd/*_j.ml
|
|
||||||
/infer/src/atd/*_j.mli
|
|
||||||
/infer/src/atd/*_t.ml
|
|
||||||
/infer/src/atd/*_t.mli
|
|
||||||
/infer/src/atd/clang_*.ml
|
|
||||||
/infer/src/atd/clang_*.mli
|
|
||||||
|
|
||||||
# intelliJ files
|
|
||||||
/infer/src/backend/.projectSettings
|
|
||||||
|
|
||||||
/infer/annotations/annot_classes/
|
|
||||||
/infer/annotations/annotations.jar
|
|
||||||
/infer/annotations/annotations-src.jar
|
|
||||||
infer/src/.project
|
|
||||||
/dependencies/ocamldot/ocamldot
|
|
||||||
/dependencies/ocamldot/ocamldot.ml
|
|
||||||
/infer/src/mod_dep.dot
|
|
||||||
/infer/src/mod_dep.pdf
|
|
||||||
|
|
||||||
# generated by Maven
|
|
||||||
/infer/annotations/target
|
|
||||||
|
|
||||||
# generated by Erlang/Rebar3
|
|
||||||
*.beam
|
|
||||||
*.plt
|
|
||||||
*.swo
|
|
||||||
.erlang.cookie
|
|
||||||
.eunit
|
|
||||||
.rebar
|
|
||||||
.rebar3
|
|
||||||
ebin
|
|
||||||
erl_crash.dump
|
|
||||||
rebar.lock
|
|
||||||
rebar3.crashdump
|
|
||||||
|
|
||||||
|
|
||||||
# dune
|
|
||||||
/infer/_build
|
|
||||||
/infer/dune-workspace
|
|
||||||
/infer/src/dune.common
|
|
||||||
/infer/src/dune
|
|
||||||
/infer/src/al/dune
|
|
||||||
/infer/src/clang/dune
|
|
||||||
/infer/src/integration/dune
|
|
||||||
/infer/src/java/dune
|
|
||||||
/infer/src/nullsafe/unit/dune
|
|
||||||
/infer/src/opensource/dune
|
|
||||||
/infer/src/unit/dune
|
|
||||||
.merlin
|
|
||||||
|
|
||||||
# generated when looking for dead code
|
|
||||||
/infer/src/deadcode/.depend
|
|
||||||
/infer/src/deadcode/all_ml_files
|
|
||||||
/infer/src/deadcode/all_ml_files_copied
|
|
||||||
/infer/src/deadcode/all_mli_files
|
|
||||||
/infer/src/deadcode/all_mli_files_copied
|
|
||||||
/infer/src/deadcode/*.ml
|
|
||||||
/infer/src/deadcode/*.mli
|
|
||||||
/infer/src/deadcode/dune
|
|
||||||
_opam
|
|
||||||
_coverage
|
|
||||||
|
|
||||||
# facebook-clang-plugins
|
|
||||||
/facebook-clang-plugins/clang-ocaml/.depend
|
|
||||||
/facebook-clang-plugins/clang-ocaml/build
|
|
||||||
/facebook-clang-plugins/clang/install
|
|
||||||
/facebook-clang-plugins/clang/installed.version
|
|
||||||
/facebook-clang-plugins/clang/src/download
|
|
||||||
/facebook-clang-plugins/libtooling/build
|
|
||||||
/facebook-clang-plugins/xcode/*
|
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"force-delete-results-dir": true,
|
|
||||||
"siof-safe-methods": ["getGlobalNonPODAllowListed", "allow_listed::getGlobalNonPOD",
|
|
||||||
"allow_listed::TemplatedObject::getGlobalNonPOD"],
|
|
||||||
"skip-translation": [
|
|
||||||
{
|
|
||||||
"language": "Java",
|
|
||||||
"source_contains": "_SHOULD_BE_SKIPPED_"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
infer/src/.ocamlformat
|
|
@ -1,230 +0,0 @@
|
|||||||
# Contribution Guidelines
|
|
||||||
|
|
||||||
|
|
||||||
## Reporting Issues
|
|
||||||
|
|
||||||
If you encounter a problem when using infer or if you have any questions, please open a
|
|
||||||
[GitHub issue](https://github.com/facebook/infer/issues/).
|
|
||||||
|
|
||||||
## Hacking on the Code
|
|
||||||
|
|
||||||
We welcome contributions via [pull requests on GitHub](https://github.com/facebook/infer/pulls).
|
|
||||||
|
|
||||||
### Development Dependencies
|
|
||||||
|
|
||||||
You'll want to install a few more dependencies to comfortably hack on the infer codebase. Simply
|
|
||||||
run:
|
|
||||||
```sh
|
|
||||||
make devsetup
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building Infer for Development
|
|
||||||
|
|
||||||
- The default build mode ("dev") makes all build warnings *fatal*. If you want the build to ignore
|
|
||||||
warnings, for example to be able to test an infer executable before polishing the code to remove
|
|
||||||
warnings, you can build in "dev-noerror" mode with `make BUILD_MODE=dev-noerror`.
|
|
||||||
|
|
||||||
- Faster edit/build cycle when working on OCaml code inside infer/src/: build inside infer/src/
|
|
||||||
(skips building the models after infer has been built), and build only what is needed for type
|
|
||||||
checking with `make -j -C infer/src check`. You need to have run `make -j` at some point before.
|
|
||||||
|
|
||||||
- Alternatively, if you want to test your changes on a small example, build in bytecode mode:
|
|
||||||
`make -j -C infer/src byte`.
|
|
||||||
|
|
||||||
- In general, `make` commands from the root of the repository make sure that dependencies are in a
|
|
||||||
consistent and up-to-date state (e.g., they rebuild infer and the models before running steps that
|
|
||||||
use infer), while running `make` commands from within subdirectories generally assumes that
|
|
||||||
dependencies are already up-to-date.
|
|
||||||
|
|
||||||
For instance, running `make direct_java_biabduction_test` will rebuild infer and the models if
|
|
||||||
necessary before running the test, but running `make -C infer/tests/codetoanalyze/java/biabduction/ test`
|
|
||||||
will just execute the test.
|
|
||||||
|
|
||||||
|
|
||||||
### Debugging OCaml Code
|
|
||||||
|
|
||||||
- Printf-debug using `Logging.debug_dev`. It comes with a warning so
|
|
||||||
that you don't accidentally push code with calls to `debug_dev` to
|
|
||||||
the repo.
|
|
||||||
|
|
||||||
- Browse the documentation of OCaml modules in your browser with `make doc`
|
|
||||||
|
|
||||||
- When using `ocamldebug`, and in particular when setting break points
|
|
||||||
with `break @ <module> <line>` don't forget that an infer module `M`
|
|
||||||
is in reality called `InferModules__M`, or `InferBase__M`, or
|
|
||||||
... See the html documentation of the OCaml modules from `make doc`
|
|
||||||
if you're unsure of a module name.
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ ledit ocamldebug infer/bin/infer.bc.exe
|
|
||||||
(ocd) break @ InferModules__InferAnalyze 100
|
|
||||||
Breakpoint 1 at 9409684: file backend/InferAnalyze.ml, line 99, characters 18-78
|
|
||||||
```
|
|
||||||
|
|
||||||
- To test the infer OCaml code you can use the OCaml toplevel. To
|
|
||||||
build the OCaml toplevel with the infer modules pre-loaded, run
|
|
||||||
`make toplevel` and follow the instructions.
|
|
||||||
|
|
||||||
To pass infer options to the toplevel, use `INFER_ARGS`, for
|
|
||||||
instance: `INFER_ARGS=--debug^-o^infer-out-foo`.
|
|
||||||
|
|
||||||
Many operations require the results directory and database to be
|
|
||||||
initialized with `ResultsDir.assert_results_dir ""`.
|
|
||||||
|
|
||||||
|
|
||||||
## Contributor License Agreement
|
|
||||||
|
|
||||||
We require contributors to sign our Contributor License Agreement. In
|
|
||||||
order for us to review and merge your code, please sign up at
|
|
||||||
https://code.facebook.com/cla. If you have any questions, please drop
|
|
||||||
us a line at cla@fb.com.
|
|
||||||
|
|
||||||
You are also expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md), so please read that if you are a new contributor.
|
|
||||||
|
|
||||||
Thanks!
|
|
||||||
|
|
||||||
## Coding Style
|
|
||||||
|
|
||||||
### All Languages
|
|
||||||
|
|
||||||
- Indent with spaces, not tabs.
|
|
||||||
|
|
||||||
- Line width limit is 100 characters.
|
|
||||||
|
|
||||||
- In general, follow the style of surrounding code.
|
|
||||||
|
|
||||||
### OCaml
|
|
||||||
|
|
||||||
- The module IStd (infer/src/istd/IStd.ml) is automatically opened in every file. Beware that this
|
|
||||||
can cause weird errors such as:
|
|
||||||
```
|
|
||||||
$ pwd
|
|
||||||
/somewhere/infer/infer/src
|
|
||||||
$ cat base/toto.ml
|
|
||||||
let b = List.mem true [true; false]
|
|
||||||
$ make
|
|
||||||
[...]
|
|
||||||
File "base/toto.ml", line 1, characters 17-21:
|
|
||||||
Error: This variant expression is expected to have type 'a list
|
|
||||||
The constructor true does not belong to type list
|
|
||||||
```
|
|
||||||
|
|
||||||
- All modules open `IStd` using `open! IStd`. This is to make that fact more explicit (there's also
|
|
||||||
the compilation flag mentioned above), and also it helps merlin find the right types. In
|
|
||||||
particular this also opens `Core.Std`.
|
|
||||||
|
|
||||||
- Do not add anything to `IStd` unless you have a compelling reason to do so, for instance if you
|
|
||||||
find some utility function is missing and is not provided by
|
|
||||||
[`Core`](https://ocaml.janestreet.com/ocaml-core/latest/doc/core/).
|
|
||||||
|
|
||||||
- Polymorphic equality is disabled; use type-specific equality instead, even for primitive types
|
|
||||||
(e.g., `Int.equal`). However, if your module uses a lot of polymorphic variants with no arguments
|
|
||||||
you may safely `open PolyVariantEqual`.
|
|
||||||
|
|
||||||
If you try and use polymorphic equality `=` in your code you will get a compilation error, such as:
|
|
||||||
```
|
|
||||||
Error: This expression has type int but an expression was expected of type
|
|
||||||
[ `no_polymorphic_compare ]
|
|
||||||
```
|
|
||||||
|
|
||||||
- Alias and use `module L = Logging` for all your logging needs. Refer to its API in Logging.mli for
|
|
||||||
documentation.
|
|
||||||
|
|
||||||
- Check that your code compiles without warnings with `make -j test_build` (this also runs as part
|
|
||||||
of `make test`).
|
|
||||||
|
|
||||||
- Apart from `IStd` and `PolyVariantEqual`, refrain from globally `open`ing modules. Using
|
|
||||||
local open instead when it improves readability: `let open MyModule in ...`.
|
|
||||||
|
|
||||||
- Avoid the use of module aliases, except for the following commonly-aliased modules. Use
|
|
||||||
module aliases consistently (e.g., do not alias `L` to a module other than `Logging`).
|
|
||||||
```OCaml
|
|
||||||
module CLOpt = CommandLineOption
|
|
||||||
module F = Format
|
|
||||||
module L = Logging
|
|
||||||
module MF = MarkupFormatter
|
|
||||||
```
|
|
||||||
|
|
||||||
- Use `[@@deriving compare]` to write comparison functions whenever possible. Watch out for
|
|
||||||
[this issue](https://github.com/ocaml-ppx/ppx_deriving/issues/116) when writing
|
|
||||||
`type nonrec t = t [@@deriving compare]`.
|
|
||||||
|
|
||||||
- Use `let equal_foo = [%compare.equal : foo]` to write equality functions whenever possible.
|
|
||||||
|
|
||||||
- Use named arguments whenever the purpose of the argument is not immediately obvious. In
|
|
||||||
particular, use named arguments for boolean and integer parameters unless the name of the function
|
|
||||||
mentions them explicitly. Also use named arguments to disambiguate between several arguments of
|
|
||||||
the same type.
|
|
||||||
|
|
||||||
- Use named arguments for functions taken as argument; it is common to name a function argument
|
|
||||||
`f`. For instance: `List.map : 'a list -> f:('a -> 'b) -> 'b list`.
|
|
||||||
|
|
||||||
- In modules defining a type `t`, functions that take an argument of that type should generally have
|
|
||||||
that argument come first, except for for optional arguments: `val f : ?optional:bool -> t -> ...`.
|
|
||||||
|
|
||||||
- Use the `_hum` suffix to flag functions that output human-readable strings.
|
|
||||||
|
|
||||||
- Format code with [ocamlformat](https://github.com/ocaml-ppx/ocamlformat).
|
|
||||||
|
|
||||||
### C/C++/Objective-C
|
|
||||||
|
|
||||||
Follow `clang-format` (see ".clang-format" at the root of the repository).
|
|
||||||
|
|
||||||
## Testing your Changes
|
|
||||||
|
|
||||||
- Make sure infer builds: `make -j test_build`. Refer to the [installation
|
|
||||||
document](https://github.com/facebook/infer/blob/master/INSTALL.md) for details.
|
|
||||||
|
|
||||||
- Run the tests: `make -j 4 test` (adjust 4 to the number of cores available of your machine). The
|
|
||||||
tests (almost) all consist of the same three ingredients:
|
|
||||||
1. Some source code to run infer on.
|
|
||||||
2. An "issues.exp" file where each line represents one item of output of the test. For most tests,
|
|
||||||
one line is one issue reported by infer.
|
|
||||||
3. A `Makefile` that orchestrates the test, for instance running infer on the source code and
|
|
||||||
comparing the results with issues.exp using `diff`.
|
|
||||||
|
|
||||||
- If your changes modified some of the expected outputs and if the changes make sense, you can
|
|
||||||
update the expected test results by running `make test-replace`.
|
|
||||||
|
|
||||||
- If relevant, add a test for your change.
|
|
||||||
|
|
||||||
- To add a test that infer finds (or does not find) a particular issue, add your test in
|
|
||||||
"infer/tests/codetoanalyze/{language}/{analyzer}/". Look at the `Makefile` in that directory and
|
|
||||||
make sure it runs your test. "{analyzer}" is often an infer analyzer (as in
|
|
||||||
`infer -a {analyzer}`), with some special cases:
|
|
||||||
- "errors" is "infer"
|
|
||||||
- "frontend" is a mode where the expected output is the result of the translation of the program
|
|
||||||
by infer's clang frontend into infer's intermediate representation.
|
|
||||||
|
|
||||||
Name the procedures in your test following these conventions:
|
|
||||||
- Test procedures where the analyzer should report an error should end with the suffix `Bad`.
|
|
||||||
- Test procedures where the analyzer should not report an error should end with the suffix `Ok`.
|
|
||||||
- Test procedures documenting current limitations of the analyzer should have the prefix `FP_`
|
|
||||||
(for "false positive") or `FN_` (for "false negative") and a comment explaining why the analyzer
|
|
||||||
gets the wrong answer.
|
|
||||||
|
|
||||||
|
|
||||||
- To add a test that a certain build system integration or a command-line option works in a certain
|
|
||||||
way, add a test in "infer/tests/build_systems/".
|
|
||||||
|
|
||||||
- If you created a new Makefile for your test, add it to the root "Makefile", either to the
|
|
||||||
`DIRECT_TESTS` (first case) or to the `BUILD_SYSTEMS_TESTS` variable (second case). Gate the
|
|
||||||
test appropriately if it depends on Java or Clang or Xcode (see how other tests do it).
|
|
||||||
|
|
||||||
- It can be useful to look at the debug HTML output of infer to see the detail of the symbolic
|
|
||||||
execution. For instance:
|
|
||||||
```sh
|
|
||||||
$ infer --debug -- clang -c examples/hello.c
|
|
||||||
$ firefox infer-out/captured/hello.c.*.html
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating infer.opam and infer.opam.locked
|
|
||||||
|
|
||||||
tl; dr: Run `make opam/infer.opam.locked`.
|
|
||||||
|
|
||||||
infer.opam.locked records fixed versions of the opam dependencies known to work with infer and to respect
|
|
||||||
the constraints in opam. This prevents unpredictable breakages of infer or its dependencies,
|
|
||||||
especially for infer releases, for which it is more difficult to change their package constraints
|
|
||||||
after the fact.
|
|
||||||
|
|
||||||
To add an opam package or update its version constraints, edit 'infer.opam' then run `make infer.opam.locked`.
|
|
@ -1,3 +0,0 @@
|
|||||||
Kihong Heo <khheo@ropas.snu.ac.kr>
|
|
||||||
Sungkeun Cho <skcho@ropas.snu.ac.kr>
|
|
||||||
Kwangkeun Yi <kwang@ropas.snu.ac.kr>
|
|
@ -1,7 +0,0 @@
|
|||||||
#Files in infer/bin/
|
|
||||||
|
|
||||||
## Top-level commands
|
|
||||||
|
|
||||||
*infer* : Main command to run Infer. Check out the docs for instructions on how to use it.
|
|
||||||
|
|
||||||
*infer-<command>* : Infer subcommands. Running `infer-<command> [options]` is the same as running `infer <command> [options]`.
|
|
@ -1,111 +0,0 @@
|
|||||||
# How to install Infer from source
|
|
||||||
|
|
||||||
## Binary versions
|
|
||||||
|
|
||||||
We provide a binary release of Infer. We encourage you to use this
|
|
||||||
release as compiling infer's dependencies is time-consuming. Follow
|
|
||||||
the instructions in our [Getting
|
|
||||||
Started](http://fbinfer.com/docs/getting-started/#get-infer)
|
|
||||||
page to install Infer.
|
|
||||||
|
|
||||||
|
|
||||||
## Infer dependencies for MacOSX
|
|
||||||
|
|
||||||
Here are the prerequisites to be able to compile Infer on MacOSX. This
|
|
||||||
is required to compile everything from source.
|
|
||||||
|
|
||||||
- opam >= 2.0.0 (instructions [here](https://opam.ocaml.org/doc/Install.html#OSX))
|
|
||||||
- sqlite
|
|
||||||
- pkg-config
|
|
||||||
- Java (only needed for the Java analysis)
|
|
||||||
- CMake (only needed for the C/Objective-C analysis)
|
|
||||||
- Ninja (optional, if you wish to use sequential linking when building the
|
|
||||||
C/Objective-C analysis)
|
|
||||||
- clang in Xcode command line tools. You can install them with the command
|
|
||||||
`xcode-select --install` (only needed for the C/Objective-C analysis)
|
|
||||||
- Xcode >= 6.1 (only needed for the C/Objective-C analysis)
|
|
||||||
- autoconf >= 2.63 and automake >= 1.11.1 (if building from git)
|
|
||||||
- gmp
|
|
||||||
- mpfr
|
|
||||||
|
|
||||||
You can install some of these dependencies using
|
|
||||||
[Homebrew](http://brew.sh/):
|
|
||||||
|
|
||||||
```sh
|
|
||||||
brew install autoconf automake cmake opam pkg-config sqlite gmp mpfr
|
|
||||||
brew cask install java
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Infer dependencies for Linux
|
|
||||||
|
|
||||||
Here are the prerequisites to be able to compile Infer on Linux. This
|
|
||||||
is required to compile everything from source.
|
|
||||||
|
|
||||||
- opam >= 2.0.0
|
|
||||||
- pkg-config
|
|
||||||
- Java (only needed for the Java analysis)
|
|
||||||
- gcc >= 5.X or clang >= 3.4 (only needed for the C/Objective-C analysis)
|
|
||||||
- autoconf >= 2.63 and automake >= 1.11.1 (if building from git)
|
|
||||||
- CMake (only needed for the C/Objective-C analysis)
|
|
||||||
- Ninja (optional, if you wish to use sequential linking when building the
|
|
||||||
C/Objective-C analysis)
|
|
||||||
|
|
||||||
See also the distro-specific instructions for Ubuntu and Debian below.
|
|
||||||
|
|
||||||
|
|
||||||
## Install Infer from source
|
|
||||||
|
|
||||||
Run the following commands to get Infer up and running:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Checkout Infer
|
|
||||||
git clone https://github.com/facebook/infer.git
|
|
||||||
cd infer
|
|
||||||
# Compile Infer
|
|
||||||
./build-infer.sh java
|
|
||||||
# install Infer system-wide...
|
|
||||||
sudo make install
|
|
||||||
# ...or, alternatively, install Infer into your PATH
|
|
||||||
export PATH=`pwd`/infer/bin:$PATH
|
|
||||||
```
|
|
||||||
|
|
||||||
Replace `./build-infer.sh java` with `./build-infer.sh clang` to build
|
|
||||||
the C and Objective-C analyzer from source. Beware that this command
|
|
||||||
may take a really long time because it will compile a custom version
|
|
||||||
of clang. This custom version is used by Infer to parse C and
|
|
||||||
Objective-C source code.
|
|
||||||
|
|
||||||
See `./build-infer.sh --help` for more options, eg `./build-infer.sh`
|
|
||||||
on its own will build the analyzers for both Java and C/ObjC.
|
|
||||||
|
|
||||||
|
|
||||||
## Install Infer from source without opam
|
|
||||||
|
|
||||||
If for some reason you prefer to install Infer's OCaml dependencies by
|
|
||||||
some means other than opam, you can still compile Infer by running:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./autogen.sh
|
|
||||||
./configure # Disable Java or C/C++/ObjC analyzers with --disable-java-analyzers or --disable-c-analyzers
|
|
||||||
make
|
|
||||||
# install Infer system-wide...
|
|
||||||
sudo make install
|
|
||||||
# ...or, alternatively, install Infer into your PATH
|
|
||||||
export PATH=`pwd`/infer/bin:$PATH
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## How to install the dependencies on Linux
|
|
||||||
|
|
||||||
See the Dockerfile in docker/ for inspiration. It includes the
|
|
||||||
dependencies needed to build Infer on Debian 9 (stretch).
|
|
||||||
|
|
||||||
|
|
||||||
### Setting up opam
|
|
||||||
|
|
||||||
Get opam from your distribution, or from the
|
|
||||||
[opam website](http://opam.ocaml.org/doc/Install.html#Binarydistribution).
|
|
||||||
|
|
||||||
The OCaml dependencies needed by Infer are automatically handled by
|
|
||||||
opam when running `./build-infer.sh`.
|
|
@ -1,10 +0,0 @@
|
|||||||
Please make sure your issue is not addressed in the [FAQ](https://fbinfer.com/docs/support#troubleshooting).
|
|
||||||
|
|
||||||
Please include the following information:
|
|
||||||
- [ ] The version of infer from `infer --version`.
|
|
||||||
- [ ] Your operating system and version, for example "Debian 9", "MacOS High Sierra", whether you are using Docker, etc.
|
|
||||||
- [ ] Which command you ran, for example `infer -- make`.
|
|
||||||
- [ ] The full output in a paste, for instance a [gist](https://gist.github.com/).
|
|
||||||
- [ ] If possible, a minimal example to reproduce your problem (for instance, some code where
|
|
||||||
infer reports incorrectly, together with the way you run infer to reproduce the incorrect
|
|
||||||
report).
|
|
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -1,101 +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.
|
|
||||||
|
|
||||||
@SET_MAKE@
|
|
||||||
|
|
||||||
ANT = @ANT@
|
|
||||||
ATDGEN = @ATDGEN@
|
|
||||||
bindir = @bindir@
|
|
||||||
BUCK = @BUCK@
|
|
||||||
BUILD_C_ANALYZERS = @BUILD_C_ANALYZERS@
|
|
||||||
BUILD_ERLANG_ANALYZERS = @BUILD_ERLANG_ANALYZERS@
|
|
||||||
BUILD_JAVA_ANALYZERS = @BUILD_JAVA_ANALYZERS@
|
|
||||||
BUILD_PLATFORM = @BUILD_PLATFORM@
|
|
||||||
CAML_LD_LIBRARY_PATH = @CAML_LD_LIBRARY_PATH@
|
|
||||||
CC = @CC@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CLANG_INCLUDES = @CLANG_INCLUDES@
|
|
||||||
CLANG_PREFIX = @CLANG_PREFIX@
|
|
||||||
CMAKE = @CMAKE@
|
|
||||||
CPATH = @CPATH@
|
|
||||||
CPP = @CPP@
|
|
||||||
CXX = @CXX@
|
|
||||||
CXXFLAGS = @CXXFLAGS@
|
|
||||||
# this is useless but autoconf is picky...
|
|
||||||
datarootdir = @datarootdir@
|
|
||||||
EMACS = @EMACS@
|
|
||||||
ENABLE_OCAMLOPT_CUSTOM_CC = @ENABLE_OCAMLOPT_CUSTOM_CC@
|
|
||||||
ENABLE_OCAML_BINANNOT = @ENABLE_OCAML_BINANNOT@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
GNU_SED = @GNU_SED@
|
|
||||||
HAS_OBJC = @HAS_OBJC@
|
|
||||||
INFER_MAJOR = @INFER_MAJOR@
|
|
||||||
INFER_MAN_LAST_MODIFIED = @INFER_MAN_LAST_MODIFIED@
|
|
||||||
INFER_MINOR = @INFER_MINOR@
|
|
||||||
INFER_PATCH = @INFER_PATCH@
|
|
||||||
INSTALL = @INSTALL@
|
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
|
||||||
INSTALL_NAME_TOOL = @INSTALL_NAME_TOOL@
|
|
||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
||||||
IS_FACEBOOK_TREE = @IS_FACEBOOK_TREE@
|
|
||||||
IS_RELEASE_TREE = @IS_RELEASE_TREE@
|
|
||||||
JAVA_MAJOR_VERSION = @JAVA_MAJOR_VERSION@
|
|
||||||
JAVAC = @JAVAC@
|
|
||||||
LDD = @LDD@
|
|
||||||
LDFLAGS = @LDFLAGS@
|
|
||||||
libdir = @libdir@
|
|
||||||
# override in your `make` command to make the install relocatable
|
|
||||||
libdir_relative_to_bindir = $(libdir)
|
|
||||||
LIBRARY_PATH = @LIBRARY_PATH@
|
|
||||||
LIBS = @LIBS@
|
|
||||||
mandir = @mandir@
|
|
||||||
MENHIR = @MENHIR@
|
|
||||||
MKDIR_P_CMD = case "@MKDIR_P@" in \
|
|
||||||
./*) printf "$(ROOT_DIR)/@MKDIR_P@\n";; \
|
|
||||||
*) printf "@MKDIR_P@\n";; \
|
|
||||||
esac
|
|
||||||
MKDIR_P = $(shell $(MKDIR_P_CMD))
|
|
||||||
MVN = @MVN@
|
|
||||||
NCPU = @NCPU@
|
|
||||||
NDKBUILD = @NDKBUILD@
|
|
||||||
NINJA = @NINJA@
|
|
||||||
OCAMLBUILD = @OCAMLBUILD@
|
|
||||||
OCAMLC = @OCAMLC@
|
|
||||||
OCAMLFIND = @OCAMLFIND@
|
|
||||||
OCAMLFORMAT_EXE = @OCAMLFORMAT@
|
|
||||||
OCAMLLEX = @OCAMLLEX@
|
|
||||||
OCAMLOPT = @OCAMLOPT@
|
|
||||||
OPAM = @OPAM@
|
|
||||||
OPAMROOT = @OPAMROOT@
|
|
||||||
OPAMSWITCH = @OPAMSWITCH@
|
|
||||||
OTOOL = @OTOOL@
|
|
||||||
PATCHELF = @PATCHELF@
|
|
||||||
PATH = @PATH@
|
|
||||||
prefix = @prefix@
|
|
||||||
REBAR3 = @REBAR3@
|
|
||||||
SDKROOT = @SDKROOT@
|
|
||||||
SHASUM = @SHASUM@
|
|
||||||
USER_JAVA_HOME = @USER_JAVA_HOME@
|
|
||||||
UTOP = @UTOP@
|
|
||||||
WINDOWS_BUILD = @WINDOWS_BUILD@
|
|
||||||
XCODE_BASE = @XCODE_BASE@
|
|
||||||
XCODE_SELECT = @XCODE_SELECT@
|
|
||||||
XCPRETTY = @XCPRETTY@
|
|
||||||
XCRUN = @XCRUN@
|
|
||||||
|
|
||||||
ifneq (,$(findstring s,$(MAKEFLAGS)))
|
|
||||||
# quiet mode
|
|
||||||
LN_S = @LN_S@
|
|
||||||
else
|
|
||||||
LN_S = @LN_S@ -v
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Export parts of the config relevant to running other programs
|
|
||||||
export PATH := $(PATH)
|
|
||||||
export CPATH := $(CPATH)
|
|
||||||
export LIBRARY_PATH := $(LIBRARY_PATH)
|
|
||||||
export CAML_LD_LIBRARY_PATH := $(CAML_LD_LIBRARY_PATH)
|
|
||||||
export OPAMROOT := $(OPAMROOT)
|
|
||||||
export SDKROOT := $(SDKROOT)
|
|
@ -1,211 +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.
|
|
||||||
|
|
||||||
ORIG_SHELL = $(shell echo "$$SHELL")
|
|
||||||
SHELL = bash -e -o pipefail -u
|
|
||||||
|
|
||||||
ORIG_SHELL_PATH = $(shell printf "%s" "$$PATH")
|
|
||||||
|
|
||||||
# Make infer crash a bit more often to detect issues in the way we call infer within this repo, eg,
|
|
||||||
# using deprecated options.
|
|
||||||
export INFER_STRICT_MODE=1
|
|
||||||
|
|
||||||
include $(ROOT_DIR)/Makefile.autoconf
|
|
||||||
|
|
||||||
# possible values:
|
|
||||||
# - dev: flambda optimizations disabled, build warnings are errors
|
|
||||||
# - dev-noerror: flambda optimizations disabled, build warnings do not fail the build
|
|
||||||
# - opt: flambda optimizations enabled, build warnings do not fail the build
|
|
||||||
BUILD_MODE = dev
|
|
||||||
DUNE_BUILD = dune build --profile=$(BUILD_MODE)
|
|
||||||
|
|
||||||
PLATFORM = $(shell uname)
|
|
||||||
|
|
||||||
COPY = cp -f
|
|
||||||
COPY_DIR = cp -Rf
|
|
||||||
REMOVE = rm -f
|
|
||||||
REMOVE_DIR = rm -rf
|
|
||||||
|
|
||||||
ABSOLUTE_ROOT_DIR = $(shell cd $(ROOT_DIR) && pwd)
|
|
||||||
|
|
||||||
DEPENDENCIES_DIR = $(ABSOLUTE_ROOT_DIR)/dependencies
|
|
||||||
DOCKER_DIR = $(ABSOLUTE_ROOT_DIR)/docker
|
|
||||||
EXAMPLES_DIR = $(ABSOLUTE_ROOT_DIR)/examples
|
|
||||||
INFER_DIR = $(ABSOLUTE_ROOT_DIR)/infer
|
|
||||||
FCP_DIR = $(ABSOLUTE_ROOT_DIR)/facebook-clang-plugins
|
|
||||||
M4_DIR = $(ABSOLUTE_ROOT_DIR)/m4
|
|
||||||
SCRIPT_DIR = $(ABSOLUTE_ROOT_DIR)/scripts
|
|
||||||
WEBSITE_DIR = $(ABSOLUTE_ROOT_DIR)/website
|
|
||||||
|
|
||||||
FCP_CLANG_OCAML_DIR = $(FCP_DIR)/clang-ocaml
|
|
||||||
|
|
||||||
ANNOTATIONS_DIR = $(INFER_DIR)/annotations
|
|
||||||
BIN_DIR = $(INFER_DIR)/bin
|
|
||||||
ETC_DIR = $(INFER_DIR)/etc
|
|
||||||
LIB_DIR = $(INFER_DIR)/lib
|
|
||||||
MAN_DIR = $(INFER_DIR)/man
|
|
||||||
MODELS_DIR = $(INFER_DIR)/models
|
|
||||||
JAVA_BUILTINS_DIR = $(MODELS_DIR)/java/builtins
|
|
||||||
JAVA_MODELS_DIR = $(MODELS_DIR)/java/src
|
|
||||||
SRC_DIR = $(INFER_DIR)/src
|
|
||||||
|
|
||||||
BUILD_DIR = $(INFER_DIR)/_build
|
|
||||||
|
|
||||||
JAVA_LIB_DIR = $(LIB_DIR)/java
|
|
||||||
|
|
||||||
INFER_BIN = $(BIN_DIR)/infer
|
|
||||||
INFER_COMMANDS = \
|
|
||||||
infer-analyze \
|
|
||||||
infer-capture \
|
|
||||||
infer-compile \
|
|
||||||
infer-debug \
|
|
||||||
infer-explore \
|
|
||||||
infer-help \
|
|
||||||
infer-report \
|
|
||||||
infer-reportdiff \
|
|
||||||
infer-run \
|
|
||||||
|
|
||||||
INFERTOP_BIN = $(BIN_DIR)/infertop.bc.exe
|
|
||||||
INFERUNIT_BIN = $(BIN_DIR)/inferunit.bc.exe
|
|
||||||
CHECKCOPYRIGHT_BIN = $(BIN_DIR)/checkCopyright
|
|
||||||
|
|
||||||
INFER_CREATE_TRACEVIEW_LINKS = InferCreateTraceViewLinks
|
|
||||||
INFER_CREATE_TRACEVIEW_LINKS_BIN = $(BIN_DIR)/$(INFER_CREATE_TRACEVIEW_LINKS)
|
|
||||||
|
|
||||||
INFER_COMMAND_MANUALS = $(INFER_COMMANDS:%=$(MAN_DIR)/man1/%.1)
|
|
||||||
INFER_COMMAND_TEXT_MANUALS = $(INFER_COMMANDS:%=$(MAN_DIR)/man1/%.txt)
|
|
||||||
INFER_MANUAL = $(MAN_DIR)/man1/infer.1
|
|
||||||
INFER_GROFF_MANUALS = $(INFER_COMMAND_MANUALS) $(INFER_MANUAL)
|
|
||||||
INFER_GROFF_MANUALS_GZIPPED = $(INFER_GROFF_MANUALS:=.gz)
|
|
||||||
INFER_TEXT_MANUAL = $(MAN_DIR)/man1/infer.txt
|
|
||||||
INFER_FULL_TEXT_MANUAL = $(MAN_DIR)/man1/infer-full.txt
|
|
||||||
INFER_TEXT_MANUALS = $(INFER_COMMAND_TEXT_MANUALS) $(INFER_TEXT_MANUAL) $(INFER_FULL_TEXT_MANUAL)
|
|
||||||
INFER_MANUALS = $(INFER_GROFF_MANUALS) $(INFER_TEXT_MANUALS)
|
|
||||||
|
|
||||||
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
|
|
||||||
JAVA_HOME=$(USER_JAVA_HOME)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# marker to keep track of when models have been rebuilt
|
|
||||||
MODELS_RESULTS_FILE = $(LIB_DIR)/models.sql
|
|
||||||
|
|
||||||
ANDROID_JAR = $(LIB_DIR)/java/android/android-23.jar
|
|
||||||
GUAVA_JAR = $(DEPENDENCIES_DIR)/java/guava/guava-23.0.jar
|
|
||||||
INFER_ANNOTATIONS_JAR = $(ANNOTATIONS_DIR)/annotations.jar
|
|
||||||
JACKSON_JAR = $(DEPENDENCIES_DIR)/java/jackson/jackson-2.2.3.jar
|
|
||||||
JSR_305_JAR = $(DEPENDENCIES_DIR)/java/jsr-305/jsr305.jar
|
|
||||||
|
|
||||||
JAVA_MODELS_JAR = $(LIB_DIR)/java/models.jar
|
|
||||||
|
|
||||||
JAVA_DEPS_NO_MODELS = \
|
|
||||||
$(ANDROID_JAR) $(GUAVA_JAR) $(JACKSON_JAR) $(JSR_305_JAR) $(INFER_ANNOTATIONS_JAR) \
|
|
||||||
$(INFER_BIN)
|
|
||||||
|
|
||||||
JAVA_DEPS = $(JAVA_DEPS_NO_MODELS) $(JAVA_MODELS_JAR) $(MODELS_RESULTS_FILE)
|
|
||||||
|
|
||||||
CLANG_DEPS_NO_MODELS = $(INFER_BIN)
|
|
||||||
|
|
||||||
CLANG_DEPS = $(CLANG_DEPS_NO_MODELS) $(MODELS_RESULTS_FILE)
|
|
||||||
|
|
||||||
XCODE_ISYSROOT_SUFFIX = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
|
|
||||||
ifeq ($(wildcard $(XCODE_BASE)/$(XCODE_ISYSROOT_SUFFIX)),)
|
|
||||||
XCODE_ISYSROOT_SUFFIX = SDKs/MacOSX.sdk
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(HAS_OBJC),yes)
|
|
||||||
XCODE_ISYSROOT = $(XCODE_BASE)/$(XCODE_ISYSROOT_SUFFIX)
|
|
||||||
endif
|
|
||||||
|
|
||||||
define copy_or_same_file
|
|
||||||
$(COPY) "$(1)" "$(2)" || diff -q "$(1)" "$(2)"
|
|
||||||
endef
|
|
||||||
|
|
||||||
INTERACTIVE = $(shell [ -t 0 ] && echo 1)
|
|
||||||
SILENT = $(findstring s,$(filter-out -%,$(firstword $(MAKEFLAGS))))
|
|
||||||
|
|
||||||
ifeq (1,$(INTERACTIVE))
|
|
||||||
TERM_ERROR = $(shell printf '\e[31;1m')
|
|
||||||
TERM_INFO = $(shell printf '\e[;1m')
|
|
||||||
TERM_SUCCESS = $(shell printf '\e[;2m')
|
|
||||||
TERM_RESET = $(shell printf '\e[0m')
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(VERBOSE),1)
|
|
||||||
# quiet
|
|
||||||
QUIET = @
|
|
||||||
endif
|
|
||||||
|
|
||||||
MAKE := $(MAKE) INTERACTIVE=$(INTERACTIVE)
|
|
||||||
|
|
||||||
# check if pid_max can be found else default to whatever
|
|
||||||
KERNEL_PID_MAX_FILE = /proc/sys/kernel/pid_max
|
|
||||||
MAX_PID_SIZE = $(shell \
|
|
||||||
[ -r $(KERNEL_PID_MAX_FILE) ] \
|
|
||||||
&& echo $$(( $$(wc -m < $(KERNEL_PID_MAX_FILE)) - 1 )) \
|
|
||||||
|| echo 5)
|
|
||||||
|
|
||||||
# Arguments:
|
|
||||||
# $(1) is a string describing the command
|
|
||||||
# $(2) is the command to run
|
|
||||||
#
|
|
||||||
ifeq ($(VERBOSE),1)
|
|
||||||
define silent_on_success
|
|
||||||
$(2)
|
|
||||||
endef
|
|
||||||
else
|
|
||||||
# Run and time the command and redirect its stdout and stderr to files. Display info about the
|
|
||||||
# command only in case of error. Try to be as helpful as possible in the error case.
|
|
||||||
#
|
|
||||||
# The PID of the process is used in the names of the output files, and as a prefix for each error
|
|
||||||
# message so that it's possible to piece error messages together even when they are interleaved with
|
|
||||||
# other messages from concurrent `make` processes.
|
|
||||||
#
|
|
||||||
# Detect if we are already wrapped inside a silent_on_success call and try not to clutter the output
|
|
||||||
# too much in that case.
|
|
||||||
define silent_on_success
|
|
||||||
if [ -n "$${INSIDE_SILENT_ON_SUCCESS-}" ]; then \
|
|
||||||
echo '*** inner $(1)'; \
|
|
||||||
echo '*** inner command: $(2)'; \
|
|
||||||
echo '*** inner CWD: $(CURDIR)'; \
|
|
||||||
($(2)); \
|
|
||||||
exit $$?; \
|
|
||||||
fi; \
|
|
||||||
export INSIDE_SILENT_ON_SUCCESS=1; \
|
|
||||||
HASH="$$$$"; \
|
|
||||||
UNIX_START_DATE=$$(date +"%s"); \
|
|
||||||
HUMAN_START_DATE=$$(date +"%H:%M:%S"); \
|
|
||||||
if [ -z $(SILENT) ]; then \
|
|
||||||
printf '[%s][%$(MAX_PID_SIZE)s] $(TERM_INFO)%s...$(TERM_RESET)\n' \
|
|
||||||
"$$HUMAN_START_DATE" "$$HASH" "$(1)"; \
|
|
||||||
fi; \
|
|
||||||
$(MKDIR_P) $(ABSOLUTE_ROOT_DIR)/_build_logs; \
|
|
||||||
ERRCODE=0; \
|
|
||||||
($(2)) 1>$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.out \
|
|
||||||
2>$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.err \
|
|
||||||
|| ERRCODE=$$?; \
|
|
||||||
if [ $$ERRCODE != 0 ]; then \
|
|
||||||
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** ERROR '$(1)'$(TERM_RESET)" >&2; \
|
|
||||||
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** command: '$(2)'$(TERM_RESET)" >&2; \
|
|
||||||
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** CWD: '$(CURDIR)'$(TERM_RESET)" >&2; \
|
|
||||||
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** stdout:$(TERM_RESET)" >&2; \
|
|
||||||
sed -e "s/^\(.*\)$$/$(TERM_ERROR)[*ERROR**][$$HASH]$(TERM_RESET) \1/" \
|
|
||||||
$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.out; >&2; \
|
|
||||||
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** stderr:$(TERM_RESET)" >&2; \
|
|
||||||
sed -e "s/^\(.*\)$$/$(TERM_ERROR)[*ERROR**][$$HASH]$(TERM_RESET) \1/" \
|
|
||||||
$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.err; >&2; \
|
|
||||||
exit $$ERRCODE; \
|
|
||||||
elif [ -z $(SILENT) ]; then \
|
|
||||||
UNIX_END_DATE=$$(date +"%s"); \
|
|
||||||
printf '[%7ss][%$(MAX_PID_SIZE)s] $(TERM_SUCCESS)SUCCESS %s$(TERM_RESET)\n' \
|
|
||||||
"$$(($$UNIX_END_DATE - $$UNIX_START_DATE))" "$$HASH" "$(1)"; \
|
|
||||||
fi
|
|
||||||
endef
|
|
||||||
endif
|
|
||||||
|
|
||||||
# print any variable for Makefile debugging
|
|
||||||
print-%:
|
|
||||||
$(QUIET)echo '$*=$($*)'
|
|
||||||
|
|
||||||
TESTLOCK = $(INFER_DIR)/tests/testlock.py
|
|
@ -1 +0,0 @@
|
|||||||
Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for how to set up your development environment and run tests.
|
|
@ -1,24 +0,0 @@
|
|||||||
<img src="website/static/img/logo.png" alt="logo" width="15%" />
|
|
||||||
|
|
||||||
# Infer [](https://travis-ci.org/facebook/infer)
|
|
||||||
|
|
||||||
[Infer](http://fbinfer.com/) is a static analysis tool for Java,
|
|
||||||
C++, Objective-C, and C. Infer is written in [OCaml](https://ocaml.org/).
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Read our [Getting
|
|
||||||
Started](http://fbinfer.com/docs/getting-started) page for
|
|
||||||
details on how to install packaged versions of Infer. To build Infer
|
|
||||||
from source, see [INSTALL.md](./INSTALL.md).
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Infer is MIT-licensed.
|
|
||||||
|
|
||||||
Note: Enabling Java support may require you to download and install
|
|
||||||
components licensed under the GPL.
|
|
@ -1,59 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
|
|
||||||
# make sure we run from the root of the repo
|
|
||||||
pushd "$SCRIPT_DIR" > /dev/null
|
|
||||||
|
|
||||||
# We need to record the date that the documentation was last modified to put in our man
|
|
||||||
# pages. Unfortunately that information is only available reliably from `git`, which we don't have
|
|
||||||
# access to from other distributions of the infer source code. Such source distributions should
|
|
||||||
# distribute the "configure" script too. The idea is to bake this date inside "configure" so that
|
|
||||||
# it's available at build time. We do that by generating an m4 macro that hardcodes the date we
|
|
||||||
# compute in this script for "configure" to find.
|
|
||||||
MAN_LAST_MODIFIED_M4=m4/__GENERATED__ac_check_infer_man_last_modified.m4
|
|
||||||
printf 'generating %s' "$MAN_LAST_MODIFIED_M4... "
|
|
||||||
if test -d '.git' ; then
|
|
||||||
# date at which the man pages were last modified, to record in the manpages themselves
|
|
||||||
MAN_FILES=(
|
|
||||||
infer/src/base/CommandLineOption.ml
|
|
||||||
infer/src/base/Config.ml
|
|
||||||
)
|
|
||||||
MAN_DATE=$(git log -n 1 --pretty=format:%cd --date=short -- "${MAN_FILES[@]}")
|
|
||||||
INFER_MAN_LAST_MODIFIED=${INFER_MAN_LAST_MODIFIED:-$MAN_DATE}
|
|
||||||
else
|
|
||||||
echo 'no git repository detected; setting last modified date to today'
|
|
||||||
# best effort: get today's date
|
|
||||||
INFER_MAN_LAST_MODIFIED=${INFER_MAN_LAST_MODIFIED:-$(date +%Y-%m-%d)}
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "AC_DEFUN([AC_CHECK_INFER_MAN_LAST_MODIFIED],\n" > "$MAN_LAST_MODIFIED_M4"
|
|
||||||
printf "[INFER_MAN_LAST_MODIFIED=%s\n" "$INFER_MAN_LAST_MODIFIED" >> "$MAN_LAST_MODIFIED_M4"
|
|
||||||
printf " AC_SUBST([INFER_MAN_LAST_MODIFIED])\n" >> "$MAN_LAST_MODIFIED_M4"
|
|
||||||
printf "])\n" >> "$MAN_LAST_MODIFIED_M4"
|
|
||||||
printf 'done\n'
|
|
||||||
|
|
||||||
# older versions of `autoreconf` only support including macros via acinclude.m4
|
|
||||||
ACINCLUDE="acinclude.m4"
|
|
||||||
printf "generating $ACINCLUDE..."
|
|
||||||
cat m4/*.m4 > "$ACINCLUDE"
|
|
||||||
printf " done\n"
|
|
||||||
|
|
||||||
printf "generating ./configure script..."
|
|
||||||
autoreconf -fi
|
|
||||||
printf " done\n"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "you may now run the following commands to build Infer:"
|
|
||||||
echo ""
|
|
||||||
echo " ./configure"
|
|
||||||
echo " make"
|
|
||||||
echo ""
|
|
||||||
echo 'run `./configure --help` for more options'
|
|
@ -1,232 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Convenience script to build Infer when using opam
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -o pipefail
|
|
||||||
set -u
|
|
||||||
|
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
INFER_ROOT="$SCRIPT_DIR"
|
|
||||||
DEPENDENCIES_DIR="$INFER_ROOT/facebook/dependencies"
|
|
||||||
PLATFORM="$(uname)"
|
|
||||||
SANDCASTLE=${SANDCASTLE:-}
|
|
||||||
NCPU="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)"
|
|
||||||
INFER_OPAM_DEFAULT_SWITCH="4.12.0+flambda"
|
|
||||||
INFER_OPAM_DEFAULT_SWITCH_OPTIONS="--package=ocaml-variants.4.12.0+options,ocaml-option-flambda"
|
|
||||||
INFER_OPAM_SWITCH=${INFER_OPAM_SWITCH:-$INFER_OPAM_DEFAULT_SWITCH}
|
|
||||||
INFER_OPAM_SWITCH_OPTIONS=${INFER_OPAM_SWITCH_OPTIONS:-$INFER_OPAM_DEFAULT_SWITCH_OPTIONS}
|
|
||||||
PLUGIN_DIR="$INFER_ROOT/facebook-clang-plugins"
|
|
||||||
PLUGIN_SETUP_SCRIPT=${PLUGIN_SETUP_SCRIPT:-setup.sh}
|
|
||||||
PLUGIN_SETUP="${PLUGIN_DIR}/clang/${PLUGIN_SETUP_SCRIPT}"
|
|
||||||
|
|
||||||
function usage() {
|
|
||||||
echo "Usage: $0 [-y] [targets]"
|
|
||||||
echo
|
|
||||||
echo " targets:"
|
|
||||||
echo " all build everything (default)"
|
|
||||||
echo " clang build C and Objective-C analyzer"
|
|
||||||
echo " erlang build Erlang analyzer"
|
|
||||||
echo " java build Java analyzer"
|
|
||||||
echo
|
|
||||||
echo " options:"
|
|
||||||
echo " -h,--help show this message"
|
|
||||||
echo " --no-opam-lock do not use the opam/infer.opam.locked file and let opam resolve dependencies"
|
|
||||||
echo " --only-setup-opam initialize opam, install the opam dependencies of infer, and exit"
|
|
||||||
echo " --user-opam-switch use the current opam switch to install infer (default: $INFER_OPAM_DEFAULT_SWITCH)"
|
|
||||||
echo " -y,--yes automatically agree to everything"
|
|
||||||
echo
|
|
||||||
echo " examples:"
|
|
||||||
echo " $0 # build Java, Erlang and C/Objective-C analyzers"
|
|
||||||
echo " $0 java erlang clang # equivalent way of doing the above"
|
|
||||||
echo " $0 java # build only the Java analyzer"
|
|
||||||
}
|
|
||||||
|
|
||||||
# arguments
|
|
||||||
BUILD_CLANG=${BUILD_CLANG:-no}
|
|
||||||
BUILD_ERLANG=${BUILD_ERLANG:-no}
|
|
||||||
BUILD_JAVA=${BUILD_JAVA:-no}
|
|
||||||
INFER_CONFIGURE_OPTS=${INFER_CONFIGURE_OPTS:-""}
|
|
||||||
INTERACTIVE=${INTERACTIVE:-yes}
|
|
||||||
JOBS=${JOBS:-$NCPU}
|
|
||||||
ONLY_SETUP_OPAM=${ONLY_SETUP_OPAM:-no}
|
|
||||||
USE_OPAM_LOCK=${USE_OPAM_LOCK:-yes}
|
|
||||||
USER_OPAM_SWITCH=no
|
|
||||||
|
|
||||||
ORIG_ARGS="$*"
|
|
||||||
|
|
||||||
function build_all() {
|
|
||||||
BUILD_CLANG=yes
|
|
||||||
BUILD_ERLANG=yes
|
|
||||||
BUILD_JAVA=yes
|
|
||||||
}
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
opt_key="$1"
|
|
||||||
case $opt_key in
|
|
||||||
all)
|
|
||||||
build_all
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
clang)
|
|
||||||
BUILD_CLANG=yes
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
erlang)
|
|
||||||
BUILD_ERLANG=yes
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
java)
|
|
||||||
BUILD_JAVA=yes
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
--no-opam-lock)
|
|
||||||
USE_OPAM_LOCK=no
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
--user-opam-switch)
|
|
||||||
USER_OPAM_SWITCH=yes
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
--only-setup-opam)
|
|
||||||
ONLY_SETUP_OPAM=yes
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
-y|--yes)
|
|
||||||
INTERACTIVE=no
|
|
||||||
shift
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$BUILD_CLANG" == "no" ] && [ "$BUILD_ERLANG" == "no" ] && [ "$BUILD_JAVA" == "no" ]; then
|
|
||||||
build_all
|
|
||||||
fi
|
|
||||||
|
|
||||||
# enable --yes option for some commands in non-interactive mode
|
|
||||||
YES=
|
|
||||||
if [ "$INTERACTIVE" == "no" ]; then
|
|
||||||
YES=--yes
|
|
||||||
fi
|
|
||||||
# --yes by default for opam commands except if we are using the user's opam switch
|
|
||||||
if [ "$INTERACTIVE" == "no" ] || [ "$USER_OPAM_SWITCH" == "no" ]; then
|
|
||||||
export OPAMYES=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
setup_opam () {
|
|
||||||
opam var root 1>/dev/null 2>/dev/null || opam init --reinit --bare --no-setup &&
|
|
||||||
opam_retry opam_switch_create_if_needed "$INFER_OPAM_SWITCH" "$INFER_OPAM_SWITCH_OPTIONS" &&
|
|
||||||
opam switch set "$INFER_OPAM_SWITCH"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_opam_deps () {
|
|
||||||
local locked=
|
|
||||||
if [ "$USE_OPAM_LOCK" == yes ]; then
|
|
||||||
locked=.locked
|
|
||||||
fi
|
|
||||||
opam install --deps-only "$INFER_ROOT"/opam/infer.opam$locked &&
|
|
||||||
if [ -n "$SANDCASTLE" ]; then
|
|
||||||
opam pin list | grep yojson || opam pin add yojson "${DEPENDENCIES_DIR}/yojson-1.7.0fix"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "initializing opam... " >&2
|
|
||||||
. "$INFER_ROOT"/scripts/opam_utils.sh
|
|
||||||
if [ "$USER_OPAM_SWITCH" == "no" ]; then
|
|
||||||
setup_opam
|
|
||||||
fi
|
|
||||||
eval $(SHELL=bash opam env)
|
|
||||||
echo >&2
|
|
||||||
echo "installing infer dependencies; this can take up to 30 minutes... " >&2
|
|
||||||
opam_retry install_opam_deps
|
|
||||||
|
|
||||||
if [ "$ONLY_SETUP_OPAM" == "yes" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "preparing build... " >&2
|
|
||||||
./autogen.sh > /dev/null
|
|
||||||
|
|
||||||
if [ "$BUILD_CLANG" == "no" ]; then
|
|
||||||
INFER_CONFIGURE_OPTS+=" --disable-c-analyzers"
|
|
||||||
fi
|
|
||||||
if [ "$BUILD_ERLANG" == "no" ]; then
|
|
||||||
INFER_CONFIGURE_OPTS+=" --disable-erlang-analyzers"
|
|
||||||
fi
|
|
||||||
if [ "$BUILD_JAVA" == "no" ]; then
|
|
||||||
INFER_CONFIGURE_OPTS+=" --disable-java-analyzers"
|
|
||||||
fi
|
|
||||||
|
|
||||||
./configure $INFER_CONFIGURE_OPTS
|
|
||||||
|
|
||||||
if [ "$BUILD_CLANG" == "yes" ]; then
|
|
||||||
if ! "$PLUGIN_SETUP" --only-check-install; then
|
|
||||||
echo ""
|
|
||||||
echo " Warning: you are not using a release of Infer. The C and"
|
|
||||||
echo " Objective-C analyses require a custom clang to be compiled"
|
|
||||||
echo " now. This step takes ~30-60 minutes, possibly more."
|
|
||||||
echo ""
|
|
||||||
echo " To speed this along, you are encouraged to use a release of"
|
|
||||||
echo " Infer instead:"
|
|
||||||
echo ""
|
|
||||||
echo " http://fbinfer.com/docs/getting-started"
|
|
||||||
echo ""
|
|
||||||
echo " If you are only interested in analyzing Java programs, simply"
|
|
||||||
echo " run this script with only the \"java\" argument:"
|
|
||||||
echo ""
|
|
||||||
echo " $0 java"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
confirm="n"
|
|
||||||
printf "Are you sure you want to compile clang? (y/N) "
|
|
||||||
if [ "$INTERACTIVE" == "no" ]; then
|
|
||||||
confirm="y"
|
|
||||||
echo "$confirm"
|
|
||||||
else
|
|
||||||
read confirm
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "x$confirm" != "xy" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# only run this script if we are definitely building clang
|
|
||||||
facebook-clang-plugins/clang/src/prepare_clang_src.sh
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
make -j "$JOBS" opt || (
|
|
||||||
echo >&2
|
|
||||||
echo ' compilation failure; you can try running' >&2
|
|
||||||
echo >&2
|
|
||||||
echo ' make clean' >&2
|
|
||||||
echo " '$0' $ORIG_ARGS" >&2
|
|
||||||
echo >&2
|
|
||||||
exit 1)
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "*** Success! Infer is now built in '$SCRIPT_DIR/infer/bin/'."
|
|
||||||
echo '*** Install infer on your system with `make install`.'
|
|
||||||
echo
|
|
||||||
echo '*** If you plan to hack on infer, check out CONTRIBUTING.md to setup your dev environment.'
|
|
@ -1,427 +0,0 @@
|
|||||||
dnl Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
dnl
|
|
||||||
dnl This source code is licensed under the MIT license found in the
|
|
||||||
dnl LICENSE file in the root directory of this source tree.
|
|
||||||
|
|
||||||
dnl autoconf script for Infer
|
|
||||||
dnl run ./autogen.sh to generate a configure script
|
|
||||||
|
|
||||||
AC_PREREQ([2.63])
|
|
||||||
|
|
||||||
# WARNING: the version number has to be kept in sync with:
|
|
||||||
# - the values below
|
|
||||||
# - opam
|
|
||||||
AC_INIT([Infer],
|
|
||||||
[1.1.0],
|
|
||||||
[https://github.com/facebook/infer/issues/])
|
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([infer/src/istd/IStd.ml])
|
|
||||||
|
|
||||||
# WARNING: keep in sync with above
|
|
||||||
INFER_MAJOR=1
|
|
||||||
INFER_MINOR=1
|
|
||||||
INFER_PATCH=0
|
|
||||||
|
|
||||||
AC_SUBST([INFER_MAJOR])
|
|
||||||
AC_SUBST([INFER_MINOR])
|
|
||||||
AC_SUBST([INFER_PATCH])
|
|
||||||
|
|
||||||
# are we in a release source tree
|
|
||||||
AC_CHECK_FILE([.release], [is_release_tree=yes], [is_release_tree=no])
|
|
||||||
IS_RELEASE_TREE=$is_release_tree
|
|
||||||
AC_SUBST([IS_RELEASE_TREE])
|
|
||||||
|
|
||||||
# are we in an internal source tree
|
|
||||||
AC_CHECK_FILE([.facebook], [is_facebook_tree=yes], [is_facebook_tree=no])
|
|
||||||
IS_FACEBOOK_TREE=$is_facebook_tree
|
|
||||||
AC_SUBST([IS_FACEBOOK_TREE])
|
|
||||||
|
|
||||||
AC_ARG_VAR([PATH], [the shell's $PATH list of directories to search for executables])
|
|
||||||
|
|
||||||
# to compile the facebook-clang-plugins
|
|
||||||
AC_ARG_VAR([CLANG_PREFIX], [directory where clang is installed (defaults=$PWD/facebook-clang-plugins/clang/install)])
|
|
||||||
AS_IF([test "x$CLANG_PREFIX" = "x"], [
|
|
||||||
CLANG_PREFIX="$(pwd)/facebook-clang-plugins/clang/install"
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_ARG_VAR([CLANG_INCLUDES], [clang headers directories (defaults=$CLANG_PREFIX/include)])
|
|
||||||
AS_IF([test "x$CLANG_INCLUDES" = "x"], [
|
|
||||||
CLANG_INCLUDES="$CLANG_PREFIX/include"
|
|
||||||
])
|
|
||||||
|
|
||||||
BUILD_PLATFORM=unknown
|
|
||||||
WINDOWS_BUILD=no
|
|
||||||
AC_MSG_CHECKING([for build platform])
|
|
||||||
# see https://stackoverflow.com/questions/714100/os-detecting-makefile
|
|
||||||
# but we do this in the configure for homogeneity
|
|
||||||
case "${OS}" in
|
|
||||||
Windows_NT*)
|
|
||||||
BUILD_PLATFORM=Windows
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
uname_str=`uname -s`
|
|
||||||
case "${uname_str}" in
|
|
||||||
Linux*)
|
|
||||||
BUILD_PLATFORM=Linux
|
|
||||||
;;
|
|
||||||
Darwin*)
|
|
||||||
BUILD_PLATFORM=Darwin
|
|
||||||
;;
|
|
||||||
cygwin*|mingw*)
|
|
||||||
BUILD_PLATFORM=Windows
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
AC_MSG_ERROR(["OS $uname_str is not supported"])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
esac
|
|
||||||
AC_MSG_RESULT([$BUILD_PLATFORM])
|
|
||||||
AC_SUBST([BUILD_PLATFORM])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([for Windows build])
|
|
||||||
AS_IF([test x"$BUILD_PLATFORM" = x"Windows"], [WINDOWS_BUILD=yes])
|
|
||||||
AC_MSG_RESULT([$WINDOWS_BUILD])
|
|
||||||
AC_SUBST([WINDOWS_BUILD])
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(c-analyzers,
|
|
||||||
AS_HELP_STRING([--disable-c-analyzers],
|
|
||||||
[do not build the C/C++/ObjC analyzers (default is to build them)]),
|
|
||||||
,
|
|
||||||
enable_c_analyzers=yes)
|
|
||||||
BUILD_C_ANALYZERS=$enable_c_analyzers
|
|
||||||
AC_SUBST([BUILD_C_ANALYZERS])
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(erlang-analyzers,
|
|
||||||
AS_HELP_STRING([--disable-erlang-analyzers],
|
|
||||||
[do not build the Erlang analyzers (default is to build them)]),
|
|
||||||
,
|
|
||||||
enable_erlang_analyzers=yes)
|
|
||||||
BUILD_ERLANG_ANALYZERS=$enable_erlang_analyzers
|
|
||||||
AC_SUBST([BUILD_ERLANG_ANALYZERS])
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(java-analyzers,
|
|
||||||
AS_HELP_STRING([--disable-java-analyzers],
|
|
||||||
[do not build the Java analyzers (default is to build them)]),
|
|
||||||
,
|
|
||||||
enable_java_analyzers=yes)
|
|
||||||
BUILD_JAVA_ANALYZERS=$enable_java_analyzers
|
|
||||||
AC_SUBST([BUILD_JAVA_ANALYZERS])
|
|
||||||
|
|
||||||
AC_ARG_WITH(fcp-clang,
|
|
||||||
AS_HELP_STRING([--with-fcp-clang],
|
|
||||||
[use $CLANG_PREFIX/bin/clang to override the default compiler (default is not to override)]),
|
|
||||||
,
|
|
||||||
with_fcp_clang=no)
|
|
||||||
|
|
||||||
AS_IF([test "x$enable_c_analyzers" = "xyes"], [
|
|
||||||
AC_MSG_CHECKING([whether to use the compilers in $CLANG_PREFIX/bin])
|
|
||||||
case "$with_fcp_clang" in
|
|
||||||
no)
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
;;
|
|
||||||
yes)
|
|
||||||
CC=$CLANG_PREFIX/bin/clang
|
|
||||||
CXX=$CLANG_PREFIX/bin/clang++
|
|
||||||
OBJC=$CLANG_PREFIX/bin/clang
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
AC_MSG_ERROR([invalid value for --without-fcp-clang; use "yes" or "no"])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([SHASUM], [shasum], [no])
|
|
||||||
AC_ASSERT_PROG([shasum], [$SHASUM])
|
|
||||||
# cmake is required to build llvm+clang
|
|
||||||
AC_CHECK_TOOL([CMAKE], [cmake], [no])
|
|
||||||
AC_ASSERT_PROG([cmake], [$CMAKE])
|
|
||||||
AC_ARG_ENABLE(ocamlopt-custom-cc,
|
|
||||||
AS_HELP_STRING([--enable-ocamlopt-custom-cc], [use CC in ocamlopt invocations]),
|
|
||||||
,
|
|
||||||
enable_ocamlopt_custom_cc=no)
|
|
||||||
ENABLE_OCAMLOPT_CUSTOM_CC=$enable_ocamlopt_custom_cc
|
|
||||||
AC_SUBST([ENABLE_OCAMLOPT_CUSTOM_CC])
|
|
||||||
])
|
|
||||||
# end if($enable_c_analyzers)
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([XCODE_SELECT], [xcode-select], [no])
|
|
||||||
AS_IF([test "x$XCODE_SELECT" != "xno"], [XCODE_SELECT_OUT=`xcode-select -p`])
|
|
||||||
|
|
||||||
AC_ARG_VAR([XCODE_BASE], [Install location of xcode])
|
|
||||||
AS_IF(
|
|
||||||
[test "x$XCODE_BASE" != "x"],
|
|
||||||
[AC_CHECK_FILE($XCODE_BASE,[HAS_OBJC=yes],[HAS_OBJC=no])],
|
|
||||||
[test "x$XCODE_SELECT" != "xno"],
|
|
||||||
[XCODE_BASE=$XCODE_SELECT_OUT HAS_OBJC=yes],
|
|
||||||
[HAS_OBJC=no])
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([XCRUN], [xcrun], [no])
|
|
||||||
|
|
||||||
AC_ARG_VAR([SDKROOT], [path to the OSX platform SDK used by clang])
|
|
||||||
AS_IF(
|
|
||||||
[test "x$SDKROOT" = "x" && test "x$XCRUN" != "xno"],
|
|
||||||
[SDKROOT=`xcrun --sdk macosx --show-sdk-path`]
|
|
||||||
)
|
|
||||||
|
|
||||||
AC_SUBST([XCODE_BASE])
|
|
||||||
AC_SUBST([HAS_OBJC])
|
|
||||||
AC_SUBST([SDKROOT])
|
|
||||||
|
|
||||||
|
|
||||||
# prefer clang over gcc because the plugins makes use of
|
|
||||||
# clang-specific #pragma's
|
|
||||||
AC_PROG_CC(clang gcc)
|
|
||||||
AC_PROG_AWK
|
|
||||||
AC_PROG_INSTALL
|
|
||||||
AC_PROG_LN_S
|
|
||||||
AC_PROG_MAKE_SET
|
|
||||||
AC_PROG_MKDIR_P
|
|
||||||
|
|
||||||
if test "x$enable_c_analyzers" = "xyes"; then
|
|
||||||
AC_PROG_CPP
|
|
||||||
AC_PROG_CXX(clang++ g++)
|
|
||||||
# AC_PROG_CXX doesn't set CXX to "no" in case of failure (I have no words...); from the manual:
|
|
||||||
# "If none of those checks succeed, then as a last resort set CXX to g++. "
|
|
||||||
AS_IF([$CXX --version > /dev/null], [], [AC_MSG_ERROR([no C++ compiler found])])
|
|
||||||
|
|
||||||
dnl clang wants either clang version >= 3.1 or gcc version >= 4.7.2 to
|
|
||||||
dnl compile itself
|
|
||||||
AC_MSG_CHECKING([if the C/C++ compiler is recent enough])
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
||||||
#ifdef __clang__
|
|
||||||
#if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 1)
|
|
||||||
#error compiler is too old
|
|
||||||
#endif // version check
|
|
||||||
#elif defined __GNUC__ // __clang__
|
|
||||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ < 7 || (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ < 2)))
|
|
||||||
#error compiler is too old
|
|
||||||
#endif // version check
|
|
||||||
#endif // __GNUC__
|
|
||||||
]])],
|
|
||||||
[AC_MSG_RESULT([yes])],
|
|
||||||
[dnl
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
AC_MSG_ERROR([
|
|
||||||
Your C/C++ compiler seems to be too old to build clang, which is
|
|
||||||
required by the facebook-clang-plugins. Please install either
|
|
||||||
gcc version >= 4.7.2 or clang version >= 3.1.
|
|
||||||
|
|
||||||
See the output of `./configure --help` to force the use of a different
|
|
||||||
C compiler.
|
|
||||||
|
|
||||||
Alternatively, you can checkout a binary release of infer:
|
|
||||||
|
|
||||||
https://github.com/facebook/infer/releases/])
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h locale.h malloc.h stddef.h stdint.h stdlib.h string.h sys/mount.h sys/param.h sys/socket.h sys/statfs.h sys/time.h unistd.h wchar.h wctype.h])
|
|
||||||
fi
|
|
||||||
# end if($enable_c_analyzers)
|
|
||||||
|
|
||||||
|
|
||||||
# OCaml dependencies
|
|
||||||
AC_PROG_OCAML
|
|
||||||
AC_ASSERT_PROG([ocamlc], [$OCAMLC])
|
|
||||||
# check the version of OCaml
|
|
||||||
AC_ASSERT_OCAML_MIN_VERSION([4.06.1])
|
|
||||||
AC_ASSERT_PROG([ocamlopt], [$OCAMLOPT])
|
|
||||||
AC_CHECK_TOOL([OCAMLBUILD], [ocamlbuild], [no])
|
|
||||||
AC_ASSERT_PROG([ocamlbuild], [$OCAMLBUILD])
|
|
||||||
AC_PROG_FINDLIB
|
|
||||||
AC_PROG_OCAMLLEX
|
|
||||||
AC_ASSERT_PROG([ocamllex], [$OCAMLLEX])
|
|
||||||
AC_CHECK_TOOL([MENHIR], [menhir], [no])
|
|
||||||
AC_ASSERT_PROG([menhir], [$MENHIR])
|
|
||||||
AC_ASSERT_OCAML_PKG([atdgen])
|
|
||||||
AC_ASSERT_OCAML_PKG([biniou])
|
|
||||||
AC_ASSERT_OCAML_PKG([camlzip], [zip])
|
|
||||||
AC_ASSERT_OCAML_PKG([easy-format])
|
|
||||||
AC_ASSERT_OCAML_PKG([oUnit])
|
|
||||||
AC_CHECK_TOOL([UTOP], [utop], [no])
|
|
||||||
AC_ASSERT_OCAML_PKG([yojson])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([which ocamlformat to use])
|
|
||||||
AS_IF([test x"$is_facebook_tree" = x"yes"],
|
|
||||||
[OCAMLFORMAT="$(pwd)"/facebook/dependencies/bin/ocamlformat],
|
|
||||||
[OCAMLFORMAT=ocamlformat])
|
|
||||||
AC_MSG_RESULT([$OCAMLFORMAT])
|
|
||||||
AC_SUBST([OCAMLFORMAT])
|
|
||||||
|
|
||||||
AC_ARG_VAR([CPATH], [Additional directories to search for C headers.])
|
|
||||||
AC_ARG_VAR([LIBRARY_PATH], [Additional directories to search for C shared objects.])
|
|
||||||
AC_ARG_VAR([CAML_LD_LIBRARY_PATH],
|
|
||||||
[Additional directories to search for dynamically-loaded libraries.])
|
|
||||||
AC_ARG_VAR([OPAMROOT], [Root of the local opam installation.])
|
|
||||||
AC_ARG_VAR([OPAMSWITCH], [Opam switch used for building infer.])
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([OPAM], [opam], [no])
|
|
||||||
AS_IF([test "$OPAM" != "no"], [
|
|
||||||
AC_MSG_CHECKING([opam version])
|
|
||||||
opam_version=$(opam --version)
|
|
||||||
case $opam_version in
|
|
||||||
2.*) AC_MSG_RESULT([$opam_version]); break;;
|
|
||||||
*) AC_MSG_ERROR([opam version $opam_version is not supported, please install opam version 2 instead]); break;;
|
|
||||||
esac
|
|
||||||
AC_MSG_CHECKING([current opam root])
|
|
||||||
OPAMROOT=$("$OPAM" config var root)
|
|
||||||
AC_MSG_RESULT([$OPAMROOT])
|
|
||||||
AC_MSG_CHECKING([current opam switch])
|
|
||||||
OPAMSWITCH=$("$OPAM" switch show)
|
|
||||||
AC_MSG_RESULT([$OPAMSWITCH])
|
|
||||||
], [
|
|
||||||
OPAMROOT=no
|
|
||||||
OPAMSWITCH=no
|
|
||||||
])
|
|
||||||
AC_SUBST([OPAMROOT])
|
|
||||||
AC_SUBST([OPAMSWITCH])
|
|
||||||
|
|
||||||
if test "x$enable_erlang_analyzers" = "xyes"; then
|
|
||||||
AC_CHECK_TOOL([ESCRIPT], [escript], [no])
|
|
||||||
AC_CHECK_TOOL([REBAR3], [rebar3], [no])
|
|
||||||
fi
|
|
||||||
# end if($enable_erlang_analyzers)
|
|
||||||
|
|
||||||
if test "x$enable_java_analyzers" = "xyes"; then
|
|
||||||
AC_CHECK_TOOL([JAVA], [java], [no])
|
|
||||||
AC_CHECK_TOOL([JAVAC], [javac], [no])
|
|
||||||
AC_ASSERT_PROG([javac], [$JAVAC])
|
|
||||||
AC_ASSERT_PROG([java], [$JAVA])
|
|
||||||
AC_ASSERT_OCAML_PKG([javalib])
|
|
||||||
AC_ASSERT_OCAML_PKG([sawja])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([for Java major version])
|
|
||||||
JAVA_MAJOR_VERSION=`"$JAVAC" -version 2>&1 | head -n 1 | cut -d ' ' -f 2`
|
|
||||||
AS_IF([test "x`echo $JAVA_MAJOR_VERSION | cut -d '.' -f 1`" = "x1"], [
|
|
||||||
# version 1.8.xx -> 8
|
|
||||||
JAVA_MAJOR_VERSION=`echo $JAVA_MAJOR_VERSION | cut -d '.' -f 2`
|
|
||||||
], [
|
|
||||||
# otherwise pick the first number as the major version
|
|
||||||
JAVA_MAJOR_VERSION=`echo $JAVA_MAJOR_VERSION | cut -d '.' -f 1`
|
|
||||||
])
|
|
||||||
AC_MSG_RESULT([$JAVA_MAJOR_VERSION])
|
|
||||||
AC_SUBST([JAVA_MAJOR_VERSION])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([for JAVA_HOME])
|
|
||||||
cat - <<_ACEOF >conftest.java
|
|
||||||
public class conftest {
|
|
||||||
public static void main(String[[]] args) {
|
|
||||||
System.out.println(System.getProperty("java.home"));
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ACEOF
|
|
||||||
rm -f conftest.class
|
|
||||||
if "$JAVAC" conftest.java; then
|
|
||||||
rm -f conftest.java
|
|
||||||
_USER_JAVA_HOME=$($JAVA -cp . conftest)
|
|
||||||
if rm -f conftest.class; then
|
|
||||||
[javac_version_10_or_more=`echo "$JAVA_MAJOR_VERSION" | grep -q -e '^1[0-9]' && echo yes`]
|
|
||||||
if test "x$javac_version_10_or_more" = "xyes"; then
|
|
||||||
USER_JAVA_HOME=$_USER_JAVA_HOME
|
|
||||||
else
|
|
||||||
USER_JAVA_HOME=$_USER_JAVA_HOME/..
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_ERROR([Could not run test program with $JAVA])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
rm -f conftest.java
|
|
||||||
AC_MSG_ERROR([Could not compile test program with $JAVAC])
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$USER_JAVA_HOME])
|
|
||||||
AC_SUBST([USER_JAVA_HOME])
|
|
||||||
|
|
||||||
AC_CHECK_LIB([z], [inflateEnd], [ZLIB_FOUND=yes], [ZLIB_FOUND=no])
|
|
||||||
AS_IF([test x"$ZLIB_FOUND" = xno], [AC_MSG_ERROR([zlib not found.])])
|
|
||||||
fi
|
|
||||||
# end if($enable_java_analyzers)
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([ATDGEN], [atdgen], [no])
|
|
||||||
AC_ASSERT_PROG([atdgen], [$ATDGEN])
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(ocaml-bin-annot,
|
|
||||||
AS_HELP_STRING([--disable-ocaml-bin-annot], [do not build ocaml .cmt files]),
|
|
||||||
,
|
|
||||||
enable_ocaml_bin_annot=yes)
|
|
||||||
ENABLE_OCAML_BINANNOT=$enable_ocaml_bin_annot
|
|
||||||
AC_SUBST([ENABLE_OCAML_BINANNOT])
|
|
||||||
|
|
||||||
|
|
||||||
# We use Buck to run the Infer tests
|
|
||||||
AS_IF([test x"$is_facebook_tree" = x"yes"],
|
|
||||||
AC_MSG_CHECKING([which .buckjavaversion to use])
|
|
||||||
cp "facebook/dependencies/dotbuckjavaversion" ".buckjavaversion"
|
|
||||||
AC_MSG_RESULT([facebook/dependencies/dotbuckjavaversion])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([which .buck-java11 to use])
|
|
||||||
cp "facebook/dependencies/dotbuck-java11" ".buck-java11"
|
|
||||||
AC_MSG_RESULT([facebook/dependencies/dotbuck-java11]))
|
|
||||||
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([GETCONF], [getconf], [no])
|
|
||||||
AC_MSG_CHECKING([the number of cpus the build host has])
|
|
||||||
if test "$GETCONF" != "no"; then
|
|
||||||
if test $("$GETCONF" _NPROCESSORS_ONLN); then
|
|
||||||
NCPU=$("$GETCONF" _NPROCESSORS_ONLN)
|
|
||||||
AC_MSG_RESULT([$NCPU])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
NCPU=1
|
|
||||||
AC_MSG_RESULT([failed, defaulting to 1])
|
|
||||||
fi
|
|
||||||
AC_SUBST([NCPU])
|
|
||||||
|
|
||||||
# optional progs and libraries that, eg build systems to be run in integration tests
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([ANT], [ant], [no])
|
|
||||||
AC_CHECK_TOOL([BUCK], [buck], [no])
|
|
||||||
AC_CHECK_TOOL([EMACS], [emacs], [no])
|
|
||||||
AC_ARG_VAR([MVN], [command to execute Maven when running tests])
|
|
||||||
AS_IF([test "x$MVN" = "x"], [
|
|
||||||
AC_CHECK_TOOL([MVN], [mvn], [no])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT([checking for mvn... $MVN])
|
|
||||||
])
|
|
||||||
AC_CHECK_TOOL([NDKBUILD], [ndk-build], [no])
|
|
||||||
if test x"$NDKBUILD" = x"no"; then
|
|
||||||
# ndk-build not in $PATH, look into potential android NDK install paths and record the absolute path
|
|
||||||
# to ndk-build
|
|
||||||
AC_PATH_PROG([NDKBUILD], [ndk-build], [no],
|
|
||||||
[$PATH$PATH_SEPARATOR$ANDROID_NDK$PATH_SEPARATOR/opt/android_ndk/r15c])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([NINJA], [ninja], [no])
|
|
||||||
AC_CHECK_TOOL([XCPRETTY], [xcpretty], [no])
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([SED], [sed], [no])
|
|
||||||
AS_IF([test "$SED" != "xno"], [
|
|
||||||
AC_MSG_CHECKING([if sed is GNU sed])
|
|
||||||
AS_IF(["$SED" --version 2> /dev/null | grep -q -e "GNU sed"], [
|
|
||||||
GNU_SED="$SED"
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
AC_CHECK_TOOL([GNU_SED], [gsed], [no])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
AC_SUBST([GNU_SED])
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([BREW], [brew], [no])
|
|
||||||
|
|
||||||
AC_CHECK_TOOL([INSTALL_NAME_TOOL], [install_name_tool], [no])
|
|
||||||
AC_SUBST([INSTALL_NAME_TOOL])
|
|
||||||
AC_CHECK_TOOL([LDD], [ldd], [no])
|
|
||||||
AC_SUBST([LDD])
|
|
||||||
AC_CHECK_TOOL([OTOOL], [otool], [no])
|
|
||||||
AC_SUBST([OTOOL])
|
|
||||||
AC_CHECK_TOOL([PATCHELF], [patchelf], [no])
|
|
||||||
AC_SUBST([PATCHELF])
|
|
||||||
|
|
||||||
AC_CHECK_INFER_MAN_LAST_MODIFIED()
|
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
|
||||||
Makefile.autoconf
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_OUTPUT
|
|
@ -1,17 +0,0 @@
|
|||||||
java_library(
|
|
||||||
name = 'java_libraries',
|
|
||||||
deps=[
|
|
||||||
'//dependencies/java/guava:guava',
|
|
||||||
'//dependencies/java/junit:hamcrest',
|
|
||||||
'//dependencies/java/jackson:jackson',
|
|
||||||
'//dependencies/java/jsr-305:jsr-305',
|
|
||||||
'//dependencies/java/junit:junit',
|
|
||||||
'//dependencies/java/opencsv:opencsv'
|
|
||||||
],
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC'
|
|
||||||
]
|
|
||||||
)
|
|
||||||
project_config(
|
|
||||||
src_target = ':java_libraries',
|
|
||||||
)
|
|
@ -1,7 +0,0 @@
|
|||||||
prebuilt_jar(
|
|
||||||
name = 'android-support-v4',
|
|
||||||
binary_jar = 'android-support-v4.jar',
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC',
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
@ -1,7 +0,0 @@
|
|||||||
prebuilt_jar(
|
|
||||||
name = 'guava',
|
|
||||||
binary_jar = 'guava-23.0.jar',
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC'
|
|
||||||
]
|
|
||||||
)
|
|
Binary file not shown.
@ -1,10 +0,0 @@
|
|||||||
prebuilt_jar(
|
|
||||||
name = 'jackson',
|
|
||||||
binary_jar = 'jackson-2.2.3.jar',
|
|
||||||
deps = [
|
|
||||||
'//dependencies/java/guava:guava',
|
|
||||||
],
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC',
|
|
||||||
]
|
|
||||||
)
|
|
Binary file not shown.
@ -1,8 +0,0 @@
|
|||||||
prebuilt_jar(
|
|
||||||
name = 'jsr-305',
|
|
||||||
binary_jar = 'jsr305.jar',
|
|
||||||
source_jar = 'jsr305-src.jar',
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC',
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
@ -1,7 +0,0 @@
|
|||||||
prebuilt_jar(
|
|
||||||
name = 'jsr-330',
|
|
||||||
binary_jar = 'javax.inject.jar',
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC',
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
@ -1,7 +0,0 @@
|
|||||||
prebuilt_jar(
|
|
||||||
name = 'sun-tools',
|
|
||||||
binary_jar = 'tools.jar',
|
|
||||||
visibility = [
|
|
||||||
'PUBLIC'
|
|
||||||
]
|
|
||||||
)
|
|
Binary file not shown.
@ -1,2 +0,0 @@
|
|||||||
Ocamldot was written by Trevor Jim. It is in the public domain; use
|
|
||||||
it however you like, at your own risk.
|
|
@ -1,28 +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.
|
|
||||||
|
|
||||||
# Try to automatically guess whether we are running under Windows.
|
|
||||||
# Set WIN32=true manually if this doesn't work.
|
|
||||||
#
|
|
||||||
ifeq (${OSTYPE},cygwin32) # Cygwin Beta 19
|
|
||||||
WIN32=true
|
|
||||||
else
|
|
||||||
ifeq (${OSTYPE},cygwin) # Cygwin Beta 20
|
|
||||||
WIN32=true
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef WIN32
|
|
||||||
EXE=.exe
|
|
||||||
else # UNIX
|
|
||||||
EXE=
|
|
||||||
endif
|
|
||||||
|
|
||||||
ocamldot$(EXE): ocamldot.mll
|
|
||||||
ocamllex ocamldot.mll
|
|
||||||
ocamlc -o $@ ocamldot.ml
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) ocamldot$(EXE) ocamldot.ml *.cmi *.cmo *.o *.obj
|
|
@ -1,34 +0,0 @@
|
|||||||
Ocamldot generates program dependency graphs for ocaml programs.
|
|
||||||
|
|
||||||
The dependency graph output by ocamldot can be rendered by a separate
|
|
||||||
program, dot. Dot is freely available from
|
|
||||||
|
|
||||||
http://www.research.att.com/sw/tools/graphviz/
|
|
||||||
|
|
||||||
Ocamldot is designed to process the output of ocamldep. A typical use
|
|
||||||
would be
|
|
||||||
|
|
||||||
ocamldep *.ml | ocamldot > dep.dot
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
ocamldep *.ml > .depend
|
|
||||||
ocamldot .depend > dep.dot
|
|
||||||
|
|
||||||
This will output a dot graph into the file dep.dot. You can then use
|
|
||||||
the program dotty to view, edit, and print the graph.
|
|
||||||
|
|
||||||
Ocamldot has the following options:
|
|
||||||
|
|
||||||
-fullgraph draw the full graph (default is to draw only the kernel)
|
|
||||||
-landscape output in landscape format (default is portrait)
|
|
||||||
-lr draw graph from left to right (default is top to bottom)
|
|
||||||
-r <r> use <r> as a root in the graph; nodes reachable from <r>
|
|
||||||
will be shown
|
|
||||||
|
|
||||||
(The transitive kernel of a dag is the smallest subset of the dag
|
|
||||||
whose transitive closure is the same as the transitive closure of the
|
|
||||||
dag. For example, the kernel of A->B, A->C, B->C is just the two
|
|
||||||
edges A->B, B->C.)
|
|
||||||
|
|
||||||
-Trevor Jim
|
|
@ -1,52 +0,0 @@
|
|||||||
.TH OCAMLDOT 1
|
|
||||||
.SH NAME
|
|
||||||
ocamldot \- generate dependency graphs of ocaml programs
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B ocamldot
|
|
||||||
.I
|
|
||||||
.RI "[options] <dependency-file>"
|
|
||||||
.SH "DESCRIPTION"
|
|
||||||
This manual page documents briefly the
|
|
||||||
.BR ocamldot
|
|
||||||
command.
|
|
||||||
.PP
|
|
||||||
.B ocamldot
|
|
||||||
generates program dependency graphs for ocaml programs. The
|
|
||||||
dependency graph output by ocamldot can be rendered by a separate
|
|
||||||
program, \fIdot\fR.
|
|
||||||
.P
|
|
||||||
Ocamldot is designed to process the output of ocamldep. A typical use would be
|
|
||||||
.P
|
|
||||||
ocamldep *.ml | ocamldot > dep.dot
|
|
||||||
.P
|
|
||||||
or
|
|
||||||
.P
|
|
||||||
ocamldep *.ml > .depend
|
|
||||||
.br
|
|
||||||
ocamldot .depend > dep.dot
|
|
||||||
.SH OPTIONS
|
|
||||||
.TP
|
|
||||||
.B \-fullgraph
|
|
||||||
Draw the full graph (default is to draw only the kernel)
|
|
||||||
.TP
|
|
||||||
.B \-landscape
|
|
||||||
Output in landscape format (default is portrait)
|
|
||||||
.TP
|
|
||||||
.B \-lr
|
|
||||||
Draw graph from left to right (default is top to bottom)
|
|
||||||
.TP
|
|
||||||
.B \-r <r>
|
|
||||||
Use \fI<r>\fR as a root in the graph; nodes reachable from \fI<r>\fR
|
|
||||||
will be shown.
|
|
||||||
.P
|
|
||||||
The transitive kernel of a dag is the smallest subset of the dag whose transitive closure is the same as the transitive closure of the dag.
|
|
||||||
For example, the kernel of A->B, A->C, B->C is just the two edges A->B, B->C.
|
|
||||||
|
|
||||||
.SH SEE ALSO
|
|
||||||
.BR ocamldep (1),
|
|
||||||
.BR dot(1)
|
|
||||||
.P
|
|
||||||
\fIhttp://www.research.att.com/~trevor/ocamldot\fR.
|
|
||||||
|
|
||||||
.SH AUTHOR
|
|
||||||
Trevor Jim <trevor@research.att.com>
|
|
@ -1,436 +0,0 @@
|
|||||||
(* ocamldot.mll, July 1999, Trevor Jim *)
|
|
||||||
|
|
||||||
{
|
|
||||||
module StringSet =
|
|
||||||
Set.Make(struct type t = string let compare = compare end)
|
|
||||||
|
|
||||||
module StringMap =
|
|
||||||
Map.Make(struct type t = string let compare = compare end)
|
|
||||||
|
|
||||||
let dependencies = ref []
|
|
||||||
let currentSource = ref ""
|
|
||||||
let addDepend t =
|
|
||||||
let s = !currentSource in
|
|
||||||
if s<>t
|
|
||||||
then dependencies := (s,t)::(!dependencies)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
rule processSource = parse
|
|
||||||
['.' '-' '/' 'A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246'
|
|
||||||
'\248'-'\255' '\'' '0'-'9' ]+ '.' ['A'-'Z' 'a'-'z']+
|
|
||||||
[' ' '\009']* ':'
|
|
||||||
{ let s = Lexing.lexeme lexbuf in
|
|
||||||
let i = String.rindex s '.' in
|
|
||||||
let s = String.sub s 0 i in
|
|
||||||
let s = Filename.basename s in
|
|
||||||
let s = String.capitalize s in
|
|
||||||
currentSource := s;
|
|
||||||
processTargets lexbuf }
|
|
||||||
| eof
|
|
||||||
{ () }
|
|
||||||
| _
|
|
||||||
{ processSource lexbuf }
|
|
||||||
|
|
||||||
and processTargets = parse
|
|
||||||
[' ' '\009']+
|
|
||||||
{ processTargets lexbuf }
|
|
||||||
| '\\' [' ' '\009']* ['\010' '\013']+ [' ' '\009']+
|
|
||||||
{ processTargets lexbuf }
|
|
||||||
| ['.' '/' 'A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246'
|
|
||||||
'\248'-'\255' '\'' '0'-'9' ]+ '.' ['A'-'Z' 'a'-'z']+
|
|
||||||
{ let t = Lexing.lexeme lexbuf in
|
|
||||||
let i = String.rindex t '.' in
|
|
||||||
let t = String.sub t 0 i in
|
|
||||||
let t = Filename.basename t in
|
|
||||||
let t = String.capitalize t in
|
|
||||||
addDepend t;
|
|
||||||
processTargets lexbuf }
|
|
||||||
| eof
|
|
||||||
{ () }
|
|
||||||
| _
|
|
||||||
{ processSource lexbuf }
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
(********************************)
|
|
||||||
(* Utility functions for graphs *)
|
|
||||||
(********************************)
|
|
||||||
|
|
||||||
|
|
||||||
(**********************************************************************)
|
|
||||||
(* A graph is represented by a (string * StringSet) list, *)
|
|
||||||
(* that is, a list of (source,targets) pairs. *)
|
|
||||||
(**********************************************************************)
|
|
||||||
|
|
||||||
let emptyGraph = []
|
|
||||||
|
|
||||||
(**********************************************************************)
|
|
||||||
(* divideGraph graph source = (sourceTargets, graphWithoutSource) *)
|
|
||||||
(* *)
|
|
||||||
(* Return the targets of a source in a graph and the graph with the *)
|
|
||||||
(* source substracted from the sources. GraphWithoutSources may *)
|
|
||||||
(* still contain source as a target. *)
|
|
||||||
(**********************************************************************)
|
|
||||||
let divideGraph graph source =
|
|
||||||
let rec aux l =
|
|
||||||
match l with
|
|
||||||
[] -> (StringSet.empty,[])
|
|
||||||
| (s,ts)::tl ->
|
|
||||||
if s=source then (ts,tl)
|
|
||||||
else
|
|
||||||
let (sourceTargets,tlWithoutSource) = aux tl in
|
|
||||||
(sourceTargets,(s,ts)::tlWithoutSource) in
|
|
||||||
aux graph
|
|
||||||
|
|
||||||
(*********************************************)
|
|
||||||
(* Add the edge (source,target) to the graph *)
|
|
||||||
(*********************************************)
|
|
||||||
let addEdge graph source target =
|
|
||||||
let (sourceTargets,graphWithoutSource) = divideGraph graph source in
|
|
||||||
(source,StringSet.add target sourceTargets)::graphWithoutSource
|
|
||||||
|
|
||||||
(************************************************************)
|
|
||||||
(* Add the edges { (source,t) | t in targets } to the graph *)
|
|
||||||
(************************************************************)
|
|
||||||
let addEdges graph source targets =
|
|
||||||
let (sourceTargets,graphWithoutSource) = divideGraph graph source in
|
|
||||||
(source,StringSet.union targets sourceTargets)::graphWithoutSource
|
|
||||||
|
|
||||||
(**************************************************)
|
|
||||||
(* Remove the edge (source,target) from the graph *)
|
|
||||||
(**************************************************)
|
|
||||||
let removeEdge graph source target =
|
|
||||||
let rec loop l =
|
|
||||||
match l with
|
|
||||||
[] -> []
|
|
||||||
| (s,ts)::tl ->
|
|
||||||
if s=source
|
|
||||||
then (s,StringSet.remove target ts)::tl
|
|
||||||
else (s,ts)::(loop tl)
|
|
||||||
in loop graph
|
|
||||||
|
|
||||||
(*****************************************************************)
|
|
||||||
(* Remove the edges { (source,t) | t in targets } from the graph *)
|
|
||||||
(*****************************************************************)
|
|
||||||
let removeEdges graph source targets =
|
|
||||||
let rec loop l =
|
|
||||||
match l with
|
|
||||||
[] -> []
|
|
||||||
| (s,ts)::tl ->
|
|
||||||
if s=source
|
|
||||||
then (s,StringSet.diff ts targets)::tl
|
|
||||||
else (s,ts)::(loop tl)
|
|
||||||
in loop graph
|
|
||||||
|
|
||||||
(**********************************************************************)
|
|
||||||
(* Convert between an edge-list representation of graphs and our *)
|
|
||||||
(* representation. *)
|
|
||||||
(**********************************************************************)
|
|
||||||
let edgesOfGraph graph =
|
|
||||||
List.concat
|
|
||||||
(List.map
|
|
||||||
(fun (s,ts) ->
|
|
||||||
List.map (fun t -> (s,t)) (StringSet.elements ts))
|
|
||||||
graph)
|
|
||||||
|
|
||||||
let graphOfEdges edges =
|
|
||||||
List.fold_left
|
|
||||||
(fun g (s,t) -> addEdge g s t)
|
|
||||||
emptyGraph
|
|
||||||
edges
|
|
||||||
|
|
||||||
(****************************)
|
|
||||||
(* Is an edge in the graph? *)
|
|
||||||
(****************************)
|
|
||||||
let isEdge graph source target =
|
|
||||||
try
|
|
||||||
let sourceTargets = List.assoc source graph in
|
|
||||||
StringSet.mem target sourceTargets
|
|
||||||
with Not_found -> false
|
|
||||||
|
|
||||||
(*****************)
|
|
||||||
(* Print a graph *)
|
|
||||||
(*****************)
|
|
||||||
let printGraph graph =
|
|
||||||
let printEdges(source,targets) =
|
|
||||||
StringSet.iter
|
|
||||||
(fun t -> Printf.printf " \"%s\" -> \"%s\" ;\n" source t)
|
|
||||||
targets in
|
|
||||||
List.iter printEdges graph
|
|
||||||
|
|
||||||
(********************************)
|
|
||||||
(* Targets of a node in a graph *)
|
|
||||||
(********************************)
|
|
||||||
let targetsOf graph node = (* A set of nodes *)
|
|
||||||
try List.assoc node graph
|
|
||||||
with Not_found -> StringSet.empty
|
|
||||||
|
|
||||||
(*****************************************)
|
|
||||||
(* Sources that target a node in a graph *)
|
|
||||||
(*****************************************)
|
|
||||||
let sourcesOf graph node = (* A list of nodes *)
|
|
||||||
let rec aux l =
|
|
||||||
match l with
|
|
||||||
[] -> []
|
|
||||||
| (s,ts)::tl ->
|
|
||||||
if StringSet.mem node ts then s::(aux tl)
|
|
||||||
else aux tl in
|
|
||||||
aux graph
|
|
||||||
|
|
||||||
(******************************************************************)
|
|
||||||
(* Add an edge to a transitively closed graph, and return the new *)
|
|
||||||
(* transitive closure. *)
|
|
||||||
(******************************************************************)
|
|
||||||
let addEdgeTc graph source target =
|
|
||||||
let targetTargets = targetsOf graph target in
|
|
||||||
let (sourceTargets,graphWithoutSource) = divideGraph graph source in
|
|
||||||
let sourceSources = sourcesOf graphWithoutSource source in
|
|
||||||
let newSourceTargets =
|
|
||||||
StringSet.add target
|
|
||||||
(StringSet.union sourceTargets targetTargets) in
|
|
||||||
(source,newSourceTargets)::
|
|
||||||
(List.fold_right
|
|
||||||
(fun s g -> addEdges g s newSourceTargets)
|
|
||||||
sourceSources
|
|
||||||
graphWithoutSource)
|
|
||||||
|
|
||||||
(**********************************************************)
|
|
||||||
(* Compute the transitive closure of a graph from scratch *)
|
|
||||||
(**********************************************************)
|
|
||||||
let tc graph =
|
|
||||||
let loop graph (source,targets) =
|
|
||||||
let reachableFromSource =
|
|
||||||
List.fold_left
|
|
||||||
(fun r (s,ts) ->
|
|
||||||
if StringSet.mem s r then StringSet.union r ts
|
|
||||||
else r)
|
|
||||||
targets
|
|
||||||
graph in
|
|
||||||
(source,reachableFromSource)::
|
|
||||||
(List.map
|
|
||||||
(fun (s,ts) ->
|
|
||||||
if StringSet.mem source ts
|
|
||||||
then (s,StringSet.union ts reachableFromSource)
|
|
||||||
else (s,ts))
|
|
||||||
graph) in
|
|
||||||
List.fold_left loop [] graph
|
|
||||||
|
|
||||||
(************************************************************************)
|
|
||||||
(* The transitive kernel (tk) of a dag is a subset of the dag whose *)
|
|
||||||
(* transitive closure is the same as the transitive closure of the dag. *)
|
|
||||||
(* *)
|
|
||||||
(* IF THE GRAPH IS NOT A DAG, THIS CODE WON'T WORK PROPERLY!!! *)
|
|
||||||
(************************************************************************)
|
|
||||||
|
|
||||||
(************************************************************************)
|
|
||||||
(* Add an edge to a kernel dag and return the new kernel and transitive *)
|
|
||||||
(* closure of the new kernel. Requires the transitive closure of the *)
|
|
||||||
(* old kernel. *)
|
|
||||||
(************************************************************************)
|
|
||||||
let addEdgeTk kernel tcKernel source target =
|
|
||||||
if isEdge tcKernel source target
|
|
||||||
then (kernel,tcKernel)
|
|
||||||
else if source=target
|
|
||||||
then (addEdge kernel source target,tcKernel)
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
let (sourceTargets,kernelWithoutSource) = divideGraph kernel source in
|
|
||||||
let targetTargets = StringSet.add target (targetsOf tcKernel target) in
|
|
||||||
let sourceSources = sourcesOf tcKernel source in
|
|
||||||
let kernelWithoutSource =
|
|
||||||
List.fold_left
|
|
||||||
(fun kws s -> removeEdges kws s targetTargets)
|
|
||||||
kernelWithoutSource
|
|
||||||
sourceSources in
|
|
||||||
((source,
|
|
||||||
StringSet.add target
|
|
||||||
(StringSet.diff sourceTargets targetTargets))
|
|
||||||
::kernelWithoutSource,
|
|
||||||
addEdgeTc tcKernel source target)
|
|
||||||
end
|
|
||||||
|
|
||||||
(**********************************)
|
|
||||||
(* The transitive kernel of a dag *)
|
|
||||||
(**********************************)
|
|
||||||
let tk dag =
|
|
||||||
let edges = edgesOfGraph dag in
|
|
||||||
let (kernel,tcKernel) =
|
|
||||||
List.fold_left
|
|
||||||
(fun (k,tck) (s,t) -> addEdgeTk k tck s t)
|
|
||||||
(emptyGraph,emptyGraph)
|
|
||||||
edges in
|
|
||||||
kernel
|
|
||||||
|
|
||||||
(**************************)
|
|
||||||
(* Print the dependencies *)
|
|
||||||
(**************************)
|
|
||||||
let doKernel = ref true
|
|
||||||
let printDepend graph =
|
|
||||||
if (!doKernel) then printGraph (tk graph)
|
|
||||||
else printGraph graph
|
|
||||||
|
|
||||||
let calledOnFile = ref false
|
|
||||||
let getDependFromFile file =
|
|
||||||
calledOnFile := true;
|
|
||||||
try
|
|
||||||
let ic = open_in file in
|
|
||||||
let lexbuf = Lexing.from_channel ic in
|
|
||||||
processSource lexbuf;
|
|
||||||
close_in ic
|
|
||||||
with Sys_error msg -> ()
|
|
||||||
| Exit -> ()
|
|
||||||
let getDependFromStdin () =
|
|
||||||
try
|
|
||||||
let lexbuf = Lexing.from_channel stdin in
|
|
||||||
processSource lexbuf
|
|
||||||
with Sys_error msg -> ()
|
|
||||||
| Exit -> ()
|
|
||||||
|
|
||||||
(**********************************)
|
|
||||||
(* Color and Cluster by directory *)
|
|
||||||
(**********************************)
|
|
||||||
|
|
||||||
let fold_dir f init path =
|
|
||||||
let collect cur_dir path (acum, dirs) =
|
|
||||||
let full_path = Filename.concat cur_dir path in
|
|
||||||
try
|
|
||||||
if Sys.is_directory full_path then
|
|
||||||
(acum, full_path :: dirs)
|
|
||||||
else
|
|
||||||
(f acum full_path, dirs)
|
|
||||||
with Sys_error _ ->
|
|
||||||
(acum, dirs) in
|
|
||||||
let rec fold_dir_ (acum, dirs) =
|
|
||||||
match dirs with
|
|
||||||
| [] ->
|
|
||||||
acum
|
|
||||||
| dir :: dirs ->
|
|
||||||
fold_dir_ (Array.fold_left (fun ad p -> collect dir p ad) (acum, dirs) (Sys.readdir dir)) in
|
|
||||||
if Sys.is_directory path then
|
|
||||||
fold_dir_ (init, [path])
|
|
||||||
else
|
|
||||||
f init path
|
|
||||||
|
|
||||||
let dir_to_mod_names graph dir =
|
|
||||||
let nodes =
|
|
||||||
List.fold_left (fun nodes (source, targets) ->
|
|
||||||
StringSet.add source (StringSet.union targets nodes)
|
|
||||||
) StringSet.empty graph in
|
|
||||||
fold_dir (fun dir_to_mod_names path ->
|
|
||||||
let file = Filename.basename path in
|
|
||||||
let mod_name = String.capitalize (try Filename.chop_extension file with _ -> file) in
|
|
||||||
if ((Filename.check_suffix file ".ml")
|
|
||||||
&& StringSet.mem mod_name nodes)
|
|
||||||
then
|
|
||||||
let dir = Filename.dirname path in
|
|
||||||
let files = mod_name :: (try StringMap.find dir dir_to_mod_names with Not_found -> []) in
|
|
||||||
StringMap.add dir files dir_to_mod_names
|
|
||||||
else
|
|
||||||
dir_to_mod_names
|
|
||||||
) StringMap.empty dir
|
|
||||||
|
|
||||||
let printColors dir_to_mod_names =
|
|
||||||
let num_dirs = StringMap.cardinal dir_to_mod_names in
|
|
||||||
let hsv i s v = Printf.sprintf "\"%f %f %f\"" ((float)i *. (1. /. (float)num_dirs)) s v in
|
|
||||||
StringMap.fold (fun dir mod_names i ->
|
|
||||||
List.iter (fun mod_name ->
|
|
||||||
Printf.printf "\"%s\" [style = filled, fillcolor = %s] ;\n" mod_name (hsv i 0.5 0.9) ;
|
|
||||||
) mod_names ;
|
|
||||||
i + 1
|
|
||||||
) dir_to_mod_names 0
|
|
||||||
|> ignore
|
|
||||||
|
|
||||||
let printClusters clusterDirs dir_to_mod_names =
|
|
||||||
StringMap.iter (fun dir mod_names ->
|
|
||||||
let base = Filename.basename dir in
|
|
||||||
if StringSet.mem base clusterDirs then (
|
|
||||||
Printf.printf "subgraph cluster_%s { label=\"%s\" ;\n" base base;
|
|
||||||
List.iter (fun mod_name ->
|
|
||||||
Printf.printf "\"%s\" ;\n" mod_name
|
|
||||||
) mod_names ;
|
|
||||||
Printf.printf "}\n"
|
|
||||||
)
|
|
||||||
) dir_to_mod_names
|
|
||||||
|
|
||||||
let colorAndCluster clusterDirs graph dir =
|
|
||||||
let dir_to_mod_names = dir_to_mod_names graph dir in
|
|
||||||
printColors dir_to_mod_names ;
|
|
||||||
printClusters clusterDirs dir_to_mod_names
|
|
||||||
|
|
||||||
|
|
||||||
(***************)
|
|
||||||
(* Entry point *)
|
|
||||||
(***************)
|
|
||||||
|
|
||||||
let usage = "Usage: ocamldot [options] <files>"
|
|
||||||
|
|
||||||
let clusters = ref []
|
|
||||||
let leftToRight = ref false
|
|
||||||
let landscape = ref false
|
|
||||||
let roots = ref []
|
|
||||||
;;
|
|
||||||
|
|
||||||
Arg.parse (Arg.align
|
|
||||||
[
|
|
||||||
("-c",
|
|
||||||
Arg.String(fun s -> clusters := s::!clusters),
|
|
||||||
"<c> cluster the modules in the <c> directory in the graph");
|
|
||||||
("-fullgraph",
|
|
||||||
Arg.Clear doKernel,
|
|
||||||
" draw the full graph (default is to draw only the kernel)");
|
|
||||||
("-landscape",
|
|
||||||
Arg.Set landscape,
|
|
||||||
" output in landscape format (default is portrait)");
|
|
||||||
("-lr",
|
|
||||||
Arg.Set leftToRight,
|
|
||||||
" draw graph from left to right (default is top to bottom)");
|
|
||||||
("-r",
|
|
||||||
Arg.String(fun s -> roots := s::!roots),
|
|
||||||
"<r> use <r> as a root in the graph; nodes reachable from <r> will be shown")
|
|
||||||
])
|
|
||||||
getDependFromFile usage;
|
|
||||||
if not(!calledOnFile) then getDependFromStdin();
|
|
||||||
print_string "digraph G {\n";
|
|
||||||
if !landscape
|
|
||||||
then print_string " size=\"10,7.5\" ;\n rotate=90 ;\n"
|
|
||||||
else print_string " size=\"7.5,10\" ;\n";
|
|
||||||
if (!leftToRight) then print_string " rankdir = LR ;\n"
|
|
||||||
else print_string " rankdir = TB ;\n";
|
|
||||||
let graph = graphOfEdges(!dependencies) in
|
|
||||||
begin
|
|
||||||
match !roots with
|
|
||||||
[] -> printDepend graph
|
|
||||||
| roots ->
|
|
||||||
(* Set up the graph so that the roots are printed at the same level *)
|
|
||||||
print_string " { rank=same ;\n";
|
|
||||||
List.iter
|
|
||||||
(fun r ->
|
|
||||||
print_string " ";
|
|
||||||
print_string r;
|
|
||||||
print_string " ;\n")
|
|
||||||
roots;
|
|
||||||
print_string " };\n";
|
|
||||||
(* Find the graph reachable from the roots *)
|
|
||||||
let tcGraph = tc graph in
|
|
||||||
let reachable node =
|
|
||||||
(List.exists (fun r -> r=node) roots)
|
|
||||||
||
|
|
||||||
(List.exists (fun r -> isEdge tcGraph r node) roots) in
|
|
||||||
let reachableFromRoots =
|
|
||||||
List.concat
|
|
||||||
(List.map
|
|
||||||
(fun (source,targets) ->
|
|
||||||
if reachable source
|
|
||||||
then [(source,targets)]
|
|
||||||
else [])
|
|
||||||
graph) in
|
|
||||||
printDepend reachableFromRoots;
|
|
||||||
let clusterDirs = List.fold_left (fun z s -> StringSet.add s z) StringSet.empty !clusters in
|
|
||||||
colorAndCluster clusterDirs reachableFromRoots (Sys.getcwd ())
|
|
||||||
end;
|
|
||||||
print_string "}\n";
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
FROM debian:bullseye-slim
|
|
||||||
|
|
||||||
LABEL maintainer "Infer team"
|
|
||||||
|
|
||||||
# mkdir the man/man1 directory due to Debian bug #863199
|
|
||||||
RUN apt-get update && \
|
|
||||||
mkdir -p /usr/share/man/man1 && \
|
|
||||||
apt-get install --yes --no-install-recommends \
|
|
||||||
curl \
|
|
||||||
libc6-dev \
|
|
||||||
openjdk-11-jdk-headless \
|
|
||||||
sqlite3 \
|
|
||||||
xz-utils \
|
|
||||||
zlib1g-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Download the Infer release
|
|
||||||
RUN INFER_VERSION=v1.1.0; \
|
|
||||||
cd /opt && \
|
|
||||||
curl -sL \
|
|
||||||
https://github.com/facebook/infer/releases/download/${INFER_VERSION}/infer-linux64-${INFER_VERSION}.tar.xz | \
|
|
||||||
tar xJ && \
|
|
||||||
rm -f /infer && \
|
|
||||||
ln -s ${PWD}/infer-linux64-$INFER_VERSION /infer
|
|
||||||
|
|
||||||
# Install infer
|
|
||||||
ENV PATH /infer/bin:${PATH}
|
|
@ -1,37 +0,0 @@
|
|||||||
# docker images for Infer
|
|
||||||
|
|
||||||
This directory, `docker/` inside the Infer repo,
|
|
||||||
contains a docker file to install Infer within a
|
|
||||||
[docker](https://www.docker.com/) container. This can be used to
|
|
||||||
quickly try Infer or to deploy Infer.
|
|
||||||
|
|
||||||
|
|
||||||
## Pre-requisites
|
|
||||||
|
|
||||||
To use this docker image, you will need a working docker
|
|
||||||
installation. See the instructions for
|
|
||||||
[Linux](http://docs.docker.com/linux/step_one/) or
|
|
||||||
[MacOSX](http://docs.docker.com/mac/step_one/) as appropriate.
|
|
||||||
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
This docker file will use the latest
|
|
||||||
[released](https://github.com/facebook/infer/releases) version of
|
|
||||||
Infer.
|
|
||||||
|
|
||||||
1. Get docker running, e.g. using Docker Quickstart Terminal.
|
|
||||||
2. go to the version of your choice, e.g. `cd docker/1.1.0/`
|
|
||||||
3. Build or install Infer in the Docker container and try on an example:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd docker/1.1.0/
|
|
||||||
docker build -t infer .
|
|
||||||
# mount the local examples directory inside the image
|
|
||||||
# you can mount your project directory here instead
|
|
||||||
docker run -it infer -v $PWD/../../examples:/infer-examples /bin/bash
|
|
||||||
# you should now be inside the docker container with a shell prompt, e.g.
|
|
||||||
# "root@5c3b9af90d59:/# "
|
|
||||||
cd /infer-examples/
|
|
||||||
infer -- clang -c hello.c
|
|
||||||
```
|
|
@ -1,69 +0,0 @@
|
|||||||
FROM debian:bullseye-slim AS compilator
|
|
||||||
|
|
||||||
LABEL maintainer "Infer team"
|
|
||||||
|
|
||||||
# mkdir the man/man1 directory due to Debian bug #863199
|
|
||||||
RUN apt-get update && \
|
|
||||||
mkdir -p /usr/share/man/man1 && \
|
|
||||||
apt-get install --yes --no-install-recommends \
|
|
||||||
autoconf \
|
|
||||||
automake \
|
|
||||||
bzip2 \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
g++ \
|
|
||||||
gcc \
|
|
||||||
git \
|
|
||||||
libc6-dev \
|
|
||||||
libgmp-dev \
|
|
||||||
libmpfr-dev \
|
|
||||||
libsqlite3-dev \
|
|
||||||
make \
|
|
||||||
opam \
|
|
||||||
openjdk-11-jdk-headless \
|
|
||||||
patch \
|
|
||||||
patchelf \
|
|
||||||
pkg-config \
|
|
||||||
python3 \
|
|
||||||
python3-distutils \
|
|
||||||
unzip \
|
|
||||||
xz-utils \
|
|
||||||
zlib1g-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Disable sandboxing
|
|
||||||
# Without this opam fails to compile OCaml for some reason. We don't need sandboxing inside a Docker container anyway.
|
|
||||||
RUN opam init --reinit --bare --disable-sandboxing --yes --auto-setup
|
|
||||||
|
|
||||||
# Download the latest Infer master
|
|
||||||
RUN cd / && \
|
|
||||||
git clone --depth 1 https://github.com/facebook/infer/
|
|
||||||
|
|
||||||
# Build opam deps first, then infer. This way if any step fails we
|
|
||||||
# don't lose the significant amount of work done in the previous
|
|
||||||
# steps.
|
|
||||||
RUN cd /infer && ./build-infer.sh java --only-setup-opam
|
|
||||||
RUN cd /infer && ./build-infer.sh java
|
|
||||||
|
|
||||||
# Generate a release
|
|
||||||
RUN cd /infer && \
|
|
||||||
make install-with-libs \
|
|
||||||
BUILD_MODE=opt \
|
|
||||||
PATCHELF=patchelf \
|
|
||||||
DESTDIR="/infer-release" \
|
|
||||||
libdir_relative_to_bindir="../lib"
|
|
||||||
|
|
||||||
FROM debian:buster-slim AS executor
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install --yes --no-install-recommends sqlite3
|
|
||||||
|
|
||||||
# Get the infer release
|
|
||||||
COPY --from=compilator /infer-release/usr/local /infer
|
|
||||||
|
|
||||||
# Install infer
|
|
||||||
ENV PATH /infer/bin:${PATH}
|
|
||||||
|
|
||||||
# if called with /infer-host mounted then copy infer there
|
|
||||||
RUN if test -d /infer-host; then \
|
|
||||||
cp -av /infer/. /infer-host; \
|
|
||||||
fi
|
|
@ -1,74 +0,0 @@
|
|||||||
FROM debian:bullseye-slim AS compilator
|
|
||||||
|
|
||||||
LABEL maintainer "Infer team"
|
|
||||||
|
|
||||||
# mkdir the man/man1 directory due to Debian bug #863199
|
|
||||||
RUN apt-get update && \
|
|
||||||
mkdir -p /usr/share/man/man1 && \
|
|
||||||
apt-get install --yes --no-install-recommends \
|
|
||||||
autoconf \
|
|
||||||
automake \
|
|
||||||
bubblewrap \
|
|
||||||
bzip2 \
|
|
||||||
cmake \
|
|
||||||
curl \
|
|
||||||
g++ \
|
|
||||||
gcc \
|
|
||||||
git \
|
|
||||||
libc6-dev \
|
|
||||||
libgmp-dev \
|
|
||||||
libmpfr-dev \
|
|
||||||
libsqlite3-dev \
|
|
||||||
make \
|
|
||||||
opam \
|
|
||||||
openjdk-11-jdk-headless \
|
|
||||||
patch \
|
|
||||||
patchelf \
|
|
||||||
pkg-config \
|
|
||||||
python3 \
|
|
||||||
python3-distutils \
|
|
||||||
unzip \
|
|
||||||
xz-utils \
|
|
||||||
zlib1g-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Disable sandboxing
|
|
||||||
# Without this opam fails to compile OCaml for some reason. We don't need sandboxing inside a Docker container anyway.
|
|
||||||
RUN opam init --reinit --bare --disable-sandboxing --yes --auto-setup
|
|
||||||
|
|
||||||
# Download the latest Infer master
|
|
||||||
RUN cd / && \
|
|
||||||
git clone --depth 1 https://github.com/facebook/infer/
|
|
||||||
|
|
||||||
# Build opam deps first, then clang, then infer. This way if any step
|
|
||||||
# fails we don't lose the significant amount of work done in the
|
|
||||||
# previous steps.
|
|
||||||
RUN cd /infer && ./build-infer.sh --only-setup-opam
|
|
||||||
RUN cd /infer && \
|
|
||||||
eval $(opam env) && \
|
|
||||||
./autogen.sh && \
|
|
||||||
./configure && \
|
|
||||||
./facebook-clang-plugins/clang/setup.sh
|
|
||||||
|
|
||||||
# Generate a release
|
|
||||||
RUN cd /infer && \
|
|
||||||
make install-with-libs \
|
|
||||||
BUILD_MODE=opt \
|
|
||||||
PATCHELF=patchelf \
|
|
||||||
DESTDIR="/infer-release" \
|
|
||||||
libdir_relative_to_bindir="../lib"
|
|
||||||
|
|
||||||
FROM debian:buster-slim AS executor
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install --yes --no-install-recommends sqlite3
|
|
||||||
|
|
||||||
# Get the infer release
|
|
||||||
COPY --from=compilator /infer-release/usr/local /infer
|
|
||||||
|
|
||||||
# Install infer
|
|
||||||
ENV PATH /infer/bin:${PATH}
|
|
||||||
|
|
||||||
# if called with /infer-host mounted then copy infer there
|
|
||||||
RUN if test -d /infer-host; then \
|
|
||||||
cp -av /infer/. /infer-host; \
|
|
||||||
fi
|
|
@ -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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Hello {
|
|
||||||
int test() {
|
|
||||||
String s = null;
|
|
||||||
return s.length();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@interface Hello : NSObject
|
|
||||||
@property NSString* s;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation Hello
|
|
||||||
NSString* m() {
|
|
||||||
Hello* hello = nil;
|
|
||||||
return hello->_s;
|
|
||||||
}
|
|
||||||
@end
|
|
@ -1,41 +0,0 @@
|
|||||||
This directory contains small examples to play with Infer. They each exhibit
|
|
||||||
one simple programming error that is caught by Infer.
|
|
||||||
|
|
||||||
Contents
|
|
||||||
--------
|
|
||||||
|
|
||||||
- `Hello.java`: try this example by running
|
|
||||||
```infer -- javac Hello.java ```
|
|
||||||
|
|
||||||
- `Hello.m`: try this example by running
|
|
||||||
```infer -- clang -c Hello.m```
|
|
||||||
|
|
||||||
- `hello.c`: try this example by running
|
|
||||||
```infer -- gcc -c hello.c```
|
|
||||||
|
|
||||||
In this case, note that Infer captures the gcc command and runs
|
|
||||||
clang instead to parse C files. Thus you may get compiler errors and
|
|
||||||
warnings that differ from gcc's.
|
|
||||||
|
|
||||||
- `android_hello/`: a sample Android app. Try this example by running
|
|
||||||
```infer -- ./gradlew build```
|
|
||||||
|
|
||||||
Make sure that you have the Android SDK 22 installed and up to date, and in
|
|
||||||
particular the "Android SDK Build-tools" and "Android Support Repository".
|
|
||||||
|
|
||||||
- `c_hello/`: a sample make-based C project. Try this example by running
|
|
||||||
```infer -- make```
|
|
||||||
|
|
||||||
- `ios_hello/`: a sample iOS app. Try this example by running
|
|
||||||
```infer -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator```
|
|
||||||
|
|
||||||
- `java_hello/`: a sample Java project. Try this example by running
|
|
||||||
```infer -- javac Pointers.java Resources.java Hello.java```
|
|
||||||
|
|
||||||
Note
|
|
||||||
----
|
|
||||||
|
|
||||||
The infer toplevel command must be in your PATH for the commands above to
|
|
||||||
succeed. Otherwise, modify the commands to use the correct path to infer, eg
|
|
||||||
```../infer/bin/infer -- javac Hello.java```
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
.gradle
|
|
||||||
/local.properties
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/libraries
|
|
||||||
.DS_Store
|
|
||||||
/build
|
|
@ -1 +0,0 @@
|
|||||||
../../.inferconfig
|
|
@ -1 +0,0 @@
|
|||||||
/build
|
|
@ -1,27 +0,0 @@
|
|||||||
apply plugin: 'com.android.application'
|
|
||||||
|
|
||||||
android {
|
|
||||||
compileSdkVersion 22
|
|
||||||
buildToolsVersion "22.0.1"
|
|
||||||
|
|
||||||
lintOptions.abortOnError false
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
applicationId "infer.inferandroidexample"
|
|
||||||
minSdkVersion 8
|
|
||||||
targetSdkVersion 22
|
|
||||||
versionCode 1
|
|
||||||
versionName "1.0"
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
minifyEnabled false
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
|
||||||
compile 'com.android.support:appcompat-v7:22.0.0'
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# By default, the flags in this file are appended to flags specified
|
|
||||||
# in /Users/irp/android-sdk-macosx/tools/proguard/proguard-android.txt
|
|
||||||
# You can edit the include path and order by changing the proguardFiles
|
|
||||||
# directive in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# Add any project specific keep options here:
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
@ -1,18 +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 infer.inferandroidexample;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.test.ApplicationTestCase;
|
|
||||||
|
|
||||||
/** <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> */
|
|
||||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
|
||||||
public ApplicationTest() {
|
|
||||||
super(Application.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="infer.inferandroidexample" >
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:icon="@drawable/ic_launcher"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme" >
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:label="@string/app_name" >
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
@ -1,17 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// _SHOULD_BE_SKIPPED_
|
|
||||||
|
|
||||||
package infer.inferandroidexample;
|
|
||||||
|
|
||||||
public class Generated {
|
|
||||||
|
|
||||||
static Object returnsNull() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +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 infer.inferandroidexample;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.app.ActionBarActivity;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class MainActivity extends ActionBarActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
String s = getDay();
|
|
||||||
int length = s.length();
|
|
||||||
writeToFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDay() {
|
|
||||||
if (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY) {
|
|
||||||
return "Wednesday";
|
|
||||||
} else {
|
|
||||||
return otherOutput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String otherOutput() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeToFile() {
|
|
||||||
byte[] arr = {1, 2, 3};
|
|
||||||
FileOutputStream fis;
|
|
||||||
try {
|
|
||||||
fis = new FileOutputStream("file.txt");
|
|
||||||
fis.write(arr);
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Deal with exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
|
||||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
// Handle action bar item clicks here. The action bar will
|
|
||||||
// automatically handle clicks on the Home/Up button, so long
|
|
||||||
// as you specify a parent activity in AndroidManifest.xml.
|
|
||||||
int id = item.getItemId();
|
|
||||||
|
|
||||||
//noinspection SimplifiableIfStatement
|
|
||||||
if (id == R.id.action_settings) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void inferShouldNotReport() {
|
|
||||||
// Generated.java is supposed to be skipped by infer, thus even though
|
|
||||||
// Generated.returnsNull() returns null, infer is not supposed to know
|
|
||||||
// about it hence should not report an NPE here
|
|
||||||
Object o = Generated.returnsNull();
|
|
||||||
o.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +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 infer.other;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.app.ActionBarActivity;
|
|
||||||
|
|
||||||
public class MainActivity extends ActionBarActivity {
|
|
||||||
|
|
||||||
Object source() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
source().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NULL_DEREFERENCE")
|
|
||||||
void shouldNotBeReported() {
|
|
||||||
source().toString();
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 19 KiB |
@ -1,11 +0,0 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
|
|
||||||
|
|
||||||
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
@ -1,6 +0,0 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
|
|
||||||
<item android:id="@+id/action_settings" android:title="@string/action_settings"
|
|
||||||
android:orderInCategory="100" app:showAsAction="never" />
|
|
||||||
</menu>
|
|
@ -1,6 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
|
||||||
(such as screen margins) for screens with more than 820dp of available width. This
|
|
||||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
|
||||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
|
||||||
</resources>
|
|
@ -1,5 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
|
||||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
|
||||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
|
||||||
</resources>
|
|
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
|
|
||||||
<string name="app_name">InferAndroidExample</string>
|
|
||||||
<string name="hello_world">Hello world!</string>
|
|
||||||
<string name="action_settings">Settings</string>
|
|
||||||
|
|
||||||
</resources>
|
|
@ -1,8 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
|
@ -1,19 +0,0 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
|
||||||
// in the individual module build.gradle files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
# Project-wide Gradle settings.
|
|
||||||
|
|
||||||
# IDE (e.g. Android Studio) users:
|
|
||||||
# Gradle settings configured through the IDE *will override*
|
|
||||||
# any settings specified in this file.
|
|
||||||
|
|
||||||
# For more details on how to configure your build environment visit
|
|
||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
|
||||||
|
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
|
||||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
|
||||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
||||||
# org.gradle.parallel=true
|
|
Binary file not shown.
@ -1,6 +0,0 @@
|
|||||||
#Wed Apr 10 15:27:10 PDT 2013
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-bin.zip
|
|
@ -1,164 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
##
|
|
||||||
## Gradle start up script for UN*X
|
|
||||||
##
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS=""
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=`basename "$0"`
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
||||||
MAX_FD="maximum"
|
|
||||||
|
|
||||||
warn ( ) {
|
|
||||||
echo "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
die ( ) {
|
|
||||||
echo
|
|
||||||
echo "$*"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
|
||||||
cygwin=false
|
|
||||||
msys=false
|
|
||||||
darwin=false
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN* )
|
|
||||||
cygwin=true
|
|
||||||
;;
|
|
||||||
Darwin* )
|
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
|
||||||
if $cygwin ; then
|
|
||||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >&-
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >&-
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
||||||
else
|
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
|
||||||
fi
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD="java"
|
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
|
||||||
if [ $? -eq 0 ] ; then
|
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
ulimit -n $MAX_FD
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
|
||||||
if $cygwin ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=$((i+1))
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
(0) set -- ;;
|
|
||||||
(1) set -- "$args0" ;;
|
|
||||||
(2) set -- "$args0" "$args1" ;;
|
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
|
||||||
function splitJvmOpts() {
|
|
||||||
JVM_OPTS=("$@")
|
|
||||||
}
|
|
||||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
|
||||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
|
||||||
|
|
||||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
|
@ -1 +0,0 @@
|
|||||||
include ':app'
|
|
@ -1,15 +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.
|
|
||||||
|
|
||||||
SOURCES = $(shell ls *.c)
|
|
||||||
OBJECTS = $(SOURCES:.c=.o)
|
|
||||||
|
|
||||||
all: $(OBJECTS)
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
${CC} -c $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECTS)
|
|
@ -1,65 +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 <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
struct Person {
|
|
||||||
int age;
|
|
||||||
int height;
|
|
||||||
int weight;
|
|
||||||
};
|
|
||||||
|
|
||||||
int simple_null_pointer() {
|
|
||||||
struct Person* max = 0;
|
|
||||||
return max->age;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Person* Person_create(int age, int height, int weight) {
|
|
||||||
struct Person* who = 0;
|
|
||||||
return who;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_age(struct Person* who) { return who->age; }
|
|
||||||
|
|
||||||
int null_pointer_interproc() {
|
|
||||||
struct Person* joe = Person_create(32, 64, 140);
|
|
||||||
return get_age(joe);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fileNotClosed() {
|
|
||||||
int fd = open("hi.txt", O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
|
||||||
if (fd != -1) {
|
|
||||||
char buffer[256];
|
|
||||||
// We can easily batch that by separating with space
|
|
||||||
write(fd, buffer, strlen(buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void simple_leak() {
|
|
||||||
int* p;
|
|
||||||
p = (int*)malloc(sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void common_realloc_leak() {
|
|
||||||
int *p, *q;
|
|
||||||
p = (int*)malloc(sizeof(int));
|
|
||||||
q = (int*)realloc(p, sizeof(int) * 42);
|
|
||||||
// if realloc fails, then p becomes unreachable
|
|
||||||
if (q != NULL)
|
|
||||||
free(q);
|
|
||||||
}
|
|
@ -1,15 +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.
|
|
||||||
|
|
||||||
SOURCES = simple_null.cpp
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
|
||||||
|
|
||||||
all: $(OBJECTS)
|
|
||||||
|
|
||||||
.cpp.o:
|
|
||||||
${CC} -c $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECTS)
|
|
@ -1,10 +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.
|
|
||||||
*/
|
|
||||||
void deref_null() {
|
|
||||||
int* p = nullptr;
|
|
||||||
*p = 42;
|
|
||||||
}
|
|
@ -1,15 +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.
|
|
||||||
|
|
||||||
SOURCES = simple_null_interproc.c wrappers.c
|
|
||||||
OBJECTS = $(SOURCES:.c=.o)
|
|
||||||
|
|
||||||
all: $(OBJECTS)
|
|
||||||
|
|
||||||
.cpp.o:
|
|
||||||
${CC} -c $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECTS)
|
|
@ -1,15 +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>
|
|
||||||
|
|
||||||
int* allocate_int();
|
|
||||||
void set(int* p, int value);
|
|
||||||
|
|
||||||
void deref_null() {
|
|
||||||
int* p = allocate_int();
|
|
||||||
set(p, 42);
|
|
||||||
}
|
|
@ -1,19 +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>
|
|
||||||
|
|
||||||
int* allocate_int();
|
|
||||||
void set(int* p, int value);
|
|
||||||
|
|
||||||
void deref_null_ok() {
|
|
||||||
int* p = allocate_int();
|
|
||||||
if (p != NULL) {
|
|
||||||
set(p, 42);
|
|
||||||
}
|
|
||||||
free(p);
|
|
||||||
}
|
|
@ -1,11 +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>
|
|
||||||
|
|
||||||
int* allocate_int() { return malloc(sizeof(int)); }
|
|
||||||
|
|
||||||
void set(int* p, int value) { *p = value; }
|
|
@ -1,15 +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.
|
|
||||||
|
|
||||||
SOURCES = Resources.java
|
|
||||||
OBJECT = Resources.class
|
|
||||||
|
|
||||||
all: $(OBJECT)
|
|
||||||
|
|
||||||
$(OBJECT): $(SOURCES)
|
|
||||||
javac $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECT)
|
|
@ -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.
|
|
||||||
*/
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
class Resources {
|
|
||||||
|
|
||||||
public static void cat() throws IOException {
|
|
||||||
FileInputStream infile = null;
|
|
||||||
FileOutputStream outfile = null;
|
|
||||||
try {
|
|
||||||
infile = new FileInputStream(new File("infile.txt"));
|
|
||||||
outfile = new FileOutputStream(new File("outfile.txt"));
|
|
||||||
outfile.write(infile.read());
|
|
||||||
} finally {
|
|
||||||
if (infile != null) infile.close();
|
|
||||||
if (outfile != null) outfile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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.
|
|
||||||
*/
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ResourcesFixed {
|
|
||||||
|
|
||||||
public static void cat() throws IOException {
|
|
||||||
try (FileInputStream infile = new FileInputStream(new File("infile.txt"));
|
|
||||||
FileOutputStream outfile = new FileOutputStream(new File("outfile.txt")); ) {
|
|
||||||
outfile.write(infile.read());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@ThreadSafe
|
|
||||||
public interface Account {
|
|
||||||
void deposit(int amount);
|
|
||||||
|
|
||||||
int withdraw(int amount);
|
|
||||||
}
|
|
@ -1,30 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class AccountImplementation implements Account {
|
|
||||||
|
|
||||||
int mBalance = 0;
|
|
||||||
|
|
||||||
private void addToBalance(int amount) {
|
|
||||||
mBalance += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void deposit(int amount) {
|
|
||||||
if (amount > 0) {
|
|
||||||
addToBalance(amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int withdraw(int amount) {
|
|
||||||
if (amount >= 0 && mBalance - amount >= 0) {
|
|
||||||
addToBalance(-amount);
|
|
||||||
return mBalance;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +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.
|
|
||||||
*/
|
|
||||||
@ThreadSafe
|
|
||||||
public class Client {
|
|
||||||
|
|
||||||
Account account;
|
|
||||||
|
|
||||||
void getPaid(int amount) {
|
|
||||||
account.deposit(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
int buyCoffee() {
|
|
||||||
return account.withdraw(5);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +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.
|
|
||||||
|
|
||||||
SOURCES = Account.java AccountImplementation.java Client.java
|
|
||||||
OBJECT = Client.class
|
|
||||||
|
|
||||||
all: $(OBJECT)
|
|
||||||
|
|
||||||
$(OBJECT): $(SOURCES)
|
|
||||||
javac $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECT)
|
|
@ -1,7 +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 @interface ThreadSafe {}
|
|
@ -1,11 +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 interface Account {
|
|
||||||
void deposit(int amount);
|
|
||||||
|
|
||||||
int withdraw(int amount);
|
|
||||||
}
|
|
@ -1,30 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class AccountImplementation implements Account {
|
|
||||||
|
|
||||||
int mBalance = 0;
|
|
||||||
|
|
||||||
private void addToBalance(int amount) {
|
|
||||||
mBalance += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deposit(int amount) {
|
|
||||||
if (amount > 0) {
|
|
||||||
addToBalance(amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int withdraw(int amount) {
|
|
||||||
if (amount >= 0 && mBalance - amount >= 0) {
|
|
||||||
addToBalance(-amount);
|
|
||||||
return mBalance;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +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 Client {
|
|
||||||
|
|
||||||
Account account;
|
|
||||||
|
|
||||||
void getPaid(int amount) {
|
|
||||||
account.deposit(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
int buyCoffee() {
|
|
||||||
return account.withdraw(5);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +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.
|
|
||||||
|
|
||||||
SOURCES = Account.java AccountImplementation.java Client.java
|
|
||||||
OBJECT = Client.class
|
|
||||||
|
|
||||||
all: $(OBJECT)
|
|
||||||
|
|
||||||
$(OBJECT): $(SOURCES)
|
|
||||||
javac $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECT)
|
|
@ -1,7 +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 @interface ThreadSafe {}
|
|
@ -1,15 +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 Client<T> {
|
|
||||||
|
|
||||||
String foo() {
|
|
||||||
Library<T> lib = new Library<T>();
|
|
||||||
T t = lib.get();
|
|
||||||
return t == null ? "default" : t.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +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 Library<T> {
|
|
||||||
|
|
||||||
@Nullable T t;
|
|
||||||
|
|
||||||
private native @Nullable T mayReturnNull();
|
|
||||||
|
|
||||||
public Library() {
|
|
||||||
t = mayReturnNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public T get() {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue