Consolidate Infer# analysis backend (#43)
* Update dockerfile * Remove result parser * Remove our version of Infer * Update instructions * Remove result parser from dockerfile * Updated C# model loading to use sqlite DB (#41) * Compatibility Bug Fixes For Latest Infer Update (#39) * bug fixes * edits * minor fix * run code cleanup * revert dockerfile and infer backend modifications * undo reference param updates * resource leak eport compaible with latest infer (#42) * Update C# model build * Update run steps * Update readme * Update Azure Pipelines * Remove a build script Co-authored-by: Anant Kharkar <71357868+ankharka@users.noreply.github.com> Co-authored-by: Matthew Jin <38902361+matjin@users.noreply.github.com> Co-authored-by: Xiaoyu Liu <lixiaoyu@microsoft.com>
This commit is contained in:
Родитель
595273f4f8
Коммит
744081cac1
|
@ -50,8 +50,8 @@ jobs:
|
|||
- script: |
|
||||
curl -o run_infersharp.sh https://raw.githubusercontent.com/microsoft/infersharp/main/run_infersharp.sh
|
||||
chmod +x run_infersharp.sh
|
||||
sh run_infersharp.sh $(System.ArtifactsDirectory) output
|
||||
./run_infersharp.sh $(System.ArtifactsDirectory)
|
||||
displayName: 'Run Infer# analysis'
|
||||
|
||||
- script: cat $(Build.SourcesDirectory)/infer-out/filtered_bugs.txt
|
||||
- script: cat $(Build.SourcesDirectory)/infer-out/report.txt
|
||||
displayName: 'Infer# analysis result'
|
|
@ -14,8 +14,8 @@ steps:
|
|||
- script: |
|
||||
curl -o run_infersharp.sh https://raw.githubusercontent.com/microsoft/infersharp/main/run_infersharp.sh
|
||||
chmod +x run_infersharp.sh
|
||||
sh run_infersharp.sh $(Build.SourcesDirectory)/Examples/Examples/bin/Debug output
|
||||
./run_infersharp.sh $(Build.SourcesDirectory)/Examples/Examples/bin/Debug
|
||||
displayName: 'Run Infer# analysis'
|
||||
|
||||
- script: cat $(Build.SourcesDirectory)/infer-out/filtered_bugs.txt
|
||||
- script: cat $(Build.SourcesDirectory)/infer-out/report.txt
|
||||
displayName: 'Infer# analysis result'
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30011.22
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnalysisResultParser", "AnalysisResultParser\AnalysisResultParser.csproj", "{8CEF8897-E677-4ECA-A37C-566DE25FE5D8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8CEF8897-E677-4ECA-A37C-566DE25FE5D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8CEF8897-E677-4ECA-A37C-566DE25FE5D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8CEF8897-E677-4ECA-A37C-566DE25FE5D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8CEF8897-E677-4ECA-A37C-566DE25FE5D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {23711A55-952F-4884-83C7-8A53941B27DC}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,18 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="FilterRules.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace AnalysisResultParser
|
||||
{
|
||||
public class FilterRule
|
||||
{
|
||||
[JsonProperty("supportedIssueType", Required = Required.Always)]
|
||||
public string SupportedIssueType { get; set; }
|
||||
|
||||
[JsonProperty("textMustContain")]
|
||||
public string TextMustContain { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
[
|
||||
{
|
||||
"supportedIssueType": "NULL_DEREFERENCE",
|
||||
"textMustContain": "could be null and is dereferenced at"
|
||||
},
|
||||
{
|
||||
"supportedIssueType": "RESOURCE_LEAK"
|
||||
}
|
||||
]
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace AnalysisResultParser
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var inputPath = args.ElementAtOrDefault(0);
|
||||
var outputPath = args.ElementAtOrDefault(1);
|
||||
var changedFilePaths = args.ElementAtOrDefault(2);
|
||||
|
||||
try
|
||||
{
|
||||
var issueList = GetIssueList(inputPath);
|
||||
var filterRules = GetFilterRules();
|
||||
|
||||
var filteredIssues = issueList.Where(
|
||||
x => filterRules.Any(y => x.Contains(y.SupportedIssueType)
|
||||
&& (string.IsNullOrEmpty(y.TextMustContain) || x.Contains(y.TextMustContain))))
|
||||
.Select(s => s.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
|
||||
if (!string.IsNullOrEmpty(changedFilePaths))
|
||||
{
|
||||
var changedFilePathList = changedFilePaths
|
||||
.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
|
||||
.Split(",").Select(p => p.Trim()).ToList();
|
||||
filteredIssues = filteredIssues.Where(x => changedFilePathList.Any(y => x.Contains(y)));
|
||||
}
|
||||
|
||||
using (var streamWriter = new StreamWriter(outputPath))
|
||||
{
|
||||
if (filteredIssues.Count() == 0)
|
||||
{
|
||||
streamWriter.WriteLine("No issues were found.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string filteredIssue in filteredIssues)
|
||||
{
|
||||
streamWriter.WriteLine(filteredIssue + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Something went wrong...");
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetIssueList(string path)
|
||||
{
|
||||
using (var streamReader = new StreamReader(path))
|
||||
{
|
||||
var content = streamReader.ReadToEnd().Split("\n\n").Select(p => p.Trim()).ToList();
|
||||
var issueList = content.Take(content.IndexOf("Summary of the reports")).ToList();
|
||||
issueList.Sort();
|
||||
return issueList;
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<FilterRule> GetFilterRules()
|
||||
{
|
||||
using (var streamReader = new StreamReader(
|
||||
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "FilterRules.json")))
|
||||
{
|
||||
var content = streamReader.ReadToEnd();
|
||||
return JsonConvert.DeserializeObject<IEnumerable<FilterRule>>(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ namespace Cilsil.Test.Assets
|
|||
/// <summary>
|
||||
/// The various error types expected to be produced by Infer in the tests.
|
||||
/// </summary>
|
||||
public enum InferError { None, NULL_DEREFERENCE, DANGLING_POINTER_DEREFERENCE, RESOURCE_LEAK }
|
||||
public enum InferError { None, NULL_DEREFERENCE, DANGLING_POINTER_DEREFERENCE, DOTNET_RESOURCE_LEAK }
|
||||
|
||||
/// <summary>
|
||||
/// The various class methods in TestClass which are called in the tests.
|
||||
|
@ -159,7 +159,7 @@ namespace Cilsil.Test.Assets
|
|||
{
|
||||
case InferError.DANGLING_POINTER_DEREFERENCE:
|
||||
case InferError.NULL_DEREFERENCE:
|
||||
case InferError.RESOURCE_LEAK:
|
||||
case InferError.DOTNET_RESOURCE_LEAK:
|
||||
return error.ToString();
|
||||
case InferError.None:
|
||||
return null;
|
||||
|
|
|
@ -16,27 +16,6 @@ namespace Cilsil.Test.E2E
|
|||
[TestInitialize]
|
||||
public void TestInitialize() => TestRunManager = new TestRunManager(TestContext.TestName);
|
||||
|
||||
/// <summary>
|
||||
/// Validates that a dereference on an uninitialized pointer is identified.
|
||||
/// </summary>
|
||||
/// <param name="initializationMethod">The TestClass method used to initialize the
|
||||
/// object to be dereference.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(TestClassMethod.InitializeInstanceObjectField, InferError.None)]
|
||||
[DataRow(TestClassMethod.None, InferError.DANGLING_POINTER_DEREFERENCE)]
|
||||
[DataTestMethod]
|
||||
public void DanglingPointerDerefSimple(TestClassMethod initializationMethod,
|
||||
InferError expectedError)
|
||||
{
|
||||
// We provide the "false" argument because it is required to initialize the object.
|
||||
TestRunManager.Run(InitVars(state: TestClassState.Initialized) +
|
||||
CallTestClassMethod(initializationMethod,
|
||||
true,
|
||||
args: new string[] { false.ToString().ToLower() }) +
|
||||
DerefObject(VarName.InstanceObjectField),
|
||||
GetString(expectedError));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that a dereference on a locally initialized null pointer is identified.
|
||||
/// </summary>
|
||||
|
@ -60,7 +39,7 @@ namespace Cilsil.Test.E2E
|
|||
/// does not.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(true, InferError.None)]
|
||||
[DataRow(false, InferError.RESOURCE_LEAK)]
|
||||
[DataRow(false, InferError.DOTNET_RESOURCE_LEAK)]
|
||||
[DataTestMethod]
|
||||
public void ResourceLeakIntraprocClose(bool closeStream, InferError expectedError)
|
||||
{
|
||||
|
@ -85,7 +64,7 @@ namespace Cilsil.Test.E2E
|
|||
/// does not.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(true, InferError.None)]
|
||||
[DataRow(false, InferError.RESOURCE_LEAK)]
|
||||
[DataRow(false, InferError.DOTNET_RESOURCE_LEAK)]
|
||||
[DataTestMethod]
|
||||
public void ResourceLeakIntraprocDispose(bool disposeStream, InferError expectedError)
|
||||
{
|
||||
|
@ -109,7 +88,7 @@ namespace Cilsil.Test.E2E
|
|||
/// does not.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(true, InferError.None)]
|
||||
[DataRow(false, InferError.RESOURCE_LEAK)]
|
||||
[DataRow(false, InferError.DOTNET_RESOURCE_LEAK)]
|
||||
[DataTestMethod]
|
||||
public void ResourceLeakInterproc(bool closeStream, InferError expectedError)
|
||||
{
|
||||
|
@ -137,7 +116,7 @@ namespace Cilsil.Test.E2E
|
|||
/// does not.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(true, InferError.None)]
|
||||
[DataRow(false, InferError.RESOURCE_LEAK)]
|
||||
[DataRow(false, InferError.DOTNET_RESOURCE_LEAK)]
|
||||
[DataTestMethod]
|
||||
public void ResourceLeakInitInterproc(bool closeStream, InferError expectedError)
|
||||
{
|
||||
|
@ -164,7 +143,7 @@ namespace Cilsil.Test.E2E
|
|||
/// does not.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(true, InferError.None)]
|
||||
[DataRow(false, InferError.RESOURCE_LEAK)]
|
||||
[DataRow(false, InferError.DOTNET_RESOURCE_LEAK)]
|
||||
[DataTestMethod]
|
||||
public void ResourceLeakReturnedResource(bool returnsResource, InferError expectedError)
|
||||
{
|
||||
|
@ -187,7 +166,7 @@ namespace Cilsil.Test.E2E
|
|||
/// does not.</param>
|
||||
/// <param name="expectedError">The kind of error expected to be reported by Infer.</param>
|
||||
[DataRow(true, InferError.None)]
|
||||
[DataRow(false, InferError.RESOURCE_LEAK)]
|
||||
[DataRow(false, InferError.DOTNET_RESOURCE_LEAK)]
|
||||
[DataTestMethod]
|
||||
public void ResourceLeakStaticSingleton(bool staticSingleton, InferError expectedError)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,11 @@ namespace Cilsil.Cil.Parsers
|
|||
switch (instruction.OpCode.Code)
|
||||
{
|
||||
case Code.Ret:
|
||||
Store retInstr;
|
||||
var retType = state.Method.ReturnType.GetElementType();
|
||||
var retNode = new StatementNode(state.CurrentLocation,
|
||||
StatementNode.StatementNodeKind.ReturnStmt,
|
||||
state.ProcDesc);
|
||||
if (retType == state.Method.Module.TypeSystem.Void)
|
||||
{
|
||||
state.PreviousNode.Successors.Add(state.ProcDesc.ExitNode);
|
||||
|
@ -29,13 +33,41 @@ namespace Cilsil.Cil.Parsers
|
|||
Expression returnVariable = new LvarExpression(
|
||||
new LocalVariable(Identifier.ReturnIdentifier,
|
||||
state.Method));
|
||||
var retInstr = new Store(lvalue: returnVariable,
|
||||
rvalue: returnValue,
|
||||
type: Typ.FromTypeReference(retType),
|
||||
location: state.CurrentLocation);
|
||||
var retNode = new StatementNode(state.CurrentLocation,
|
||||
StatementNode.StatementNodeKind.ReturnStmt,
|
||||
state.ProcDesc);
|
||||
|
||||
if (returnValue is BinopExpression)
|
||||
{
|
||||
// We see that for the auto-generated method op_Inequality in records,
|
||||
// an equality expression is pushed directly onto the stack and
|
||||
// returned. However, return of an expression is not valid in the SIL --
|
||||
// we must inline a variable store and load of the value prior to
|
||||
// subsequently returning it.
|
||||
var inlineReturn = new LocalVariable("inlineReturn", state.Method);
|
||||
var inlineIdentifier = state.GetIdentifier(Identifier.IdentKind.Normal);
|
||||
|
||||
var storeInlineReturn = new Store(new LvarExpression(inlineReturn),
|
||||
returnValue,
|
||||
Typ.FromTypeReference(retType),
|
||||
state.CurrentLocation);
|
||||
AddMethodBodyInstructionsToCfg(state, storeInlineReturn);
|
||||
|
||||
var loadInlineReturn = new Load(inlineIdentifier,
|
||||
new LvarExpression(inlineReturn),
|
||||
Typ.FromTypeReference(retType),
|
||||
state.CurrentLocation);
|
||||
AddMethodBodyInstructionsToCfg(state, loadInlineReturn);
|
||||
|
||||
retInstr = new Store(returnVariable,
|
||||
new VarExpression(inlineIdentifier),
|
||||
Typ.FromTypeReference(retType),
|
||||
state.CurrentLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
retInstr = new Store(returnVariable,
|
||||
returnValue,
|
||||
Typ.FromTypeReference(retType),
|
||||
state.CurrentLocation);
|
||||
}
|
||||
retNode.Instructions.Add(retInstr);
|
||||
retNode.Successors = new List<CfgNode> { state.ProcDesc.ExitNode };
|
||||
RegisterNode(state, retNode);
|
||||
|
|
|
@ -57,9 +57,9 @@ namespace Cilsil.Cil.Parsers
|
|||
|
||||
var variable = new LocalVariable(LocalName(index), state.Method);
|
||||
var storeValueIntoVariable = new Store(new LvarExpression(variable),
|
||||
value,
|
||||
type,
|
||||
state.CurrentLocation);
|
||||
value,
|
||||
type,
|
||||
state.CurrentLocation);
|
||||
node = AddMethodBodyInstructionsToCfg(state, storeValueIntoVariable);
|
||||
RegisterLocalVariable(state, variable, type);
|
||||
state.PushInstruction(instruction.Next, node);
|
||||
|
|
88
Dockerfile
88
Dockerfile
|
@ -2,70 +2,66 @@ FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS base
|
|||
|
||||
FROM base AS buildbackend
|
||||
WORKDIR /app
|
||||
COPY infer /app/infer/
|
||||
# mkdir the man/man1 directory due to Debian bug #863199
|
||||
RUN apt-get update && \
|
||||
mkdir -p /usr/local/lib/infer/infer && \
|
||||
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 \
|
||||
openjdk-8-jdk-headless \
|
||||
patch \
|
||||
pkg-config \
|
||||
python2.7 \
|
||||
unzip \
|
||||
sudo \
|
||||
xz-utils \
|
||||
zlib1g-dev && \
|
||||
autoconf \
|
||||
automake \
|
||||
bzip2 \
|
||||
cmake \
|
||||
curl \
|
||||
gcc \
|
||||
git \
|
||||
libc6-dev \
|
||||
libgmp-dev \
|
||||
libmpfr-dev \
|
||||
libsqlite3-dev \
|
||||
make \
|
||||
openjdk-11-jdk-headless \
|
||||
patch \
|
||||
pkg-config \
|
||||
python3.7 \
|
||||
python3-distutils \
|
||||
sqlite3 \
|
||||
sudo \
|
||||
unzip \
|
||||
zlib1g-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
|
||||
RUN apt-get install -y nodejs
|
||||
|
||||
# Some scripts in facebook-clang-plugins assume "python" is available
|
||||
RUN cd /usr/local/bin && ln -s /usr/bin/python2.7 python
|
||||
|
||||
# Install opam 2
|
||||
RUN curl -sL https://github.com/ocaml/opam/releases/download/2.0.2/opam-2.0.2-x86_64-linux > /usr/bin/opam && \
|
||||
RUN curl -sL https://github.com/ocaml/opam/releases/download/2.0.6/opam-2.0.6-x86_64-linux > /usr/bin/opam && \
|
||||
chmod +x /usr/bin/opam
|
||||
|
||||
# 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
|
||||
|
||||
# Download the latest Infer master
|
||||
RUN cd / && \
|
||||
git clone https://github.com/facebook/infer.git && \
|
||||
cd infer && \
|
||||
git reset --hard 285ddb4a98f337a40d61e73b7a0867e44fa4f042
|
||||
|
||||
# build in non-optimized mode by default to speed up build times
|
||||
ENV BUILD_MODE=default
|
||||
ENV BUILD_MODE=dev
|
||||
|
||||
# prevent exiting by compulsively hitting Control-D
|
||||
ENV IGNOREEOF=9
|
||||
|
||||
# export `opam env`
|
||||
ENV OPAM_SWITCH_PREFIX=/root/.opam/4.07.1
|
||||
ENV CAML_LD_LIBRARY_PATH=/root/.opam/4.07.1/lib/stublibs:/root/.opam/4.07.1/lib/ocaml/stublibs:/root/.opam/4.07.1/lib/ocaml
|
||||
ENV OCAML_TOPLEVEL_PATH=/root/.opam/4.07.1/lib/toplevel
|
||||
ENV MANPATH=$MANPATH:/root/.opam/4.07.1/man
|
||||
ENV PATH=/root/.opam/4.07.1/bin:$PATH
|
||||
ENV OPAM_SWITCH_PREFIX=/root/.opam/4.08.1
|
||||
ENV CAML_LD_LIBRARY_PATH=/root/.opam/4.08.1/lib/stublibs:/root/.opam/4.08.1/lib/ocaml/stublibs:/root/.opam/4.08.1/lib/ocaml
|
||||
ENV OCAML_TOPLEVEL_PATH=/root/.opam/4.08.1/lib/toplevel
|
||||
ENV MANPATH=$MANPATH:/root/.opam/4.08.1/man
|
||||
ENV PATH=/root/.opam/4.08.1/bin:$PATH
|
||||
|
||||
# Build Infer
|
||||
RUN cd infer && \
|
||||
RUN cd / && \
|
||||
cd infer && \
|
||||
eval $(opam env) && \
|
||||
chmod +x ./build-infer.sh ./autogen.sh && \
|
||||
chmod +x ./build-infer.sh && \
|
||||
./build-infer.sh java && \
|
||||
./autogen.sh && \
|
||||
sudo make install && \
|
||||
sudo make install && \
|
||||
cd .. && \
|
||||
rm -r infer
|
||||
|
||||
|
@ -75,15 +71,13 @@ COPY . .
|
|||
RUN chmod +x build_csharp_models.sh && ./build_csharp_models.sh
|
||||
RUN dotnet test Cilsil.Test/Cilsil.Test.csproj
|
||||
RUN dotnet publish -c Release Cilsil/Cilsil.csproj -r ubuntu.16.10-x64
|
||||
RUN dotnet publish -c Release AnalysisResultParser/AnalysisResultParser/AnalysisResultParser.csproj -r ubuntu.16.10-x64
|
||||
RUN dotnet build Examples/Examples/Examples.csproj
|
||||
|
||||
FROM buildbackend AS release
|
||||
WORKDIR /app
|
||||
COPY --from=buildfrontend /app/AnalysisResultParser/AnalysisResultParser/bin/Release/net5.0/ubuntu.16.10-x64/publish/ /app/AnalysisResultParser/
|
||||
COPY --from=buildfrontend /app/Examples/Examples/bin/Debug/net5.0/ /app/Examples/
|
||||
COPY --from=buildfrontend /app/Cilsil/bin/Release/net5.0/ubuntu.16.10-x64/publish/ /app/Cilsil/
|
||||
COPY --from=buildfrontend /usr/local/lib/infer/infer/lib/specs/ /usr/local/lib/infer/infer/lib/specs/
|
||||
COPY --from=buildfrontend /usr/local/lib/infer/infer/lib/models.sql /usr/local/lib/infer/infer/lib/models.sql
|
||||
COPY --from=buildfrontend /app/run_infersharp.sh /app/
|
||||
COPY --from=buildfrontend /app/.build/NOTICE.txt /app/
|
||||
COPY --from=buildfrontend /app/LICENSE /app/
|
||||
COPY --from=buildfrontend /app/LICENSE /app/
|
|
@ -6,6 +6,7 @@
|
|||
- [.NET Blog](https://devblogs.microsoft.com/dotnet/infer-interprocedural-memory-safety-analysis-for-c/)
|
||||
- [Facebook Engineering Blog](https://engineering.fb.com/2020/12/14/open-source/infer/)
|
||||
- [.NET Community Standup](https://youtu.be/cIB4gxqm6EY?list=PLdo4fOcmZ0oX-DBuRG4u58ZTAJgBAeQ-t&t=147)
|
||||
- Visual Studio Toolbox - [YouTube](https://www.youtube.com/watch?v=yNSJv5wN4OA&feature=youtu.be), [Channel9](https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Analyzing-Code-with-Infer)
|
||||
|
||||
## Get Started
|
||||
### GitHub Action
|
||||
|
@ -22,11 +23,7 @@ docker pull mcr.microsoft.com/infersharp:latest
|
|||
```
|
||||
Start a container in interactive mode, then run the following command in the container:
|
||||
```shell
|
||||
sh run_infersharp.sh Examples output
|
||||
```
|
||||
To view the bug report:
|
||||
```shell
|
||||
cat output/filtered_bugs.txt
|
||||
./run_infersharp.sh Examples
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
|
|
@ -25,15 +25,18 @@ System/bin/Debug/net5.0/System.dll \
|
|||
--cfgtxt models_out/cfg.txt
|
||||
|
||||
section "Analyze model CFGs using Infer#"
|
||||
cd infer
|
||||
rm -rf infer-out
|
||||
infer capture
|
||||
mkdir infer-out/captured
|
||||
infer analyzejson --debug \
|
||||
--cfg-json ../models_out/cfg.json \
|
||||
--tenv-json ../models_out/tenv.json
|
||||
--cfg-json models_out/cfg.json \
|
||||
--tenv-json models_out/tenv.json
|
||||
|
||||
section "Move model specs to lib"
|
||||
sudo cp -r infer-out/specs/. /usr/local/lib/infer/infer/lib/specs/
|
||||
section "Move model DB to lib"
|
||||
sqlite3 infer-out/results.db \
|
||||
-cmd ".mode insert model_specs" \
|
||||
-cmd ".output `pwd`/infer-out/models.sql" \
|
||||
-cmd "select * from specs order by proc_uid ;" </dev/null
|
||||
|
||||
cat infer-out/models.sql >> /usr/local/lib/infer/infer/lib/models.sql
|
||||
|
||||
cd ..
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[buildfile]
|
||||
includes = //DEFS
|
||||
|
||||
[project]
|
||||
ignore = .git, .ml, .mli
|
||||
|
||||
[java]
|
||||
source_level = 8
|
||||
target_level = 8
|
|
@ -1,46 +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
|
||||
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: 60
|
||||
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,182 +0,0 @@
|
|||
# Generated files #
|
||||
###################
|
||||
*.pyc
|
||||
*.specs
|
||||
*.cm*
|
||||
*.o
|
||||
*~
|
||||
*.swp
|
||||
*.annot
|
||||
*.class
|
||||
*.log
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# generated by build and tests
|
||||
/_build
|
||||
/_build_logs
|
||||
/infer/tests/codetoanalyze/java/*/codetoanalyze
|
||||
_build_infer
|
||||
*.exp.test*
|
||||
*.test.dot
|
||||
*.test.txt
|
||||
duplicates.txt
|
||||
*.ast.sh
|
||||
*.ast.bdump
|
||||
*.ast.biniou
|
||||
/infer/tests/build_systems/buck_flavors_diff/src/hello.c
|
||||
/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/utf8_*n_pwd
|
||||
/infer/tests/build_systems/codetoanalyze/mvn/**/target/
|
||||
/infer/tests/build_systems/codetoanalyze/path with spaces/
|
||||
/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_with_MD_flag/hello.d
|
||||
/infer/tests/build_systems/codetoanalyze/xcodebuild/simple_app/app_built
|
||||
/infer/tests/build_systems/codetoanalyze/xcodebuild/simple_app/build/
|
||||
/infer/tests/build_systems/differential_*/**/*.class
|
||||
/infer/tests/build_systems/differential_*/**/Diff*.java
|
||||
/infer/tests/build_systems/diff/src
|
||||
/infer/tests/build_systems/diff_*/src
|
||||
/infer/tests/build_systems/buck_flavors_deterministic/capture_hash-*.sha
|
||||
/infer/tests/build_systems/genrule/report.json
|
||||
/infer/tests/build_systems/java_test_determinator/*.test
|
||||
/infer/tests/codetoanalyze/java/classloads/*.loads
|
||||
/infer/tests/codetoanalyze/java/classloads/loads.exp
|
||||
/_release
|
||||
/infer-source
|
||||
|
||||
# generated by oUnit
|
||||
/oUnit-all.cache
|
||||
|
||||
# autoconf-generated stuff
|
||||
/acinclude.m4
|
||||
/aclocal.m4
|
||||
/autom4te.cache
|
||||
/config.status
|
||||
/m4/__GENERATED__*.m4
|
||||
/configure
|
||||
/Makefile.autoconf
|
||||
/.buckversion
|
||||
/*/.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
|
||||
|
||||
# Eclipse settings files
|
||||
ocaml.prefs
|
||||
/infer/.paths
|
||||
/infer/src/.paths
|
||||
org.eclipse.core.resources.prefs
|
||||
|
||||
# vscode
|
||||
.vscode/
|
||||
|
||||
# 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/bin/infer
|
||||
/infer/bin/infer.bc
|
||||
/infer/bin/infer.exe
|
||||
/infer/bin/infer-analyze
|
||||
/infer/bin/infer-capture
|
||||
/infer/bin/infer-compile
|
||||
/infer/bin/infer-explore
|
||||
/infer/bin/infer-report
|
||||
/infer/bin/infer-reportdiff
|
||||
/infer/bin/infer-run
|
||||
/infer/bin/InferCreateTraceViewLinks
|
||||
/infer/bin/InferUnit
|
||||
/infer/bin/infertop.bc
|
||||
/infer/bin/llvm_sil
|
||||
/infer/man/man1/*.1
|
||||
/infer/man/man1/*.1.gz
|
||||
|
||||
/infer/src/base/Version.ml
|
||||
/infer/models/java/models/
|
||||
/infer/models/java/models.jar
|
||||
/infer/lib/java/models.jar
|
||||
/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
|
||||
/scripts/checkCopyright
|
||||
/infer/etc/clang_ast.dict
|
||||
/infer/src/toplevel.mlpack
|
||||
|
||||
# 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
|
||||
|
||||
# copied from facebook-clang-plugins or generated by atdgen
|
||||
/infer/src/clang_plugin/*.ml
|
||||
/infer/src/clang_plugin/*.mli
|
||||
|
||||
/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
|
||||
|
||||
# dune
|
||||
/infer/src/_build
|
||||
/infer/src/dune.common
|
||||
/infer/src/dune
|
||||
/infer/src/atd/dune
|
||||
/infer/src/base/dune
|
||||
/infer/src/IR/dune
|
||||
/infer/src/istd/dune
|
||||
/infer/src/scripts/dune
|
||||
/infer/src/dune-workspace
|
||||
.merlin
|
||||
|
||||
# generated when looking for dead code
|
||||
/infer/src/deadcode/.depend
|
||||
/infer/src/deadcode/dune
|
||||
/infer/src/deadcode/*.ml
|
||||
/infer/src/deadcode/*.mli
|
||||
_opam
|
||||
_coverage
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "facebook-clang-plugins"]
|
||||
path = facebook-clang-plugins
|
||||
url = https://github.com/facebook/facebook-clang-plugins.git
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"force-delete-results-dir": true,
|
||||
"siof-safe-methods": ["getGlobalNonPODWhitelisted", "whitelisted::getGlobalNonPOD",
|
||||
"whitelisted::TemplatedObject::getGlobalNonPOD"],
|
||||
"skip-translation": [
|
||||
{
|
||||
"language": "Java",
|
||||
"source_contains": "_SHOULD_BE_SKIPPED_"
|
||||
}
|
||||
],
|
||||
"skip-implementation": [
|
||||
{
|
||||
"language": "Java",
|
||||
"source_contains": "_SHOULD_SKIP_IMPLEMENTATION_"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
profile = ocamlformat
|
||||
let-binding-spacing = sparse
|
||||
margin = 100
|
||||
version = 0.9
|
|
@ -1 +0,0 @@
|
|||
9006560863e9323b8ee3e4d78fd0e799fe10259c
|
|
@ -1,26 +0,0 @@
|
|||
language: c
|
||||
sudo: required
|
||||
env:
|
||||
- OCAML_VERSION=4.07.1
|
||||
cache:
|
||||
directories:
|
||||
- ${HOME}/.opam
|
||||
- facebook-clang-plugins
|
||||
before_install:
|
||||
- wget -O ${HOME}/opam https://github.com/ocaml/opam/releases/download/2.0.3/opam-2.0.3-x86_64-linux
|
||||
- chmod +x ${HOME}/opam
|
||||
- export PATH=${HOME}:${PATH}
|
||||
- export OPAMYES=1
|
||||
- export OPAMJOBS=2
|
||||
- opam init --compiler=${OCAML_VERSION} --disable-sandboxing
|
||||
- eval $(opam env)
|
||||
- export OPAMVERBOSE=1
|
||||
install:
|
||||
- opam update --upgrade
|
||||
- opam pin add --no-action infer .
|
||||
- opam depext --update infer
|
||||
- opam install --deps-only infer
|
||||
script:
|
||||
- opam install infer
|
||||
os:
|
||||
- linux
|
|
@ -1,3 +0,0 @@
|
|||
# Code of Conduct
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.fb.com/codeofconduct/) so that you can understand what actions will and will not be tolerated.
|
|
@ -1,236 +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
|
||||
|
||||
- Build the code faster: `make -j BUILD_MODE=default`. By default `make` builds infer with flambda
|
||||
enabled, which makes it very slow (but makes infer significantly faster).
|
||||
|
||||
- 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 bytecode instead of native:
|
||||
`make -j -C infer/src byte`. You need to have run `make -j` (with or without `BUILD_MODE=default`)
|
||||
at some point before.
|
||||
|
||||
- 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_infer_test` will rebuild infer and the models if necessary
|
||||
before running the test, but running `make -C infer/tests/codetoanalyze/java/infer test` will just
|
||||
execute the test.
|
||||
|
||||
- To switch the default build mode to flambda disabled, you can `export BUILD_MODE=default` in your
|
||||
shell.
|
||||
|
||||
### 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
|
||||
(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 ""`.
|
||||
|
||||
|
||||
## Hacking on the Code in facebook-clang-plugins
|
||||
|
||||
Infer uses `ASTExporter` from the [facebook-clang-plugins](https://github.com/facebook/facebook-clang-plugins)
|
||||
repository. To change that part of the code:
|
||||
1. Create a [pull request](https://github.com/facebook/facebook-clang-plugins/pulls) in `facebook-clang-plugins` with the changes.
|
||||
2. Create a pull request in this repository updating the version of the git submodule.
|
||||
|
||||
## 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 (except for Python for which the limit is 80).
|
||||
|
||||
- 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/whitequark/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 opam and opam.locked
|
||||
|
||||
tl; dr: Run `make opam.locked`.
|
||||
|
||||
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 'opam' then run `make 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>
|
52
infer/DEFS
52
infer/DEFS
|
@ -1,52 +0,0 @@
|
|||
import os
|
||||
|
||||
original_java_library = java_library
|
||||
def java_library(
|
||||
name,
|
||||
srcs=[],
|
||||
**kwargs
|
||||
):
|
||||
|
||||
original_java_library(
|
||||
name=name,
|
||||
srcs=srcs,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
create_infer_genrule(name, srcs)
|
||||
|
||||
original_android_library = android_library
|
||||
def android_library(
|
||||
name,
|
||||
srcs=[],
|
||||
**kwargs
|
||||
):
|
||||
|
||||
original_android_library(
|
||||
name=name,
|
||||
srcs=srcs,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
create_infer_genrule(name, srcs)
|
||||
|
||||
def create_infer_genrule(
|
||||
name,
|
||||
srcs
|
||||
):
|
||||
genrule_name = name + '_infer'
|
||||
genrule(
|
||||
name = genrule_name,
|
||||
srcs=srcs,
|
||||
cmd = ' '.join([
|
||||
os.getenv('INFER_BIN', 'infer'),
|
||||
'--genrule-mode',
|
||||
'--project-root', os.getenv('PROJECT_ROOT', os.environ['PWD']),
|
||||
'--eradicate-only',
|
||||
'--results-dir', '$OUT',
|
||||
'--classpath', '$(classpath :{})'.format(name),
|
||||
'--sourcepath', '$SRCDIR',
|
||||
'--generated-classes', '$(location :{})'.format(name),
|
||||
]),
|
||||
out = 'infer_out',
|
||||
)
|
|
@ -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]`.
|
108
infer/INSTALL.md
108
infer/INSTALL.md
|
@ -1,108 +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.html#install-from-source)
|
||||
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))
|
||||
- Python 2.7
|
||||
- sqlite
|
||||
- pkg-config
|
||||
- Java (only needed for the Java analysis)
|
||||
- cmake (only needed for 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
|
||||
- Python 2.7
|
||||
- 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)
|
||||
|
||||
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](http://fbinfer.com/support.html#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) 2013-present, Facebook, Inc.
|
||||
|
||||
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.
|
928
infer/Makefile
928
infer/Makefile
|
@ -1,928 +0,0 @@
|
|||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
.PHONY: default
|
||||
default: infer
|
||||
|
||||
ROOT_DIR = .
|
||||
include $(ROOT_DIR)/Makefile.config
|
||||
|
||||
ORIG_SHELL_BUILD_MODE = $(BUILD_MODE)
|
||||
# override this for faster builds (but slower infer)
|
||||
BUILD_MODE ?= opt
|
||||
|
||||
MAKE_SOURCE = $(MAKE) -C $(SRC_DIR) INFER_BUILD_DIR=_build/$(BUILD_MODE)
|
||||
|
||||
ifneq ($(UTOP),no)
|
||||
BUILD_SYSTEMS_TESTS += infertop
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_C_ANALYZERS),yes)
|
||||
BUILD_SYSTEMS_TESTS += \
|
||||
assembly \
|
||||
backtrack_level \
|
||||
ck_analytics ck_imports \
|
||||
clang_compilation_db_escaped clang_compilation_db_relpath \
|
||||
clang_multiple_files \
|
||||
clang_translation \
|
||||
clang_unknown_ext \
|
||||
clang_with_blacklisted_flags \
|
||||
clang_with_E_flag \
|
||||
clang_with_M_flag \
|
||||
clang_with_MD_flag \
|
||||
deduplicate_template_warnings \
|
||||
delete_results_dir \
|
||||
diff \
|
||||
diff_gen_build_script \
|
||||
duplicate_symbols \
|
||||
fail_on_issue \
|
||||
j1 \
|
||||
linters \
|
||||
project_root_rel \
|
||||
reactive \
|
||||
run_hidden_linters \
|
||||
tracebugs \
|
||||
utf8_in_procname \
|
||||
|
||||
DIRECT_TESTS += \
|
||||
c_biabduction \
|
||||
c_bufferoverrun \
|
||||
c_errors \
|
||||
c_frontend \
|
||||
c_performance \
|
||||
c_purity \
|
||||
c_uninit \
|
||||
cpp_bufferoverrun \
|
||||
cpp_conflicts \
|
||||
cpp_errors \
|
||||
cpp_frontend \
|
||||
cpp_linters \
|
||||
cpp_linters-for-test-only \
|
||||
cpp_liveness \
|
||||
cpp_nullable \
|
||||
cpp_ownership cpp_pulse \
|
||||
cpp_quandary cpp_quandaryBO \
|
||||
cpp_racerd \
|
||||
cpp_siof \
|
||||
cpp_starvation \
|
||||
cpp_uninit \
|
||||
|
||||
|
||||
ifneq ($(BUCK),no)
|
||||
BUILD_SYSTEMS_TESTS += buck_blacklist buck-clang-db buck_flavors buck_flavors_run buck_flavors_deterministic
|
||||
endif
|
||||
ifneq ($(CMAKE),no)
|
||||
BUILD_SYSTEMS_TESTS += clang_compilation_db cmake inferconfig inferconfig_not_strict
|
||||
endif
|
||||
ifneq ($(NDKBUILD),no)
|
||||
BUILD_SYSTEMS_TESTS += ndk_build
|
||||
endif
|
||||
ifneq ($(PYTHON_lxml),no)
|
||||
BUILD_SYSTEMS_TESTS += results_xml
|
||||
endif
|
||||
ifeq ($(HAS_OBJC),yes)
|
||||
BUILD_SYSTEMS_TESTS += objc_getters_setters objc_missing_fld objc_retain_cycles objc_retain_cycles_weak
|
||||
DIRECT_TESTS += \
|
||||
objc_errors \
|
||||
objc_frontend \
|
||||
objc_ioslints \
|
||||
objc_linters \
|
||||
objc_linters-def-folder \
|
||||
objc_linters-for-test-only \
|
||||
objc_liveness \
|
||||
objc_nullable \
|
||||
objc_performance objc_uninit \
|
||||
objcpp_errors \
|
||||
objcpp_frontend \
|
||||
objcpp_linters \
|
||||
objcpp_linters-for-test-only \
|
||||
objcpp_liveness \
|
||||
objcpp_nullable \
|
||||
objcpp_racerd \
|
||||
objcpp_retain-cycles \
|
||||
|
||||
ifneq ($(XCODE_SELECT),no)
|
||||
BUILD_SYSTEMS_TESTS += xcodebuild_no_xcpretty
|
||||
endif
|
||||
ifneq ($(XCPRETTY),no)
|
||||
BUILD_SYSTEMS_TESTS += xcodebuild
|
||||
endif
|
||||
endif # HAS_OBJC
|
||||
endif # BUILD_C_ANALYZERS
|
||||
|
||||
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
|
||||
BUILD_SYSTEMS_TESTS += \
|
||||
differential_interesting_paths_filter \
|
||||
differential_of_costs_report \
|
||||
differential_skip_anonymous_class_renamings \
|
||||
differential_skip_duplicated_types_on_filenames \
|
||||
differential_skip_duplicated_types_on_filenames_with_renamings \
|
||||
gradle \
|
||||
java_test_determinator \
|
||||
javac \
|
||||
resource_leak_exception_lines \
|
||||
racerd_dedup
|
||||
|
||||
#TODO T41549034: Jdk11 translates string append differently, causing
|
||||
#test failures in NullPointerExceptions:stringVarEqualsFalseNPE
|
||||
|
||||
DIRECT_TESTS += \
|
||||
java_bufferoverrun \
|
||||
java_checkers \
|
||||
java_classloads \
|
||||
java_eradicate \
|
||||
java_hoisting \
|
||||
java_hoistingExpensive \
|
||||
java_infer \
|
||||
java_performance \
|
||||
java_purity \
|
||||
java_quandary \
|
||||
java_racerd \
|
||||
java_starvation \
|
||||
java_topl \
|
||||
java_tracing \
|
||||
|
||||
ifneq ($(ANT),no)
|
||||
BUILD_SYSTEMS_TESTS += ant
|
||||
endif
|
||||
|
||||
|
||||
|
||||
ifneq ($(BUCK),no)
|
||||
BUILD_SYSTEMS_TESTS += buck genrule buck_javac_jar
|
||||
# Introduce the dependency only if the two tests are going to be built in parallel, so that they do
|
||||
# not run in parallel (otherwise Buck has a bad time). This works by checking if one of the main
|
||||
# testing targets was passed as a goal on the command line.
|
||||
ifneq ($(filter build_systems_tests config_tests test test-replace,${MAKECMDGOALS}),)
|
||||
build_genrule_print: build_buck_print
|
||||
build_genrule_replace: build_buck_replace
|
||||
build_genrule_test: build_buck_test
|
||||
endif
|
||||
endif
|
||||
ifneq ($(MVN),no)
|
||||
BUILD_SYSTEMS_TESTS += mvn
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_C_ANALYZERS)+$(BUILD_JAVA_ANALYZERS),yes+yes)
|
||||
BUILD_SYSTEMS_TESTS += make utf8_in_pwd waf
|
||||
# the waf test and the make test run the same `make` command; use the same trick as for
|
||||
# "build_buck_test" to prevent make from running them in parallel
|
||||
ifneq ($(filter build_systems_tests config_tests test test-replace,${MAKECMDGOALS}),)
|
||||
build_waf_replace: build_make_replace
|
||||
build_waf_print: build_make_print
|
||||
build_waf_test: build_make_test
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(IS_INFER_RELEASE),no)
|
||||
configure: configure.ac $(wildcard m4/*.m4)
|
||||
# rerun ./autogen.sh in case of failure as the failure may be due to needing to rerun
|
||||
# ./configure
|
||||
$(QUIET)($(call silent_on_success,Generate ./configure,./autogen.sh)) || \
|
||||
./autogen.sh
|
||||
|
||||
Makefile.autoconf: configure Makefile.autoconf.in
|
||||
# rerun ./configure with the flags that were used last time it was run (if available)
|
||||
# retry in case of failure as the failure may be due to needing to rerun ./configure
|
||||
$(QUIET)($(call silent_on_success,Running\
|
||||
./configure $(shell ./config.status --config || true),\
|
||||
./configure $(shell ./config.status --config || true))) || \
|
||||
./configure $(shell ./config.status --config || true)
|
||||
endif
|
||||
|
||||
.PHONY: fb-setup
|
||||
fb-setup:
|
||||
$(QUIET)$(call silent_on_success,Facebook setup,\
|
||||
$(MAKE) -C facebook setup)
|
||||
|
||||
OCAMLFORMAT_EXE?=ocamlformat
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
parallel $(OCAMLFORMAT_EXE) -i ::: $$(git diff --name-only --diff-filter=ACMRU $$(git merge-base origin/master HEAD) | grep "\.mli\?$$")
|
||||
|
||||
DUNE_ML:=$(shell find * -name 'dune*.in' | grep -v workspace)
|
||||
|
||||
.PHONY: fmt_dune
|
||||
fmt_dune:
|
||||
parallel $(OCAMLFORMAT_EXE) -i ::: $(DUNE_ML)
|
||||
|
||||
SRC_ML:=$(shell find * \( -name _build -or -name facebook-clang-plugins -or -path facebook/dependencies -or -path sledge/llvm \) -not -prune -or -type f -and -name '*'.ml -or -name '*'.mli 2>/dev/null)
|
||||
|
||||
.PHONY: fmt_all
|
||||
fmt_all:
|
||||
parallel $(OCAMLFORMAT_EXE) -i ::: $(SRC_ML) $(DUNE_ML)
|
||||
|
||||
# pre-building these avoids race conditions when building, eg src_build and test_build in parallel
|
||||
.PHONY: src_build_common
|
||||
src_build_common:
|
||||
$(QUIET)$(call silent_on_success,Generating source dependencies,\
|
||||
$(MAKE_SOURCE) src_build_common)
|
||||
|
||||
.PHONY: src_build
|
||||
src_build: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Building native($(BUILD_MODE)) Infer,\
|
||||
$(MAKE_SOURCE) infer)
|
||||
|
||||
.PHONY: byte
|
||||
byte: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Building byte Infer,\
|
||||
$(MAKE_SOURCE) byte)
|
||||
|
||||
.PHONY: test_build
|
||||
test_build: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Testing Infer builds without warnings,\
|
||||
$(MAKE_SOURCE) test)
|
||||
|
||||
# deadcode analysis: only do the deadcode detection on Facebook builds and if GNU sed is available
|
||||
.PHONY: real_deadcode
|
||||
real_deadcode: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Testing there is no dead OCaml code,\
|
||||
$(MAKE) -C $(SRC_DIR)/deadcode)
|
||||
|
||||
.PHONY: deadcode
|
||||
deadcode:
|
||||
ifeq ($(IS_FACEBOOK_TREE),no)
|
||||
$(QUIET)echo "Deadcode detection only works in Facebook builds, skipping"
|
||||
endif
|
||||
ifeq ($(GNU_SED),no)
|
||||
$(QUIET)echo "Deadcode detection only works with GNU sed installed, skipping"
|
||||
endif
|
||||
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
ifneq ($(GNU_SED),no)
|
||||
deadcode: real_deadcode
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: toplevel toplevel_test
|
||||
toplevel toplevel_test: src_build_common
|
||||
|
||||
toplevel:
|
||||
$(QUIET)$(call silent_on_success,Building Infer REPL,\
|
||||
$(MAKE_SOURCE) toplevel)
|
||||
$(QUIET)echo
|
||||
$(QUIET)echo "You can now use the infer REPL:"
|
||||
$(QUIET)echo " \"$(ABSOLUTE_ROOT_DIR)/scripts/infer_repl\""
|
||||
|
||||
toplevel_test: test_build
|
||||
$(QUIET)$(call silent_on_success,Building Infer REPL (test mode),\
|
||||
$(MAKE_SOURCE) BUILD_MODE=test toplevel)
|
||||
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
byte src_build_common src_build test_build: fb-setup
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_C_ANALYZERS),yes)
|
||||
byte src_build src_build_common test_build: clang_plugin
|
||||
endif
|
||||
|
||||
$(INFER_COMMAND_MANUALS): src_build $(MAKEFILE_LIST)
|
||||
$(QUIET)$(MKDIR_P) $(@D)
|
||||
$(QUIET)$(INFER_BIN) $(patsubst infer-%.1,%,$(@F)) --help --help-format=groff > $@
|
||||
|
||||
$(INFER_COMMAND_TEXT_MANUALS): src_build $(MAKEFILE_LIST)
|
||||
$(QUIET)$(MKDIR_P) $(@D)
|
||||
$(QUIET)$(INFER_BIN) $(patsubst infer-%.txt,%,$(@F)) --help --help-format=plain > $@
|
||||
|
||||
$(INFER_MANUAL): src_build $(MAKEFILE_LIST)
|
||||
$(QUIET)$(MKDIR_P) $(@D)
|
||||
$(QUIET)$(INFER_BIN) --help --help-format=groff > $@
|
||||
|
||||
$(INFER_TEXT_MANUAL): src_build $(MAKEFILE_LIST)
|
||||
$(QUIET)$(MKDIR_P) $(@D)
|
||||
$(QUIET)$(INFER_BIN) --help --help-format=plain > $@
|
||||
|
||||
$(INFER_FULL_TEXT_MANUAL): src_build $(MAKEFILE_LIST)
|
||||
$(QUIET)$(MKDIR_P) $(@D)
|
||||
$(QUIET)$(INFER_BIN) --help-full --help-format=plain > $@
|
||||
|
||||
$(INFER_GROFF_MANUALS_GZIPPED): %.gz: %
|
||||
$(QUIET)$(REMOVE) $@
|
||||
gzip $<
|
||||
|
||||
infer_models: src_build
|
||||
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
|
||||
$(MAKE) -C $(ANNOTATIONS_DIR)
|
||||
endif
|
||||
$(MAKE) -C $(MODELS_DIR) all
|
||||
|
||||
.PHONY: infer byte_infer
|
||||
infer byte_infer:
|
||||
$(QUIET)$(call silent_on_success,Building Infer models,\
|
||||
$(MAKE) infer_models)
|
||||
$(QUIET)$(call silent_on_success,Building Infer manuals,\
|
||||
$(MAKE) $(INFER_MANUALS))
|
||||
infer: src_build
|
||||
byte_infer: byte
|
||||
|
||||
.PHONY: opt
|
||||
opt:
|
||||
$(QUIET)$(MAKE) BUILD_MODE=opt infer
|
||||
|
||||
.PHONY: clang_setup
|
||||
clang_setup:
|
||||
# if clang is already built then let the user know they might not need to rebuild clang
|
||||
$(QUIET)export CC="$(CC)" CFLAGS="$(CFLAGS)"; \
|
||||
export CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)"; \
|
||||
export CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)"; \
|
||||
$(FCP_DIR)/clang/setup.sh --only-check-install || { \
|
||||
if [ -x '$(FCP_DIR)'/clang/install/bin/clang ]; then \
|
||||
echo '$(TERM_INFO)*** Now building clang, this will take a while...$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** If you believe that facebook-clang-plugins/clang/install is up-to-date you can$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** interrupt the compilation (Control-C) and run this to prevent clang from being rebuilt:$(TERM_RESET)' >&2; \
|
||||
echo >&2 ; \
|
||||
echo '$(TERM_INFO) $(FCP_DIR)/clang/setup.sh --only-record-install$(TERM_RESET)' >&2; \
|
||||
echo >&2 ; \
|
||||
echo '$(TERM_INFO)(TIP: you can also force a clang rebuild by removing $(FCP_DIR)/clang/installed.version)$(TERM_RESET)' >&2; \
|
||||
echo >&2 ; \
|
||||
fi; \
|
||||
$(FCP_DIR)/clang/setup.sh; \
|
||||
}
|
||||
|
||||
.PHONY: clang_plugin
|
||||
clang_plugin: clang_setup
|
||||
$(QUIET)$(call silent_on_success,Building clang plugin,\
|
||||
$(MAKE) -C $(FCP_DIR)/libtooling all \
|
||||
CC="$(CC)" CXX="$(CXX)" \
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \
|
||||
CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \
|
||||
LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \
|
||||
CLANG_PREFIX=$(CLANG_PREFIX) \
|
||||
CLANG_INCLUDES=$(CLANG_INCLUDES))
|
||||
$(QUIET)$(call silent_on_success,Building clang plugin OCaml interface,\
|
||||
$(MAKE) -C $(FCP_DIR)/clang-ocaml all \
|
||||
build/clang_ast_proj.ml build/clang_ast_proj.mli \
|
||||
CC=$(CC) CXX=$(CXX) \
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \
|
||||
CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \
|
||||
LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \
|
||||
CLANG_PREFIX=$(CLANG_PREFIX) \
|
||||
CLANG_INCLUDES=$(CLANG_INCLUDES))
|
||||
|
||||
.PHONY: clang_plugin_test
|
||||
clang_plugin_test: clang_setup
|
||||
$(QUIET)$(call silent_on_success,Running facebook-clang-plugins/libtooling/ tests,\
|
||||
$(MAKE) -C $(FCP_DIR)/libtooling test \
|
||||
CC=$(CC) CXX=$(CXX) \
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \
|
||||
CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \
|
||||
LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \
|
||||
CLANG_PREFIX=$(CLANG_PREFIX) \
|
||||
CLANG_INCLUDES=$(CLANG_INCLUDES))
|
||||
$(QUIET)$(call silent_on_success,Running facebook-clang-plugins/clang-ocaml/ tests,\
|
||||
$(MAKE) -C $(FCP_DIR)/clang-ocaml test \
|
||||
CC=$(CC) CXX=$(CXX) \
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \
|
||||
CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \
|
||||
LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \
|
||||
CLANG_PREFIX=$(CLANG_PREFIX) \
|
||||
CLANG_INCLUDES=$(CLANG_INCLUDES))
|
||||
|
||||
.PHONY: clang_plugin_test
|
||||
clang_plugin_test_replace: clang_setup
|
||||
$(QUIET)$(call silent_on_success,Running facebook-clang-plugins/libtooling/ record tests,\
|
||||
$(MAKE) -C $(FCP_DIR)/libtooling record-test-outputs \
|
||||
CC=$(CC) CXX=$(CXX) \
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \
|
||||
CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \
|
||||
LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \
|
||||
CLANG_PREFIX=$(CLANG_PREFIX) \
|
||||
CLANG_INCLUDES=$(CLANG_INCLUDES))
|
||||
$(QUIET)$(call silent_on_success,Running facebook-clang-plugins/clang-ocaml/ record tests,\
|
||||
$(MAKE) -C $(FCP_DIR)/clang-ocaml record-test-outputs \
|
||||
CC=$(CC) CXX=$(CXX) \
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \
|
||||
CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \
|
||||
LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \
|
||||
CLANG_PREFIX=$(CLANG_PREFIX) \
|
||||
CLANG_INCLUDES=$(CLANG_INCLUDES))
|
||||
|
||||
.PHONY: ocaml_unit_test
|
||||
ocaml_unit_test: test_build
|
||||
$(QUIET)$(REMOVE_DIR) infer-out-unit-tests
|
||||
$(QUIET)$(call silent_on_success,Running OCaml unit tests,\
|
||||
INFER_ARGS=--results-dir^infer-out-unit-tests $(BUILD_DIR)/test/inferunit.bc)
|
||||
|
||||
define silence_make
|
||||
$(1) 2> >(grep -v 'warning: \(ignoring old\|overriding\) \(commands\|recipe\) for target')
|
||||
endef
|
||||
|
||||
.PHONY: $(DIRECT_TESTS:%=direct_%_test)
|
||||
$(DIRECT_TESTS:%=direct_%_test): infer
|
||||
$(QUIET)$(call silent_on_success,Running test: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C \
|
||||
$(INFER_DIR)/tests/codetoanalyze/$(shell printf $@ | cut -f 2 -d _)/$(shell printf $@ | cut -f 3 -d _) \
|
||||
test))
|
||||
|
||||
.PHONY: $(DIRECT_TESTS:%=direct_%_print)
|
||||
$(DIRECT_TESTS:%=direct_%_print): infer
|
||||
$(QUIET)$(call silent_on_success,Running: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C \
|
||||
$(INFER_DIR)/tests/codetoanalyze/$(shell printf $@ | cut -f 2 -d _)/$(shell printf $@ | cut -f 3 -d _) \
|
||||
print))
|
||||
|
||||
.PHONY: $(DIRECT_TESTS:%=direct_%_clean)
|
||||
$(DIRECT_TESTS:%=direct_%_clean):
|
||||
$(QUIET)$(call silent_on_success,Cleaning: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C \
|
||||
$(INFER_DIR)/tests/codetoanalyze/$(shell printf $@ | cut -f 2 -d _)/$(shell printf $@ | cut -f 3 -d _) \
|
||||
clean))
|
||||
|
||||
.PHONY: $(DIRECT_TESTS:%=direct_%_replace)
|
||||
$(DIRECT_TESTS:%=direct_%_replace): infer
|
||||
$(QUIET)$(call silent_on_success,Recording: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C \
|
||||
$(INFER_DIR)/tests/codetoanalyze/$(shell printf $@ | cut -f 2 -d _)/$(shell printf $@ | cut -f 3 -d _) \
|
||||
replace))
|
||||
|
||||
.PHONY: direct_tests
|
||||
direct_tests: $(DIRECT_TESTS:%=direct_%_test)
|
||||
|
||||
.PHONY: $(BUILD_SYSTEMS_TESTS:%=build_%_test)
|
||||
$(BUILD_SYSTEMS_TESTS:%=build_%_test): infer
|
||||
$(QUIET)$(call silent_on_success,Running test: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C $(INFER_DIR)/tests/build_systems/$(patsubst build_%_test,%,$@) test))
|
||||
|
||||
.PHONY: $(BUILD_SYSTEMS_TESTS:%=build_%_print)
|
||||
$(BUILD_SYSTEMS_TESTS:%=build_%_print): infer
|
||||
$(QUIET)$(call silent_on_success,Running: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C $(INFER_DIR)/tests/build_systems/$(patsubst build_%_print,%,$@) print))
|
||||
|
||||
.PHONY: $(BUILD_SYSTEMS_TESTS:%=build_%_clean)
|
||||
$(BUILD_SYSTEMS_TESTS:%=build_%_clean):
|
||||
$(QUIET)$(call silent_on_success,Cleaning: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C $(INFER_DIR)/tests/build_systems/$(patsubst build_%_clean,%,$@) clean))
|
||||
|
||||
.PHONY: $(BUILD_SYSTEMS_TESTS:%=build_%_replace)
|
||||
$(BUILD_SYSTEMS_TESTS:%=build_%_replace): infer
|
||||
$(QUIET)$(call silent_on_success,Recording: $(subst _, ,$@),\
|
||||
$(call silence_make,\
|
||||
$(MAKE) -C $(INFER_DIR)/tests/build_systems/$(patsubst build_%_replace,%,$@) replace))
|
||||
|
||||
build_infertop_print build_infertop_test build_infertop_replace: toplevel_test
|
||||
|
||||
.PHONY: build_systems_tests
|
||||
build_systems_tests: $(BUILD_SYSTEMS_TESTS:%=build_%_test)
|
||||
|
||||
.PHONY: endtoend_test
|
||||
endtoend_test: $(BUILD_SYSTEMS_TESTS:%=build_%_test) $(DIRECT_TESTS:%=direct_%_test)
|
||||
|
||||
.PHONY: check_missing_mli
|
||||
check_missing_mli:
|
||||
$(QUIET)for x in $$(find $(INFER_DIR)/src -name "*.ml"); do \
|
||||
test -f "$$x"i || echo Missing "$$x"i; done
|
||||
|
||||
.PHONY: checkCopyright
|
||||
checkCopyright: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Building checkCopyright,\
|
||||
$(MAKE) -C $(SRC_DIR) checkCopyright)
|
||||
|
||||
.PHONY: validate-skel
|
||||
validate-skel:
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
$(QUIET)$(call silent_on_success,Validating facebook/,\
|
||||
$(MAKE) -C facebook validate)
|
||||
endif
|
||||
|
||||
.PHONY: crash_if_not_all_analyzers_enabled
|
||||
crash_if_not_all_analyzers_enabled:
|
||||
ifneq ($(BUILD_C_ANALYZERS)+$(BUILD_JAVA_ANALYZERS),yes+yes)
|
||||
ifneq ($(BUILD_C_ANALYZERS),yes)
|
||||
@echo '*** ERROR: Cannot run the full tests: the Clang analyzers are disabled.'
|
||||
@echo '*** ERROR: You can run clang-only tests with:'
|
||||
@echo '*** ERROR:'
|
||||
@echo '*** ERROR: make config_tests'
|
||||
@echo '*** ERROR:'
|
||||
endif
|
||||
ifneq ($(BUILD_JAVA_ANALYZERS),yes)
|
||||
@echo '*** ERROR: Cannot run the full tests: the Java analyzers are disabled.'
|
||||
@echo '*** ERROR: You can run Java-only tests with:'
|
||||
@echo '*** ERROR:'
|
||||
@echo '*** ERROR: make config_tests'
|
||||
@echo '*** ERROR:'
|
||||
endif
|
||||
@echo '*** ERROR: To run the full set of tests, please enable all the analyzers.'
|
||||
@exit 1
|
||||
else
|
||||
@:
|
||||
endif
|
||||
|
||||
.PHONY: mod_dep
|
||||
mod_dep: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Building Infer source dependency graph,\
|
||||
$(MAKE) -C $(SRC_DIR) mod_dep.dot)
|
||||
|
||||
.PHONY: config_tests
|
||||
config_tests: test_build ocaml_unit_test endtoend_test checkCopyright validate-skel mod_dep
|
||||
|
||||
ifneq ($(filter config_tests test,${MAKECMDGOALS}),)
|
||||
test_build: src_build
|
||||
checkCopyright: src_build test_build
|
||||
endif
|
||||
|
||||
.PHONY: test
|
||||
test: crash_if_not_all_analyzers_enabled config_tests
|
||||
ifeq (,$(findstring s,$(MAKEFLAGS)))
|
||||
$(QUIET)echo "$(TERM_INFO)ALL TESTS PASSED$(TERM_RESET)"
|
||||
endif
|
||||
|
||||
.PHONY: quick-test
|
||||
quick-test: test_build ocaml_unit_test
|
||||
|
||||
.PHONY: test-replace
|
||||
test-replace: $(BUILD_SYSTEMS_TESTS:%=build_%_replace) $(DIRECT_TESTS:%=direct_%_replace) \
|
||||
clang_plugin_test_replace
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
$(REMOVE_DIR) $(DESTDIR)$(libdir)/infer/
|
||||
$(REMOVE) $(DESTDIR)$(bindir)/infer
|
||||
$(REMOVE) $(INFER_COMMANDS:%=$(DESTDIR)$(bindir)/%)
|
||||
$(REMOVE) $(foreach manual,$(INFER_GROFF_MANUALS_GZIPPED),\
|
||||
$(DESTDIR)$(mandir)/man1/$(notdir $(manual)))
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
$(MAKE) -C facebook uninstall
|
||||
endif
|
||||
|
||||
.PHONY: test_clean
|
||||
test_clean: $(DIRECT_TESTS:%=direct_%_clean) $(BUILD_SYSTEMS_TESTS:%=build_%_clean)
|
||||
|
||||
.PHONY: install
|
||||
install: infer $(INFER_GROFF_MANUALS_GZIPPED)
|
||||
# create directory structure
|
||||
test -d '$(DESTDIR)$(bindir)' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(bindir)'
|
||||
test -d '$(DESTDIR)$(mandir)/man1' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(mandir)/man1'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/'
|
||||
ifeq ($(BUILD_C_ANALYZERS),yes)
|
||||
test -d '$(DESTDIR)$(libdir)/infer/facebook-clang-plugins/libtooling/build/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/facebook-clang-plugins/libtooling/build/'
|
||||
find facebook-clang-plugins/clang/install/. -type d -print0 | xargs -0 -n 1 \
|
||||
$(SHELL) -x -c "test -d '$(DESTDIR)$(libdir)'/infer/\$$1 || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)'/infer/\$$1" --
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/clang_wrappers/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/clang_wrappers/'
|
||||
find infer/models/cpp/include -type d -print0 | xargs -0 -n 1 \
|
||||
$(SHELL) -x -c "test -d '$(DESTDIR)$(libdir)'/infer/\$$1 || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)'/infer/\$$1" --
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/linter_rules/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/linter_rules/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/etc/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/etc'
|
||||
endif
|
||||
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/java/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/java/'
|
||||
endif
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/annotations/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/annotations/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/wrappers/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/wrappers/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/specs/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/specs/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/python/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/python/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/python/inferlib/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/python/inferlib/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/lib/python/inferlib/capture/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/lib/python/inferlib/capture/'
|
||||
test -d '$(DESTDIR)$(libdir)/infer/infer/bin/' || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)/infer/infer/bin/'
|
||||
# copy files
|
||||
ifeq ($(BUILD_C_ANALYZERS),yes)
|
||||
$(INSTALL_DATA) -C 'facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib' \
|
||||
'$(DESTDIR)$(libdir)/infer/facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib'
|
||||
# do not use "install" for symbolic links as this will copy the destination file instead
|
||||
find facebook-clang-plugins/clang/install/. -not -type d -not -type l -not -name '*.a' -print0 \
|
||||
| xargs -0 -I \{\} $(INSTALL_PROGRAM) -C \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
# all the symlinks in clang are relative and safe to brutally copy over
|
||||
find facebook-clang-plugins/clang/install/. -type l -not -name '*.a' -print0 \
|
||||
| xargs -0 -I \{\} $(COPY) -a \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
find infer/lib/clang_wrappers/* -print0 | xargs -0 -I \{\} \
|
||||
$(INSTALL_PROGRAM) -C \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
# only for files that point to infer
|
||||
(cd '$(DESTDIR)$(libdir)/infer/infer/lib/wrappers/' && \
|
||||
$(foreach cc,$(shell find '$(LIB_DIR)/wrappers' -type l), \
|
||||
[ $(cc) -ef '$(INFER_BIN)' ] && \
|
||||
$(REMOVE) '$(notdir $(cc))' && \
|
||||
$(LN_S) ../../bin/infer '$(notdir $(cc))';))
|
||||
find infer/lib/specs/* -print0 | xargs -0 -I \{\} \
|
||||
$(INSTALL_DATA) -C \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
find infer/models/cpp/include -not -type d -print0 | xargs -0 -I \{\} \
|
||||
$(INSTALL_DATA) -C \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
$(INSTALL_DATA) -C 'infer/lib/linter_rules/linters.al' \
|
||||
'$(DESTDIR)$(libdir)/infer/infer/lib/linter_rules/linters.al'
|
||||
$(INSTALL_DATA) -C 'infer/etc/clang_ast.dict' \
|
||||
'$(DESTDIR)$(libdir)/infer/infer/etc/clang_ast.dict'
|
||||
endif
|
||||
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
|
||||
$(INSTALL_DATA) -C 'infer/annotations/annotations.jar' \
|
||||
'$(DESTDIR)$(libdir)/infer/infer/annotations/annotations.jar'
|
||||
find infer/lib/java/*.jar -print0 | xargs -0 -I \{\} \
|
||||
$(INSTALL_DATA) -C \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
$(INSTALL_PROGRAM) -C '$(LIB_DIR)'/wrappers/javac \
|
||||
'$(DESTDIR)$(libdir)'/infer/infer/lib/wrappers/
|
||||
endif
|
||||
find infer/lib/python/inferlib/* -type f -print0 | xargs -0 -I \{\} \
|
||||
$(INSTALL_DATA) -C \{\} '$(DESTDIR)$(libdir)'/infer/\{\}
|
||||
$(INSTALL_PROGRAM) -C infer/lib/python/infer.py \
|
||||
'$(DESTDIR)$(libdir)'/infer/infer/lib/python/infer.py
|
||||
$(INSTALL_PROGRAM) -C infer/lib/python/inferTraceBugs \
|
||||
'$(DESTDIR)$(libdir)'/infer/infer/lib/python/inferTraceBugs
|
||||
$(INSTALL_PROGRAM) -C infer/lib/python/report.py \
|
||||
'$(DESTDIR)$(libdir)'/infer/infer/lib/python/report.py
|
||||
$(INSTALL_PROGRAM) -C '$(INFER_BIN)' '$(DESTDIR)$(libdir)'/infer/infer/bin/
|
||||
(cd '$(DESTDIR)$(bindir)/' && \
|
||||
$(REMOVE) infer && \
|
||||
$(LN_S) '$(libdir_relative_to_bindir)'/infer/infer/bin/infer infer)
|
||||
for alias in $(INFER_COMMANDS); do \
|
||||
(cd '$(DESTDIR)$(bindir)'/ && \
|
||||
$(REMOVE) "$$alias" && \
|
||||
$(LN_S) infer "$$alias"); done
|
||||
for alias in $(INFER_COMMANDS); do \
|
||||
(cd '$(DESTDIR)$(libdir)'/infer/infer/bin && \
|
||||
$(REMOVE) "$$alias" && \
|
||||
$(LN_S) infer "$$alias"); done
|
||||
$(foreach man,$(INFER_GROFF_MANUALS_GZIPPED), \
|
||||
$(INSTALL_DATA) -C $(man) '$(DESTDIR)$(mandir)/man1/$(notdir $(man))';)
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
ifdef DESTDIR
|
||||
ifeq (,$(findstring :/,:$(DESTDIR)))
|
||||
# DESTDIR is set and relative
|
||||
$(MAKE) -C facebook install 'DESTDIR=../$(DESTDIR)'
|
||||
else
|
||||
# DESTDIR is set and absolute
|
||||
$(MAKE) -C facebook install
|
||||
endif
|
||||
else
|
||||
# DESTDIR not set
|
||||
$(MAKE) -C facebook install
|
||||
endif
|
||||
endif
|
||||
|
||||
# install dynamic libraries
|
||||
# use this if you want to distribute infer binaries
|
||||
install-with-libs: install
|
||||
test -d '$(DESTDIR)$(libdir)'/infer/infer/libso || \
|
||||
$(MKDIR_P) '$(DESTDIR)$(libdir)'/infer/infer/libso
|
||||
ifneq ($(OPAM),no)
|
||||
set -x; \
|
||||
OPAM_SHARE=$$($(OPAM) config var share); \
|
||||
APRON_LIB_PATHS="$$OPAM_SHARE/apron/lib/libapron.so $$OPAM_SHARE/apron/lib/liboctMPQ.so"; \
|
||||
ELINA_LIB_PATHS="$$OPAM_SHARE/elina/lib/libelinalinearize.so $$OPAM_SHARE/elina/lib/liboptpoly.so $$OPAM_SHARE/elina/lib/libpartitions.so"; \
|
||||
$(INSTALL_PROGRAM) -C $$APRON_LIB_PATHS '$(DESTDIR)$(libdir)'/infer/infer/libso/; \
|
||||
$(INSTALL_PROGRAM) -C $$ELINA_LIB_PATHS '$(DESTDIR)$(libdir)'/infer/infer/libso/
|
||||
ifneq ($(LDD),no)
|
||||
ifneq ($(PATCHELF),no)
|
||||
# this sort of assumes Linux
|
||||
# figure out where libgmp and libmpfr are using ldd
|
||||
set -x; \
|
||||
for lib in $$($(LDD) $(INFER_BIN) \
|
||||
| cut -d ' ' -f 3 \
|
||||
| grep -e 'lib\(gmp\|mpfr\)'); do \
|
||||
$(INSTALL_PROGRAM) -C "$$lib" '$(DESTDIR)$(libdir)'/infer/infer/libso/; \
|
||||
done
|
||||
# update rpath of executables
|
||||
for sofile in '$(DESTDIR)$(libdir)'/infer/infer/libso/*.so; do \
|
||||
$(PATCHELF) --set-rpath '$$ORIGIN' --force-rpath "$$sofile"; \
|
||||
done
|
||||
$(PATCHELF) --set-rpath '$$ORIGIN/../libso' --force-rpath '$(DESTDIR)$(libdir)'/infer/infer/bin/infer
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
$(PATCHELF) --set-rpath '$$ORIGIN/../libso' --force-rpath '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks
|
||||
endif
|
||||
else # ldd found but not patchelf
|
||||
echo "ERROR: ldd (Linux?) found but not patchelf, please install patchelf" >&2; exit 1
|
||||
endif
|
||||
else # ldd not found
|
||||
ifneq ($(OTOOL),no)
|
||||
ifneq ($(INSTALL_NAME_TOOL),no)
|
||||
# this sort of assumes osx
|
||||
# figure out where libgmp and libmpfr are using otool
|
||||
set -e; \
|
||||
set -x; \
|
||||
for lib in $$($(OTOOL) -L $(INFER_BIN) \
|
||||
| cut -d ' ' -f 1 | tr -d '\t' \
|
||||
| grep -e 'lib\(gmp\|mpfr\)'); do \
|
||||
$(INSTALL_PROGRAM) -C "$$lib" '$(DESTDIR)$(libdir)'/infer/infer/libso/; \
|
||||
done
|
||||
set -x; \
|
||||
for sofile in '$(DESTDIR)$(libdir)'/infer/infer/libso/*.{so,dylib}; do \
|
||||
$(INSTALL_NAME_TOOL) -add_rpath "@executable_path" "$$sofile" 2> /dev/null || true; \
|
||||
scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso "$$sofile"; \
|
||||
done
|
||||
$(INSTALL_NAME_TOOL) -add_rpath '@executable_path/../libso' '$(DESTDIR)$(libdir)'/infer/infer/bin/infer 2> /dev/null || true
|
||||
scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso '$(DESTDIR)$(libdir)'/infer/infer/bin/infer
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
$(INSTALL_NAME_TOOL) -add_rpath '@executable_path/../libso' '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks 2> /dev/null || true
|
||||
scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks
|
||||
endif
|
||||
else # install_name_tool not found
|
||||
echo "ERROR: otool (OSX?) found but not install_name_tool, please install install_name_tool" >&2; exit 1
|
||||
endif
|
||||
else # otool not found
|
||||
echo "ERROR: need ldd + patchelf (Linux) or otool + install_name_tool (OSX) available" >&2; exit 1
|
||||
endif
|
||||
endif # ldd
|
||||
else # opam
|
||||
echo "ERROR: need opam" >&2; exit 1
|
||||
endif
|
||||
|
||||
# Nuke objects built from OCaml. Useful when changing the OCaml compiler, for instance.
|
||||
.PHONY: ocaml_clean
|
||||
ocaml_clean:
|
||||
ifeq ($(BUILD_C_ANALYZERS),yes)
|
||||
$(QUIET)$(call silent_on_success,Cleaning facebook-clang-plugins OCaml build,\
|
||||
$(MAKE) -C $(FCP_DIR)/clang-ocaml clean)
|
||||
endif
|
||||
$(QUIET)$(call silent_on_success,Cleaning infer OCaml build,\
|
||||
$(MAKE) -C $(SRC_DIR) clean)
|
||||
$(QUIET)$(call silent_on_success,Cleaning ocamldot,\
|
||||
$(MAKE) -C $(DEPENDENCIES_DIR)/ocamldot clean)
|
||||
|
||||
.PHONY: clean
|
||||
clean: ocaml_clean test_clean
|
||||
ifeq ($(BUILD_C_ANALYZERS),yes)
|
||||
$(QUIET)$(call silent_on_success,Cleaning facebook-clang-plugins C++ build,\
|
||||
$(MAKE) -C $(FCP_DIR) clean)
|
||||
endif
|
||||
$(QUIET)$(call silent_on_success,Cleaning Java annotations,\
|
||||
$(MAKE) -C $(ANNOTATIONS_DIR) clean)
|
||||
$(QUIET)$(call silent_on_success,Cleaning infer models,\
|
||||
$(MAKE) -C $(MODELS_DIR) clean)
|
||||
ifeq ($(IS_FACEBOOK_TREE),yes)
|
||||
$(QUIET)$(call silent_on_success,Cleaning facebook/,\
|
||||
$(MAKE) -C facebook clean)
|
||||
endif
|
||||
$(QUIET)$(call silent_on_success,Removing *.o and *.o.sh,\
|
||||
find $(INFER_DIR)/tests \( -name '*.o' -o -name '*.o.sh' \) -delete)
|
||||
$(QUIET)$(call silent_on_success,Removing build logs,\
|
||||
$(REMOVE_DIR) _build_logs)
|
||||
|
||||
.PHONY: conf-clean
|
||||
conf-clean: clean
|
||||
$(REMOVE) $(PYTHON_DIR)/inferlib/*.pyc
|
||||
$(REMOVE) $(PYTHON_DIR)/inferlib/*/*.pyc
|
||||
$(REMOVE) .buckversion
|
||||
$(REMOVE) Makefile.config
|
||||
$(REMOVE) acinclude.m4
|
||||
$(REMOVE) aclocal.m4
|
||||
$(REMOVE_DIR) autom4te.cache/
|
||||
$(REMOVE) config.log
|
||||
$(REMOVE) config.status
|
||||
$(REMOVE) configure
|
||||
$(REMOVE_DIR) $(MODELS_DIR)/c/out/
|
||||
$(REMOVE_DIR) $(MODELS_DIR)/cpp/out/
|
||||
$(REMOVE_DIR) $(MODELS_DIR)/java/infer-out/
|
||||
$(REMOVE_DIR) $(MODELS_DIR)/objc/out/
|
||||
|
||||
|
||||
# phony because it depends on opam's internal state
|
||||
.PHONY: opam.locked
|
||||
opam.locked: opam
|
||||
# allow users to not force a run of opam update since it's very slow
|
||||
ifeq ($(NO_OPAM_UPDATE),)
|
||||
$(QUIET)$(call silent_on_success,opam update,$(OPAM) update)
|
||||
endif
|
||||
$(QUIET)$(call silent_on_success,generating opam.locked,\
|
||||
$(OPAM) lock .)
|
||||
|
||||
# This is a magical version number that doesn't reinstall the world when added on top of what we
|
||||
# have in opam.locked. To upgrade this version number, manually try to install several utop versions
|
||||
# until you find one that doesn't recompile the world. TODO(t20828442): get rid of magic
|
||||
OPAM_DEV_DEPS = ocamlformat.$$(grep version .ocamlformat | cut -d ' ' -f 3) ocp-indent merlin utop.2.2.0 webbrowser
|
||||
|
||||
ifneq ($(EMACS),no)
|
||||
OPAM_DEV_DEPS += tuareg
|
||||
endif
|
||||
|
||||
.PHONY: devsetup
|
||||
devsetup: Makefile.autoconf
|
||||
$(QUIET)[ $(OPAM) != "no" ] || (echo 'No `opam` found, aborting setup.' >&2; exit 1)
|
||||
$(QUIET)$(call silent_on_success,installing $(OPAM_DEV_DEPS),\
|
||||
OPAMSWITCH=$(OPAMSWITCH); $(OPAM) install --yes --no-checksum user-setup $(OPAM_DEV_DEPS))
|
||||
$(QUIET)echo '$(TERM_INFO)*** Running `opam user-setup`$(TERM_RESET)' >&2
|
||||
$(QUIET)OPAMSWITCH=$(OPAMSWITCH); OPAMYES=1; $(OPAM) user-setup install
|
||||
$(QUIET)if [ "$(PLATFORM)" = "Darwin" ] && [ x"$(GNU_SED)" = x"no" ]; then \
|
||||
echo '$(TERM_INFO)*** Installing GNU sed$(TERM_RESET)' >&2; \
|
||||
brew install gnu-sed; \
|
||||
fi
|
||||
$(QUIET)if [ "$(PLATFORM)" = "Darwin" ] && ! $$(parallel -h | grep -q GNU); then \
|
||||
echo '$(TERM_INFO)*** Installing GNU parallel$(TERM_RESET)' >&2; \
|
||||
brew install parallel; \
|
||||
fi
|
||||
$(QUIET)if [ ! -d "$$HOME"/.parallel ]; then mkdir "$$HOME"/.parallel; fi
|
||||
$(QUIET)touch "$$HOME"/.parallel/will-cite
|
||||
# expand all occurrences of "~" in PATH and MANPATH
|
||||
$(QUIET)infer_repo_is_in_path=$$(echo $${PATH//\~/$$HOME} | grep -q "$(ABSOLUTE_ROOT_DIR)"/infer/bin; echo $$?); \
|
||||
infer_repo_is_in_manpath=$$(echo $${MANPATH//\~/$$HOME} | grep -q "$(ABSOLUTE_ROOT_DIR)"/infer/man; echo $$?); \
|
||||
shell_config_file="<could not auto-detect, please fill in yourself>"; \
|
||||
if [ $$(basename "$(ORIG_SHELL)") = "bash" ]; then \
|
||||
if [ "$(PLATFORM)" = "Linux" ]; then \
|
||||
shell_config_file="$$HOME"/.bashrc; \
|
||||
else \
|
||||
shell_config_file="$$HOME"/.bash_profile; \
|
||||
fi; \
|
||||
elif [ $$(basename "$(ORIG_SHELL)") = "zsh" ]; then \
|
||||
shell_config_file="$$HOME"/.zshrc; \
|
||||
fi; \
|
||||
if [ "$$infer_repo_is_in_path" != "0" ] || [ "$$infer_repo_is_in_manpath" != "0" ]; then \
|
||||
echo >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: `infer` is not in your PATH or MANPATH. If you are hacking on infer, you may$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: want to make infer executables and manuals available in your terminal. Type$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: the following commands to configure the current terminal and record the$(TERM_RESET)' >&2; \
|
||||
printf '$(TERM_INFO)*** NOTE: changes in your shell configuration file (%s):$(TERM_RESET)\n' "$$shell_config_file">&2; \
|
||||
echo >&2; \
|
||||
if [ "$$infer_repo_is_in_path" != "0" ]; then \
|
||||
printf '$(TERM_INFO) export PATH="%s/infer/bin":$$PATH$(TERM_RESET)\n' "$(ABSOLUTE_ROOT_DIR)" >&2; \
|
||||
fi; \
|
||||
if [ "$$infer_repo_is_in_manpath" != "0" ]; then \
|
||||
printf '$(TERM_INFO) export MANPATH="%s/infer/man":$$MANPATH$(TERM_RESET)\n' "$(ABSOLUTE_ROOT_DIR)" >&2; \
|
||||
fi; \
|
||||
if [ "$$infer_repo_is_in_path" != "0" ]; then \
|
||||
printf "$(TERM_INFO) echo 'export PATH=\"%s/infer/bin\":\$$PATH' >> \"$$shell_config_file\"$(TERM_RESET)\n" "$(ABSOLUTE_ROOT_DIR)" >&2; \
|
||||
fi; \
|
||||
if [ "$$infer_repo_is_in_manpath" != "0" ]; then \
|
||||
printf "$(TERM_INFO) echo 'export MANPATH=\"%s/infer/man\":\$$MANPATH' >> \"$$shell_config_file\"$(TERM_RESET)\n" "$(ABSOLUTE_ROOT_DIR)" >&2; \
|
||||
fi; \
|
||||
fi; \
|
||||
if [ -z "$(ORIG_SHELL_BUILD_MODE)" ]; then \
|
||||
echo >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: Set `BUILD_MODE=default` in your shell to disable flambda by default.$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: Compiling with flambda is ~5 times slower than without, so unless you are$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: testing infer on a very large project it will not be worth it. Use the$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: commands below to set the default build mode. You can then use `make opt`$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: when you really do want to enable flambda.$(TERM_RESET)' >&2; \
|
||||
echo >&2; \
|
||||
printf "$(TERM_INFO) export BUILD_MODE=default$(TERM_RESET)\n" >&2; \
|
||||
printf "$(TERM_INFO) echo 'export BUILD_MODE=default' >> \"$$shell_config_file\"$(TERM_RESET)\n" >&2; \
|
||||
fi
|
||||
$(QUIET)PATH=$(ORIG_SHELL_PATH); if [ "$$(ocamlc -where 2>/dev/null)" != "$$($(OCAMLC) -where)" ]; then \
|
||||
echo >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: The current shell is not set up for the right opam switch.$(TERM_RESET)' >&2; \
|
||||
echo '$(TERM_INFO)*** NOTE: Please run:$(TERM_RESET)' >&2; \
|
||||
echo >&2; \
|
||||
echo "$(TERM_INFO) eval \$$($(OPAM) env)$(TERM_RESET)" >&2; \
|
||||
fi
|
||||
|
||||
GHPAGES ?= no
|
||||
|
||||
.PHONY: doc
|
||||
doc: src_build_common
|
||||
$(QUIET)$(call silent_on_success,Generating infer documentation,\
|
||||
$(MAKE_SOURCE) doc)
|
||||
# do not call the browser if we are publishing the docs
|
||||
ifeq ($(filter doc-publish,${MAKECMDGOALS}),)
|
||||
$(QUIET)$(call silent_on_success,Opening in browser,\
|
||||
browse $(SRC_DIR)/_build/$(BUILD_MODE)/_doc/_html/index.html)
|
||||
$(QUIET)echo "Tip: you can generate the doc for all the opam dependencies of infer like this:"
|
||||
$(QUIET)echo
|
||||
$(QUIET)echo " odig odoc # takes a while, run it only when the dependencies change"
|
||||
$(QUIET)echo " odig doc"
|
||||
endif
|
||||
|
||||
.PHONY: doc-publish
|
||||
doc-publish: doc $(INFER_GROFF_MANUALS)
|
||||
ifeq ($(GHPAGES),no)
|
||||
$(QUIET)echo "$(TERM_ERROR)Please set GHPAGES to a checkout of the gh-pages branch of the GitHub repo of infer$(TERM_RESET)" >&2
|
||||
$(QUIET)exit 1
|
||||
endif
|
||||
# sanity check to avoid cryptic error messages and potentially annoying side-effects
|
||||
$(QUIET)if ! [ -d "$(GHPAGES)"/static/man ]; then \
|
||||
echo "$(TERM_ERROR)ERROR: GHPAGES doesn't seem to point to a checkout of the gh-pages branch of the GitHub repo of infer:$(TERM_RESET)" >&2; \
|
||||
echo "$(TERM_ERROR)ERROR: '$(GHPAGES)/static/man' not found or not a directory.$(TERM_RESET)" >&2; \
|
||||
echo "$(TERM_ERROR)ERROR: Please fix this and try again.$(TERM_RESET)" >&2; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(QUIET)$(call silent_on_success,Copying man pages,\
|
||||
$(REMOVE_DIR) "$(GHPAGES)"/static/man/*; \
|
||||
for man in $(INFER_GROFF_MANUALS); do \
|
||||
groff -Thtml "$$man" > "$(GHPAGES)"/static/man/$$(basename "$$man").html; \
|
||||
done)
|
||||
ifeq ($(IS_FACEBOOK_TREE),no)
|
||||
$(QUIET)$(call silent_on_success,Copying OCaml modules documentation,\
|
||||
version=$$($(INFER_BIN) --version | head -1 | cut -d ' ' -f 3 | cut -c 2-); \
|
||||
rsync -a --delete $(SRC_DIR)/_build/$(BUILD_MODE)/_doc/_html/ "$(GHPAGES)"/static/odoc/"$$version"; \
|
||||
$(REMOVE) "$(GHPAGES)"/static/odoc/latest; \
|
||||
$(LN_S) "$$version" "$(GHPAGES)"/static/odoc/latest)
|
||||
else
|
||||
$(QUIET)echo "Not an open-source tree, skipping the API docs generation"
|
||||
endif
|
||||
|
||||
# print list of targets
|
||||
.PHONY: show-targets
|
||||
show-targets:
|
||||
$(QUIET)$(MAKE) -pqrR . | grep --only-matching -e '^[a-zA-Z0-9][^ ]*:' | cut -d ':' -f 1 | sort
|
|
@ -1,96 +0,0 @@
|
|||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# 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_JAVA_ANALYZERS = @BUILD_JAVA_ANALYZERS@
|
||||
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@
|
||||
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@
|
||||
JAVAC = @JAVAC@
|
||||
JDK11_ENABLED = @JDK11_ENABLED@
|
||||
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@
|
||||
OCAMLBUILD = @OCAMLBUILD@
|
||||
OCAMLC = @OCAMLC@
|
||||
OCAMLFIND = @OCAMLFIND@
|
||||
OCAMLLEX = @OCAMLLEX@
|
||||
OCAMLOPT = @OCAMLOPT@
|
||||
OPAM = @OPAM@
|
||||
OPAMROOT = @OPAMROOT@
|
||||
OPAMSWITCH = @OPAMSWITCH@
|
||||
OTOOL = @OTOOL@
|
||||
PATCHELF = @PATCHELF@
|
||||
PATH = @PATH@
|
||||
prefix = @prefix@
|
||||
PYTHON_lxml = @PYTHON_lxml@
|
||||
SDKROOT = @SDKROOT@
|
||||
SHASUM = @SHASUM@
|
||||
USER_JAVA_HOME = @USER_JAVA_HOME@
|
||||
UTOP = @UTOP@
|
||||
XCODE_SELECT = @XCODE_SELECT@
|
||||
XCODE_BASE = @XCODE_BASE@
|
||||
HAS_OBJC = @HAS_OBJC@
|
||||
XCPRETTY = @XCPRETTY@
|
||||
WINDOWS_BUILD = @WINDOWS_BUILD@
|
||||
|
||||
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,199 +0,0 @@
|
|||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
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 = $(SRC_DIR)/_build
|
||||
|
||||
JAVA_LIB_DIR = $(LIB_DIR)/java
|
||||
SPECS_LIB_DIR = $(LIB_DIR)/specs
|
||||
|
||||
PYTHON_DIR = $(LIB_DIR)/python
|
||||
PYTHON_LIB_DIR = $(PYTHON_DIR)/inferlib
|
||||
CAPTURE_LIB_DIR = $(PYTHON_LIB_DIR)/capture
|
||||
|
||||
INFER_BIN = $(BIN_DIR)/infer
|
||||
INFER_COMMANDS = \
|
||||
infer-analyze \
|
||||
infer-capture \
|
||||
infer-compile \
|
||||
infer-explore \
|
||||
infer-report \
|
||||
infer-reportdiff \
|
||||
infer-run \
|
||||
|
||||
INFERTOP_BIN = $(BIN_DIR)/infertop.bc
|
||||
INFERUNIT_BIN = $(BIN_DIR)/InferUnit
|
||||
|
||||
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
|
||||
|
||||
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 = \
|
||||
$(addprefix $(PYTHON_LIB_DIR)/, \
|
||||
analyze.py bucklib.py config.py issues.py jwlib.py source.py utils.py) \
|
||||
$(addprefix $(CAPTURE_LIB_DIR)/, util.py) \
|
||||
$(ANDROID_JAR) $(GUAVA_JAR) $(JACKSON_JAR) $(JSR_305_JAR) $(INFER_ANNOTATIONS_JAR) \
|
||||
$(INFER_BIN)
|
||||
|
||||
JAVA_DEPS = $(JAVA_DEPS_NO_MODELS) $(JAVA_MODELS_JAR)
|
||||
|
||||
# marker to keep track of when clang models have been rebuilt
|
||||
MODELS_RESULTS_FILE = $(SPECS_LIB_DIR)/clang_models
|
||||
|
||||
CLANG_DEPS_NO_MODELS = \
|
||||
$(addprefix $(PYTHON_LIB_DIR)/, \
|
||||
analyze.py config.py issues.py source.py utils.py) \
|
||||
$(addprefix $(CAPTURE_LIB_DIR)/, util.py) \
|
||||
$(INFER_BIN)
|
||||
|
||||
CLANG_DEPS = $(CLANG_DEPS_NO_MODELS) $(MODELS_RESULTS_FILE) \
|
||||
$(shell find $(MODELS_DIR)/cpp/include -type f)
|
||||
|
||||
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)
|
||||
|
||||
# 99999 PIDs ought to be enough for anybody, but check if pid_max can be found just in case
|
||||
MAX_PID_SIZE = \
|
||||
$(shell PID_MAX=$$(cat /proc/sys/kernel/pid_max 2>/dev/null); echo $${\#PID_MAX} || 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 '$*=$($*)'
|
|
@ -1 +0,0 @@
|
|||
Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for how to set up your development environment and run tests.
|
|
@ -1,23 +0,0 @@
|
|||
# Infer [![Build Status](https://travis-ci.org/facebook/infer.svg?branch=master)](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.html) 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,70 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# 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
|
||||
|
||||
# try to pull submodules if we are in a git repo
|
||||
# might fail if git is not installed (how did you even checkout the
|
||||
# repo in the first place?)
|
||||
if test -d '.git' && [ -z "$SKIP_SUBMODULES" ] ; then
|
||||
printf 'git repository detected, updating submodule... '
|
||||
git submodule update --init > /dev/null
|
||||
printf 'done\n'
|
||||
else
|
||||
echo 'no git repository detected; not updating git submodules'
|
||||
fi
|
||||
|
||||
# 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,209 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Convenience script to build Infer when using opam
|
||||
|
||||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# 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"
|
||||
PLATFORM="$(uname)"
|
||||
NCPU="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)"
|
||||
INFER_OPAM_DEFAULT_SWITCH="ocaml-variants.4.07.1+flambda"
|
||||
INFER_OPAM_SWITCH=${INFER_OPAM_SWITCH:-$INFER_OPAM_DEFAULT_SWITCH}
|
||||
|
||||
function usage() {
|
||||
echo "Usage: $0 [-y] [targets]"
|
||||
echo
|
||||
echo " targets:"
|
||||
echo " all build everything (default)"
|
||||
echo " clang build C and Objective-C analyzer"
|
||||
echo " java build Java analyzer"
|
||||
echo
|
||||
echo " options:"
|
||||
echo " -h,--help show this message"
|
||||
echo " --no-opam-lock do not use the 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 and C/Objective-C analyzers"
|
||||
echo " $0 java clang # equivalent way of doing the above"
|
||||
echo " $0 java # build only the Java analyzer"
|
||||
}
|
||||
|
||||
# arguments
|
||||
BUILD_CLANG=${BUILD_CLANG:-no}
|
||||
BUILD_JAVA=${BUILD_JAVA:-no}
|
||||
INFER_CONFIGURE_OPTS=${INFER_CONFIGURE_OPTS:-""}
|
||||
INFER_OPAM_SWITCH=${INFER_OPAM_SWITCH:-$INFER_OPAM_SWITCH_DEFAULT}
|
||||
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="$*"
|
||||
|
||||
while [[ $# > 0 ]]; do
|
||||
opt_key="$1"
|
||||
case $opt_key in
|
||||
all)
|
||||
BUILD_CLANG=yes
|
||||
BUILD_JAVA=yes
|
||||
shift
|
||||
continue
|
||||
;;
|
||||
clang)
|
||||
BUILD_CLANG=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 no arguments then build both clang and Java
|
||||
if [ "$BUILD_CLANG" == "no" ] && [ "$BUILD_JAVA" == "no" ]; then
|
||||
BUILD_CLANG=yes
|
||||
BUILD_JAVA=yes
|
||||
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_switch_create_if_needed "$INFER_OPAM_SWITCH"
|
||||
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 "$INFER_ROOT" $locked
|
||||
}
|
||||
|
||||
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
|
||||
if [ "$BUILD_CLANG" == "no" ]; then
|
||||
SKIP_SUBMODULES=true ./autogen.sh > /dev/null
|
||||
else
|
||||
./autogen.sh > /dev/null
|
||||
fi
|
||||
|
||||
if [ "$BUILD_CLANG" == "no" ]; then
|
||||
INFER_CONFIGURE_OPTS+=" --disable-c-analyzers"
|
||||
fi
|
||||
if [ "$BUILD_JAVA" == "no" ]; then
|
||||
INFER_CONFIGURE_OPTS+=" --disable-java-analyzers"
|
||||
fi
|
||||
|
||||
./configure $INFER_CONFIGURE_OPTS
|
||||
|
||||
if [ "$BUILD_CLANG" == "yes" ] && ! facebook-clang-plugins/clang/setup.sh --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.html"
|
||||
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
|
||||
fi
|
||||
|
||||
make -j "$JOBS" || (
|
||||
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,371 +0,0 @@
|
|||
dnl Copyright (c) 2015-present, Facebook, Inc.
|
||||
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],
|
||||
[0.16.0],
|
||||
[https://github.com/facebook/infer/issues/])
|
||||
|
||||
AC_CONFIG_SRCDIR([infer/src/istd/IStd.ml])
|
||||
|
||||
# WARNING: keep in sync with above
|
||||
INFER_MAJOR=0
|
||||
INFER_MINOR=16
|
||||
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"
|
||||
])
|
||||
|
||||
windows_build=no
|
||||
AC_MSG_CHECKING([for Windows build])
|
||||
# see https://stackoverflow.com/questions/714100/os-detecting-makefile
|
||||
# but we do this in the configure for homogeneity
|
||||
case "${OS}" in
|
||||
Windows_NT*)
|
||||
windows_build=yes
|
||||
;;
|
||||
esac
|
||||
WINDOWS_BUILD=$windows_build
|
||||
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(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([PYTHON27], [python2.7], [no])
|
||||
AC_ASSERT_PROG([python2.7], [$PYTHON27])
|
||||
|
||||
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_SUBST([XCODE_BASE])
|
||||
AC_SUBST([HAS_OBJC])
|
||||
|
||||
# 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_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_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_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=`"$JAVAC" -version 2>&1 | head -n 1`
|
||||
[JDK11_ENABLED=`echo "$javac_version" | grep -E -q '^javac\ (11|1[0-9])' && echo yes`]
|
||||
if test "x$JDK11_ENABLED" = "xyes"; then
|
||||
USER_JAVA_HOME=$_USER_JAVA_HOME
|
||||
AC_SUBST([JDK11_ENABLED])
|
||||
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
|
||||
AC_MSG_CHECKING([which .buckversion to use])
|
||||
fb_buckversion_file=facebook/dependencies/dotbuckversion
|
||||
oss_buckversion_file=dotbuckversion
|
||||
AS_IF([test x"$is_facebook_tree" = x"yes"],
|
||||
[buckversion_file="$fb_buckversion_file"],
|
||||
[buckversion_file="$oss_buckversion_file"])
|
||||
cat "$buckversion_file" > ".buckversion"
|
||||
AC_MSG_RESULT([$buckversion_file])
|
||||
|
||||
|
||||
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_PYTHON_MODULE([$PYTHON27], [lxml])
|
||||
|
||||
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_ARG_VAR([SDKROOT], [path to the OSX platform SDK used by clang])
|
||||
AC_SUBST([SDKROOT])
|
||||
|
||||
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',
|
||||
],
|
||||
)
|
Двоичный файл не отображается.
|
@ -1,7 +0,0 @@
|
|||
prebuilt_jar(
|
||||
name = 'guava',
|
||||
binary_jar = 'guava-23.0.jar',
|
||||
visibility = [
|
||||
'PUBLIC'
|
||||
]
|
||||
)
|
Двоичные данные
infer/dependencies/java/guava/guava-23.0.jar
Двоичные данные
infer/dependencies/java/guava/guava-23.0.jar
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
prebuilt_jar(
|
||||
name = 'jackson',
|
||||
binary_jar = 'jackson-2.2.3.jar',
|
||||
deps = [
|
||||
'//dependencies/java/guava:guava',
|
||||
],
|
||||
visibility = [
|
||||
'PUBLIC',
|
||||
]
|
||||
)
|
Двоичные данные
infer/dependencies/java/jackson/jackson-2.2.3.jar
Двоичные данные
infer/dependencies/java/jackson/jackson-2.2.3.jar
Двоичный файл не отображается.
|
@ -1,8 +0,0 @@
|
|||
prebuilt_jar(
|
||||
name = 'jsr-305',
|
||||
binary_jar = 'jsr305.jar',
|
||||
source_jar = 'jsr305-src.jar',
|
||||
visibility = [
|
||||
'PUBLIC',
|
||||
],
|
||||
)
|
Двоичные данные
infer/dependencies/java/jsr-305/jsr305-src.jar
Двоичные данные
infer/dependencies/java/jsr-305/jsr305-src.jar
Двоичный файл не отображается.
Двоичные данные
infer/dependencies/java/jsr-305/jsr305.jar
Двоичные данные
infer/dependencies/java/jsr-305/jsr305.jar
Двоичный файл не отображается.
|
@ -1,7 +0,0 @@
|
|||
prebuilt_jar(
|
||||
name = 'jsr-330',
|
||||
binary_jar = 'javax.inject.jar',
|
||||
visibility = [
|
||||
'PUBLIC',
|
||||
],
|
||||
)
|
Двоичные данные
infer/dependencies/java/jsr-330/javax.inject.jar
Двоичные данные
infer/dependencies/java/jsr-330/javax.inject.jar
Двоичный файл не отображается.
|
@ -1,7 +0,0 @@
|
|||
prebuilt_jar(
|
||||
name = 'sun-tools',
|
||||
binary_jar = 'tools.jar',
|
||||
visibility = [
|
||||
'PUBLIC'
|
||||
]
|
||||
)
|
Двоичные данные
infer/dependencies/java/sun-tools/tools.jar
Двоичные данные
infer/dependencies/java/sun-tools/tools.jar
Двоичный файл не отображается.
|
@ -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) 2017-present, Facebook, Inc.
|
||||
#
|
||||
# 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,47 +0,0 @@
|
|||
FROM debian:stretch-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 \
|
||||
autoconf \
|
||||
automake \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
libc6-dev \
|
||||
libsqlite3-dev \
|
||||
opam \
|
||||
openjdk-8-jdk-headless \
|
||||
pkg-config \
|
||||
python2.7 \
|
||||
zlib1g-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Download the latest Infer release
|
||||
RUN INFER_VERSION=v0.14.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
|
||||
|
||||
# Compile Infer
|
||||
RUN OCAML_VERSION=4.06.1+flambda; \
|
||||
cd /infer && ./build-infer.sh --opam-switch $OCAML_VERSION && rm -rf /root/.opam
|
||||
|
||||
# Install Infer
|
||||
ENV INFER_HOME /infer/infer
|
||||
ENV PATH ${INFER_HOME}/bin:${PATH}
|
||||
|
||||
ENV ANDROID_HOME /opt/android-sdk-linux
|
||||
WORKDIR $ANDROID_HOME
|
||||
RUN curl -o sdk-tools-linux.zip \
|
||||
https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip && \
|
||||
unzip sdk-tools-linux.zip && \
|
||||
rm sdk-tools-linux.zip
|
||||
ENV PATH ${ANDROID_HOME}/tools/bin:${PATH}
|
||||
RUN echo "sdk.dir=${ANDROID_HOME}" > /infer/examples/android_hello/local.properties
|
|
@ -1,53 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
EXEC_NAME="$0"
|
||||
|
||||
show_usage() {
|
||||
echo "Usage: $EXEC_NAME [-h]"
|
||||
echo ""
|
||||
echo "Build and run the docker image. See infer/docker/README.md for more"
|
||||
echo "information."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help Show this message and exit"
|
||||
}
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
arg="$1"
|
||||
case $arg in
|
||||
"-h" | "--help" )
|
||||
show_usage;
|
||||
exit 0;
|
||||
;;
|
||||
*)
|
||||
echo "unknown argument $1"
|
||||
show_usage;
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! docker --version > /dev/null; then
|
||||
echo "docker install not working"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f Dockerfile ]; then
|
||||
echo "Dockerfile not found. Are you in the right directory?"
|
||||
echo "Please see infer/docker/README.md for more information."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NAME="infer"
|
||||
|
||||
docker build -t $NAME . && \
|
||||
echo "*************************************************************" && \
|
||||
echo "To build the Android example, you must accept the Android SDK" && \
|
||||
echo "licenses by running 'sdkmanager --licenses' first." && \
|
||||
echo "*************************************************************" && \
|
||||
docker run -it $NAME /bin/bash -c 'cd /infer/examples/; exec /bin/bash'
|
|
@ -1,35 +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. cd to the directory `docker/`,
|
||||
3. Build Infer in docker container and try on an example:
|
||||
|
||||
```sh
|
||||
# Build Infer; 20min or so; to be executed from docker/ in the Infer repo
|
||||
./run.sh
|
||||
# you should now be inside the docker container with a shell prompt, e.g.
|
||||
# "root@5c3b9af90d59:/infer/examples# "
|
||||
sdkmanager --licenses
|
||||
cd android_hello/
|
||||
infer -- ./gradlew build
|
||||
```
|
|
@ -1,74 +0,0 @@
|
|||
FROM debian:stretch-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 \
|
||||
autoconf \
|
||||
automake \
|
||||
bzip2 \
|
||||
cmake \
|
||||
curl \
|
||||
gcc \
|
||||
git \
|
||||
libc6-dev \
|
||||
libgmp-dev \
|
||||
libmpfr-dev \
|
||||
libsqlite3-dev \
|
||||
make \
|
||||
openjdk-8-jdk-headless \
|
||||
patch \
|
||||
pkg-config \
|
||||
python2.7 \
|
||||
unzip \
|
||||
zlib1g-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Some scripts in facebook-clang-plugins assume "python" is available
|
||||
RUN cd /usr/local/bin && ln -s /usr/bin/python2.7 python
|
||||
|
||||
# Install opam 2
|
||||
RUN curl -sL https://github.com/ocaml/opam/releases/download/2.0.2/opam-2.0.2-x86_64-linux > /usr/bin/opam && \
|
||||
chmod +x /usr/bin/opam
|
||||
|
||||
# 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
|
||||
|
||||
# Download the latest Infer master
|
||||
RUN cd / && \
|
||||
git clone 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 && \
|
||||
INFER_OPAM_SWITCH=4.07.1 ./build-infer.sh --only-setup-opam --no-opam-lock java && \
|
||||
opam clean
|
||||
|
||||
# Make sure clang is disabled
|
||||
RUN eval $(opam env) && \
|
||||
cd /infer && \
|
||||
SKIP_SUBMODULES=true ./autogen.sh && \
|
||||
./configure --disable-c-analyzers
|
||||
|
||||
# "Install" Infer. The tutorial assumes /infer-host is the working copy of infer so let's put it in the PATH too.
|
||||
ENV PATH /infer-host/infer/bin:/infer/bin:$PATH
|
||||
|
||||
# build in non-optimized mode by default to speed up build times
|
||||
ENV BUILD_MODE=default
|
||||
|
||||
# prevent exiting by compulsively hitting Control-D
|
||||
ENV IGNOREEOF=9
|
||||
|
||||
# should be moved earlier
|
||||
ENV INFER_OPAM_SWITCH=4.07.1
|
||||
|
||||
# export `opam env`
|
||||
ENV OPAM_SWITCH_PREFIX=/root/.opam/4.07.1
|
||||
ENV CAML_LD_LIBRARY_PATH=/root/.opam/4.07.1/lib/stublibs:/root/.opam/4.07.1/lib/ocaml/stublibs:/root/.opam/4.07.1/lib/ocaml
|
||||
ENV OCAML_TOPLEVEL_PATH=/root/.opam/4.07.1/lib/toplevel
|
||||
ENV MANPATH=$MANPATH:/root/.opam/4.07.1/man
|
||||
ENV PATH=/root/.opam/4.07.1/bin:$PATH
|
|
@ -1,73 +0,0 @@
|
|||
FROM debian:stretch-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 \
|
||||
autoconf \
|
||||
automake \
|
||||
bubblewrap \
|
||||
bzip2 \
|
||||
cmake \
|
||||
curl \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
libc6-dev \
|
||||
libgmp-dev \
|
||||
libmpfr-dev \
|
||||
libsqlite3-dev \
|
||||
make \
|
||||
openjdk-8-jdk-headless \
|
||||
patch \
|
||||
pkg-config \
|
||||
python2.7 \
|
||||
unzip \
|
||||
xz-utils \
|
||||
zlib1g-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Some scripts in facebook-clang-plugins assume "python" is available
|
||||
RUN cd /usr/local/bin && ln -s /usr/bin/python2.7 python
|
||||
|
||||
# Install opam 2
|
||||
RUN curl -sL https://github.com/ocaml/opam/releases/download/2.0.2/opam-2.0.2-x86_64-linux > /usr/bin/opam && \
|
||||
chmod +x /usr/bin/opam
|
||||
|
||||
# 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
|
||||
|
||||
# Download the latest Infer master
|
||||
RUN cd / && \
|
||||
git clone --recurse-submodules 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
|
||||
|
||||
# Hackish for now: pull to get the latest version
|
||||
RUN cd /infer && git pull
|
||||
|
||||
# if called with /infer-host mounted then copy infer there
|
||||
RUN if test -d /infer-host; then \
|
||||
cp -av /infer/. /infer-host; \
|
||||
fi
|
||||
|
||||
# Install Infer
|
||||
ENV INFER_HOME /infer/infer
|
||||
ENV PATH ${INFER_HOME}/bin:${PATH}
|
||||
|
||||
# build in non-optimized mode by default to speed up build times
|
||||
ENV BUILD_MODE=default
|
||||
|
||||
# prevent exiting by compulsively hitting Control-D
|
||||
ENV IGNOREEOF=9
|
|
@ -1 +0,0 @@
|
|||
f560ec067a2fdd7d6ee4a4e91ade70a1650c552f
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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();
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 9.2 KiB |
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 5.1 KiB |
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 14 KiB |
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 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
|
Двоичный файл не отображается.
|
@ -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) 2017-present, Facebook, Inc.
|
||||
#
|
||||
# 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) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* 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,13 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void test() {
|
||||
int* s = NULL;
|
||||
*s = 42;
|
||||
}
|
|
@ -1,433 +0,0 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
124F6C531B0CDAE400C16385 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C521B0CDAE400C16385 /* main.m */; };
|
||||
124F6C561B0CDAE400C16385 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C551B0CDAE400C16385 /* AppDelegate.m */; };
|
||||
124F6C591B0CDAE400C16385 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C581B0CDAE400C16385 /* ViewController.m */; };
|
||||
124F6C5C1B0CDAE400C16385 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 124F6C5A1B0CDAE400C16385 /* Main.storyboard */; };
|
||||
124F6C5E1B0CDAE400C16385 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 124F6C5D1B0CDAE400C16385 /* Images.xcassets */; };
|
||||
124F6C611B0CDAE400C16385 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 124F6C5F1B0CDAE400C16385 /* LaunchScreen.xib */; };
|
||||
124F6C6D1B0CDAE400C16385 /* HelloWorldAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C6C1B0CDAE400C16385 /* HelloWorldAppTests.m */; };
|
||||
124F6C771B0CED9B00C16385 /* Hello.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C761B0CED9B00C16385 /* Hello.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
124F6C671B0CDAE400C16385 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 124F6C451B0CDAE400C16385 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 124F6C4C1B0CDAE400C16385;
|
||||
remoteInfo = HelloWorldApp;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
124F6C4D1B0CDAE400C16385 /* HelloWorldApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorldApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
124F6C511B0CDAE400C16385 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
124F6C521B0CDAE400C16385 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
124F6C541B0CDAE400C16385 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
124F6C551B0CDAE400C16385 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
124F6C571B0CDAE400C16385 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||
124F6C581B0CDAE400C16385 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
|
||||
124F6C5B1B0CDAE400C16385 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
124F6C5D1B0CDAE400C16385 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
124F6C601B0CDAE400C16385 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
124F6C661B0CDAE400C16385 /* HelloWorldAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HelloWorldAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
124F6C6B1B0CDAE400C16385 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
124F6C6C1B0CDAE400C16385 /* HelloWorldAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldAppTests.m; sourceTree = "<group>"; };
|
||||
124F6C761B0CED9B00C16385 /* Hello.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Hello.m; sourceTree = "<group>"; };
|
||||
124F6C781B0CEDAF00C16385 /* Hello.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Hello.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
124F6C4A1B0CDAE400C16385 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
124F6C631B0CDAE400C16385 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
124F6C441B0CDAE400C16385 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
124F6C4F1B0CDAE400C16385 /* HelloWorldApp */,
|
||||
124F6C691B0CDAE400C16385 /* HelloWorldAppTests */,
|
||||
124F6C4E1B0CDAE400C16385 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
124F6C4E1B0CDAE400C16385 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
124F6C4D1B0CDAE400C16385 /* HelloWorldApp.app */,
|
||||
124F6C661B0CDAE400C16385 /* HelloWorldAppTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
124F6C4F1B0CDAE400C16385 /* HelloWorldApp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
124F6C541B0CDAE400C16385 /* AppDelegate.h */,
|
||||
124F6C551B0CDAE400C16385 /* AppDelegate.m */,
|
||||
124F6C571B0CDAE400C16385 /* ViewController.h */,
|
||||
124F6C581B0CDAE400C16385 /* ViewController.m */,
|
||||
124F6C5A1B0CDAE400C16385 /* Main.storyboard */,
|
||||
124F6C5D1B0CDAE400C16385 /* Images.xcassets */,
|
||||
124F6C5F1B0CDAE400C16385 /* LaunchScreen.xib */,
|
||||
124F6C501B0CDAE400C16385 /* Supporting Files */,
|
||||
124F6C761B0CED9B00C16385 /* Hello.m */,
|
||||
124F6C781B0CEDAF00C16385 /* Hello.h */,
|
||||
);
|
||||
path = HelloWorldApp;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
124F6C501B0CDAE400C16385 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
124F6C511B0CDAE400C16385 /* Info.plist */,
|
||||
124F6C521B0CDAE400C16385 /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
124F6C691B0CDAE400C16385 /* HelloWorldAppTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
124F6C6C1B0CDAE400C16385 /* HelloWorldAppTests.m */,
|
||||
124F6C6A1B0CDAE400C16385 /* Supporting Files */,
|
||||
);
|
||||
path = HelloWorldAppTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
124F6C6A1B0CDAE400C16385 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
124F6C6B1B0CDAE400C16385 /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
124F6C4C1B0CDAE400C16385 /* HelloWorldApp */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 124F6C701B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldApp" */;
|
||||
buildPhases = (
|
||||
124F6C491B0CDAE400C16385 /* Sources */,
|
||||
124F6C4A1B0CDAE400C16385 /* Frameworks */,
|
||||
124F6C4B1B0CDAE400C16385 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = HelloWorldApp;
|
||||
productName = HelloWorldApp;
|
||||
productReference = 124F6C4D1B0CDAE400C16385 /* HelloWorldApp.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
124F6C651B0CDAE400C16385 /* HelloWorldAppTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 124F6C731B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldAppTests" */;
|
||||
buildPhases = (
|
||||
124F6C621B0CDAE400C16385 /* Sources */,
|
||||
124F6C631B0CDAE400C16385 /* Frameworks */,
|
||||
124F6C641B0CDAE400C16385 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
124F6C681B0CDAE400C16385 /* PBXTargetDependency */,
|
||||
);
|
||||
name = HelloWorldAppTests;
|
||||
productName = HelloWorldAppTests;
|
||||
productReference = 124F6C661B0CDAE400C16385 /* HelloWorldAppTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
124F6C451B0CDAE400C16385 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0620;
|
||||
ORGANIZATIONNAME = "Dulma Rodriguez";
|
||||
TargetAttributes = {
|
||||
124F6C4C1B0CDAE400C16385 = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
};
|
||||
124F6C651B0CDAE400C16385 = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
TestTargetID = 124F6C4C1B0CDAE400C16385;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 124F6C481B0CDAE400C16385 /* Build configuration list for PBXProject "HelloWorldApp" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 124F6C441B0CDAE400C16385;
|
||||
productRefGroup = 124F6C4E1B0CDAE400C16385 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
124F6C4C1B0CDAE400C16385 /* HelloWorldApp */,
|
||||
124F6C651B0CDAE400C16385 /* HelloWorldAppTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
124F6C4B1B0CDAE400C16385 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
124F6C5C1B0CDAE400C16385 /* Main.storyboard in Resources */,
|
||||
124F6C611B0CDAE400C16385 /* LaunchScreen.xib in Resources */,
|
||||
124F6C5E1B0CDAE400C16385 /* Images.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
124F6C641B0CDAE400C16385 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
124F6C491B0CDAE400C16385 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
124F6C591B0CDAE400C16385 /* ViewController.m in Sources */,
|
||||
124F6C561B0CDAE400C16385 /* AppDelegate.m in Sources */,
|
||||
124F6C771B0CED9B00C16385 /* Hello.m in Sources */,
|
||||
124F6C531B0CDAE400C16385 /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
124F6C621B0CDAE400C16385 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
124F6C6D1B0CDAE400C16385 /* HelloWorldAppTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
124F6C681B0CDAE400C16385 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 124F6C4C1B0CDAE400C16385 /* HelloWorldApp */;
|
||||
targetProxy = 124F6C671B0CDAE400C16385 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
124F6C5A1B0CDAE400C16385 /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
124F6C5B1B0CDAE400C16385 /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
124F6C5F1B0CDAE400C16385 /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
124F6C601B0CDAE400C16385 /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
124F6C6E1B0CDAE400C16385 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
124F6C6F1B0CDAE400C16385 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
124F6C711B0CDAE400C16385 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = HelloWorldApp/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
124F6C721B0CDAE400C16385 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = HelloWorldApp/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
124F6C741B0CDAE400C16385 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = HelloWorldAppTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorldApp.app/HelloWorldApp";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
124F6C751B0CDAE400C16385 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = HelloWorldAppTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorldApp.app/HelloWorldApp";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
124F6C481B0CDAE400C16385 /* Build configuration list for PBXProject "HelloWorldApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
124F6C6E1B0CDAE400C16385 /* Debug */,
|
||||
124F6C6F1B0CDAE400C16385 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
124F6C701B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
124F6C711B0CDAE400C16385 /* Debug */,
|
||||
124F6C721B0CDAE400C16385 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
124F6C731B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldAppTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
124F6C741B0CDAE400C16385 /* Debug */,
|
||||
124F6C751B0CDAE400C16385 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 124F6C451B0CDAE400C16385 /* Project object */;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:HelloWorldApp.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
Двоичный файл не отображается.
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "HelloWorldApp/AppDelegate.m"
|
||||
timestampString = "453837074.323482"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "30"
|
||||
endingLineNumber = "30"
|
||||
landmarkName = "-resource_leak_bug"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
|
@ -1,112 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
|
||||
BuildableName = "HelloWorldApp.app"
|
||||
BlueprintName = "HelloWorldApp"
|
||||
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "124F6C651B0CDAE400C16385"
|
||||
BuildableName = "HelloWorldAppTests.xctest"
|
||||
BlueprintName = "HelloWorldAppTests"
|
||||
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "124F6C651B0CDAE400C16385"
|
||||
BuildableName = "HelloWorldAppTests.xctest"
|
||||
BlueprintName = "HelloWorldAppTests"
|
||||
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
|
||||
BuildableName = "HelloWorldApp.app"
|
||||
BlueprintName = "HelloWorldApp"
|
||||
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
|
||||
BuildableName = "HelloWorldApp.app"
|
||||
BlueprintName = "HelloWorldApp"
|
||||
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
|
||||
BuildableName = "HelloWorldApp.app"
|
||||
BlueprintName = "HelloWorldApp"
|
||||
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче