OCLint.0.source-code-of-oclint
Source Code Of OCLint
OCLint Version: 2022.02
1. Dependency of OCLint
"OCLint is based on libTooling for parsing source code and generating Abstract Syntax Tree (AST) generation." Ref[3]
2. Build Release
After download the source code of OCLint 2022.02 from github, we will build it using the make script.
It's so simple to build OCLint using make script as the Ref[1]:
cd oclint-scripts ./make cd ..
Assume the OCLINT_ROOT_PATH is root path of OCLint source code at local host.
2.1 make script
The make script depends on the ci script which is a python script. The content of make script is as the following:
#! /bin/sh -e ./ci -reset "$@" ./ci -setup -release "$@"
2.2 ci script
A. The work of ./ci -reset "$@"
Remove the paths:
${OCLINT_ROOT_PATH}/build
${OCLINT_ROOT_PATH}/llvm
${OCLINT_ROOT_PATH}/googletest
${OCLINT_ROOT_PATH}/oclint-json-compilation-database
${OCLINT_ROOT_PATH}/oclint-xcodebuild
B. The work of ./ci -setup -release "$@"
// Download the oclint-json-compilation-database tool which is the wrapper of OCLint tool.
// This tool provides the inclusion and exclusion flags (-i, -e) to generate the source list for OCLint.
git clone https://github.com/oclint/oclint-json-compilation-database.git
//Download the oclint-xcodebuild tool which is a helper program that converts xcodebuild log to compile_commands.json.
// NOTE: This project is no longer under maintenance by OCLint team!
git clone https://github.com/oclint/oclint-xcodebuild.git
// Prepare the llvm libraries and LLVMExports.cmake file
// NOTE: This step should be avoided after the dev environment is already prepared at the first time.
// The works of the clang tool as the following:
// A. Download and install the release of llvm+clang
// curl -L -o prebuilt.tar.xz https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/clang+llvm-13.0.1-x86_64-apple-darwin.tar.xz
// tar xf prebuilt.tar.xz -C ${OCLINT_ROOT_PATH}/build/llvm-install --strip-components=1
// B. Write the following content into file ${OCLINT_ROOT_PATH}/build/llvm-install/lib/cmake/llvm/LLVMExports.cmake
// INTERFACE_LINK_LIBRARIES "m;ZLIB::ZLIB;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libcurses.tbd;LLVMDemangle"
/usr/local/opt/python@3.9/bin/python3.9 clang
// Delete the directory of the module, then build the modules: core, metrics, rules, reporters, driver
/usr/local/opt/python@3.9/bin/python3.9 build -clean -release -j 4
// Call the bundle to install the products which are built by previous step.
/usr/local/opt/python@3.9/bin/python3.9 bundle
"python3.9 build -release -j 4 " will execute the following commands:
cmake -G Ninja -D OCLINT_BUILD_TYPE=Release -D LLVM_ROOT=${OCLINT_ROOT_PATH}/build/llvm-install ${OCLINT_ROOT_PATH}/oclint-core
cmake -G Ninja -D OCLINT_BUILD_TYPE=Release -D LLVM_ROOT=${OCLINT_ROOT_PATH}/build/llvm-install ${OCLINT_ROOT_PATH}/oclint-metrics
cmake -G Ninja -D OCLINT_BUILD_TYPE=Release
-D LLVM_ROOT=${OCLINT_ROOT_PATH}/build/llvm-install
-D OCLINT_SOURCE_DIR=${OCLINT_ROOT_PATH}/oclint-core
-D OCLINT_BUILD_DIR=${OCLINT_ROOT_PATH}/build/oclint-core
-D OCLINT_METRICS_SOURCE_DIR=${OCLINT_ROOT_PATH}/oclint-metrics
-D OCLINT_METRICS_BUILD_DIR=${OCLINT_ROOT_PATH}/build/oclint-metrics
${OCLINT_ROOT_PATH}/oclint-rules
cmake -G Ninja -D OCLINT_BUILD_TYPE=Release
-D LLVM_ROOT=${OCLINT_ROOT_PATH}/build/llvm-install
-D OCLINT_SOURCE_DIR=${OCLINT_ROOT_PATH}/oclint-core
-D OCLINT_BUILD_DIR=${OCLINT_ROOT_PATH}/build/oclint-core
${OCLINT_ROOT_PATH}/oclint-reporters
cmake -G Ninja -D OCLINT_BUILD_TYPE=Release
-D LLVM_ROOT=${OCLINT_ROOT_PATH}/build/llvm-install
-D OCLINT_SOURCE_DIR=${OCLINT_ROOT_PATH}/oclint-core
-D OCLINT_BUILD_DIR=${OCLINT_ROOT_PATH}/build/oclint-core
${OCLINT_ROOT_PATH}/oclint-driver
3. Build for Rules Development
4. Source Code Structure
The file tree in the ${OCLINT_ROOT_PATH} as the following:
├── LICENSE ├── README.md ├── build ├── oclint-core ├── oclint-driver ├── oclint-metrics ├── oclint-reporters ├── oclint-rules └── oclint-scripts
4.1 oclint-core Module
Tow libraries will be generated by oclint-core module. These libraries are: OCLintCore, OCLintRuleSet.
This module also provide a CMake Module: OCLintConfig.cmake.
What's CMake Module?
4.2 CMake Modlue: OCLintConfig
Look at OCLint.3.OCLintConfig.cmake-file
4.3 oclint-Driver Module
The module create an executable (oclint-${OCLINT_VERSION_RELEASE} we refer to it as oclint for short) and a library (OCLintDriver).
The executable dynamically load the Rules and Reporter. The executable depends on these libraries:
TARGET_LINK_LIBRARIES(oclint-${OCLINT_VERSION_RELEASE} OCLintDriver OCLintRuleSet OCLintCore clangStaticAnalyzerFrontend clangStaticAnalyzerCheckers clangStaticAnalyzerCore clangRewriteFrontend clangRewrite clangCrossTU clangIndex ${CLANG_LIBRARIES} ${REQ_LLVM_LIBRARIES} ${CMAKE_DL_LIBS} )
The executable first load the Rules and Reporter dynamic libraries by the dlopen() function.
4.4 oclint-rules Module
This module create a dynamic library (OCLintAbstractRule) on which other rules depended.
The rules are orginzed by category, each rule is built into a dynamic library.
The defalut categories are:
basic, convention, design, migration, redundant, unused, abstract, cocoa, cuda, empty, naming, size.
The abstract category is not built into dynamic library, it just contains base classes for other rule class.
4.4.1 Rule Dynamic Library
Each rule depends on OCLintAbstractRule, clangASTMatchers, OCLintMetric, OCLintHelper, OCLintUtil, OCLintCore.
// ${OCLINT_ROOT_PATH}/oclint-rules/rules/CMakeLists.txt
IF (MINGW) TARGET_LINK_LIBRARIES(${name}Rule OCLintAbstractRule OCLintMetric ) ELSE() TARGET_LINK_LIBRARIES(${name}Rule OCLintAbstractRule) TARGET_LINK_LIBRARIES(${name}Rule clangASTMatchers ) # TODO: might be redundant TARGET_LINK_LIBRARIES(${name}Rule OCLintMetric OCLintHelper OCLintUtil OCLintCore ) IF (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") TARGET_LINK_LIBRARIES(${name}Rule ${CLANG_LIBRARIES} ${REQ_LLVM_LIBRARIES} OCLintRuleSet ) ENDIF() ENDIF()
4.5 oclint-metrics module
Cyclomatic Complexity,
Ncss (non-commenting source statements, Ref[5], Ref[6]),
NPathComplexity (Ref[6]),
StmtDepth.
4.6 oclint-reporters module
The module built the reporters: HTMLReporter, JSONReporter, PMDReporter, TextReporter, XcodeReporter, XMLReporter.
Each reporter is a dynamic library which depends on OCLintCore.
MACRO(build_dynamic_reporter name)
// ... ...
TARGET_LINK_LIBRARIES(${name}Reporter
OCLintCore
)
ENDMACRO(build_dynamic_reporter)
5. The stps in oclint
Reference
1. Building OCLint
This page presents building OCLint in release mode.
https://docs.oclint.org/en/stable/intro/build.html
2. Development [To Read]
http://docs.oclint.org/en/stable/devel/index.html
3. System Requirement
http://docs.oclint.org/en/stable/devel/requirements.html#llvm-system-requirements
4. 2022.02 version of OCLint
https://github.com/oclint/oclint/releases/tag/v22.02
5. Code Metrics
Driving up quality with automated review
http://www.codingthearchitecture.com/2006/12/15/code_metrics.html
6. Index of Java code metrics
https://pmd.github.io/latest/pmd_java_metrics_index.html