Home
To compile LIEF, you need at least the following requirements:
C++14 compiler (GCC, Clang, MSVC..)
CMake
Python >= 3.6 (for the bindings)
To build the documentation:
Doxygen (= 1.8.10
, the CI uses 1.8.20
)
Sphinx (with sphinx_rtd_theme
module)
breathe (>= 4.25.1
)
Note
A compilation from scratch with all the options enabled can take ~30 minutes on a regular laptop.
$ git clone https://github.com/lief-project/LIEF.git
$ cd LIEF
$ mkdir build
$ cd build
$ cmake -DLIEF_PYTHON_API=off -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --target LIB_LIEF --config Release
Warning
On Windows one can choose the CRT to use by setting the LIEF_USE_CRT_<RELEASE;DEBUG;..>
variable:
$ cmake -DCMAKE_BUILD_TYPE=Release -DLIEF_USE_CRT_RELEASE=MT ..
For Debug, you should set the CRT to MTd:
$ cmake -DCMAKE_BUILD_TYPE=Debug -DLIEF_USE_CRT_DEBUG=MTd ..
$ cmake --build . --target LIB_LIEF --config Debug
$ git clone https://github.com/lief-project/LIEF.git
$ cd LIEF
$ python ./setup.py [--ninja] build install [--user]
If you want to enable tests, you can add --lief-test
after setup.py
.
By default, LIEF is compiled with CMAKE_BUILD_TYPE
set to Release
. One can change this behavior by setting either RelWithDebInfo
or Debug
during the cmake’s configuration step:
$ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo [...] ..
On the other hand, Python bindings can also be compiled with debug information by using the --debug
flag:
$ python ./setup.py build --debug
Note
When developing on LIEF, you can use:
$ python ./setup [--ninja] build --debug develop --user
Compared to the install
command, develop
creates a .egg-link
that links to the native LIEF library currently presents in you build directory.
The --user
flag is used to avoid creating the .egg-link
system-wide (i.e. /usr/lib/python3.9/site-packages
). Instead, it links the .egg-link
in the user’s local dir (e.g. ~/.local/lib/python3.9/site-packages
)
LIEF relies on few external projects and we try to limit as much as possible the dependencies in the public headers. This table summarizes these dependencies and their scope. internal
means that it is required to compile LIEF but it is not required to use LIEF. external
means that it is required for both.
Dependency | Scope | Purpose |
| C++11 span interface | |
| Error handling (see: Error Handling ) | |
| Logging | |
| ASN.1 parser / Hash functions | |
| Unicode support (for PE and DEX files) | |
| Serialize LIEF’s object into JSON | |
| Python bindings | |
|
| |
| Testing | |
| ELF Fuzzing |
Except MbedTLS, all these dependencies are header-only and they are by default embedded/managed by LIEF such as it eases the compilation and the integration.
Nevertheless, packages manager might require to not self-use/embed external dependencies 1 2.
To address this requirement, the user can control the integration of LIEF’s dependencies using the following cmake’s options:
LIEF_OPT_NLOHMANN_JSON_EXTERNAL
LIEF_OPT_EXTERNAL_LEAF
/LIEF_EXTERNAL_LEAF_DIR
LIEF_OPT_UTFCPP_EXTERNAL
LIEF_OPT_MBEDTLS_EXTERNAL
LIEF_EXTERNAL_SPDLOG
LIEF_OPT_FROZEN_EXTERNAL
LIEF_OPT_EXTERNAL_SPAN/LIEF_EXTERNAL_SPAN_DIR
LIEF_OPT_PYBIND11_EXTERNAL
By setting these flags, LIEF resolves the dependencies with CMake find_package(...)
which is aware of <DEPS>_DIR
to find the package. Boost’s Leaf does not provide CMake files that can be resolved with find_package
so the user can provide LIEF_EXTERNAL_LEAF_DIR
instead, which must point to the directory that contains boost/leaf
.
As a result, LIEF can be, for instance, compiled with the following configuration:
$ cmake .. -GNinja \
-DLIEF_OPT_NLOHMANN_JSON_EXTERNAL=ON \
-Dnlohmann_json_DIR=/lief-third-party/json/install/lib/cmake/nlohmann_json \
-DLIEF_OPT_MBEDTLS_EXTERNAL=on \
-DMbedTLS_DIR=/lief-third-party/mbedtls/install/cmake \
-DLIEF_OPT_EXTERNAL_LEAF=on \
-DLIEF_EXTERNAL_LEAF_DIR=/lief-third-party/leaf/include/cmake
Warning
As mentioned previously, MbedTLS is not header-only which means that if it is externalized the static version of LIEF won’t include the MbedTLS object files and the end user will have to link again LIEF.a
with a provided version of MbedTLS.
LIEF uses different CI (Github Action, AppVeyor, …) to test and release nightly builds. The configuration of these CI can also be a good source of information for the compilation process. In particular, scripts/docker/travis-linux-sdk.sh contains the build process to generate the Linux x86-64 SDK.
The build_script
section of .appveyor.yml contains the logic for generating Windows Python wheels and the SDK.
For OSX & iOS, the CI configs .github/workflows/ios.yml and .github/workflows/osx.yml to compile (and cross-compile) LIEF for these platforms.
if(__add_lief_options)
return()
endif()
set(__add_lief_options ON)
include(CMakeDependentOption)
option(LIEF_TESTS "Enable tests" OFF)
option(LIEF_DOC "Enable documentation" OFF)
option(LIEF_PYTHON_API "Enable Python Bindings" OFF)
option(LIEF_C_API "C API" ON)
option(LIEF_EXAMPLES "Build LIEF C++ examples" ON)
option(LIEF_FORCE32 "Force build LIEF 32 bits version" OFF)
option(LIEF_COVERAGE "Perform code coverage" OFF)
option(LIEF_USE_CCACHE "Use ccache to speed up compilation" ON)
option(LIEF_EXTRA_WARNINGS "Enable extra warning from the compiler" OFF)
option(LIEF_LOGGING "Enable logging" ON)
option(LIEF_LOGGING_DEBUG "Enable debug logging" ON)
option(LIEF_ENABLE_JSON "Enable JSON-related APIs" ON)
option(LIEF_OPT_NLOHMANN_JSON_EXTERNAL "Use nlohmann/json externaly" OFF)
option(LIEF_FORCE_API_EXPORTS "Force exports of API symbols" OFF)
option(LIEF_DISABLE_FROZEN "Disable Frozen even if it is supported" OFF)
option(LIEF_ELF "Build LIEF with ELF module" ON)
option(LIEF_PE "Build LIEF with PE module" ON)
option(LIEF_MACHO "Build LIEF with MachO module" ON)
option(LIEF_DEX "Build LIEF with DEX module" ON)
option(LIEF_ART "Build LIEF with ART module" ON)
# OAT support relies on the ELF and DEX format.
# Therefore, these options must be enabled to support use this format
cmake_dependent_option(LIEF_OAT "Build LIEF with OAT module" ON
"LIEF_ELF;LIEF_DEX" OFF)
# VDEX format depends on the DEX module
cmake_dependent_option(LIEF_VDEX "Build LIEF with VDEX module" ON
"LIEF_DEX" OFF)
# Sanitizer
option(LIEF_ASAN "Enable Address sanitizer" OFF)
option(LIEF_LSAN "Enable Leak sanitizer" OFF)
option(LIEF_TSAN "Enable Thread sanitizer" OFF)
option(LIEF_USAN "Enable undefined sanitizer" OFF)
# Fuzzer
option(LIEF_FUZZING "Fuzz LIEF" OFF)
# Profiling
option(LIEF_PROFILING "Enable performance profiling" OFF)
# Install options
cmake_dependent_option(LIEF_INSTALL_COMPILED_EXAMPLES "Install LIEF Compiled examples" OFF
"LIEF_EXAMPLES" OFF)
# Use a user-provided version of spdlog
# It can be useful to reduce compile time
option(LIEF_EXTERNAL_SPDLOG OFF)
# This option enables to provide an external
# version of Boost Leaf (e.g. present on the system)
option(LIEF_OPT_EXTERNAL_LEAF OFF)
set(LIEF_EXTERNAL_LEAF_DIR )
# This option enables to provide an external version of utf8cpp
option(LIEF_OPT_UTFCPP_EXTERNAL OFF)
# This option enables to provide an external version of MbedTLS
option(LIEF_OPT_MBEDTLS_EXTERNAL OFF)
# This option enables to provide an external version of pybind11
option(LIEF_OPT_PYBIND11_EXTERNAL OFF)
# This option enables to provide an external
# version of https://github.com/tcbrindle/span (e.g. present on the system)
option(LIEF_OPT_EXTERNAL_SPAN OFF)
set(LIEF_EXTERNAL_SPAN_DIR )
# This option enables to provide an external version of Frozen
set(_LIEF_USE_FROZEN ON)
if(LIEF_DISABLE_FROZEN)
set(_LIEF_USE_FROZEN OFF)
endif()
cmake_dependent_option(LIEF_OPT_FROZEN_EXTERNAL "Use an external provided version of Frozen" OFF
"_LIEF_USE_FROZEN" OFF)
set(LIEF_ELF_SUPPORT 0)
set(LIEF_PE_SUPPORT 0)
set(LIEF_MACHO_SUPPORT 0)
set(LIEF_OAT_SUPPORT 0)
set(LIEF_DEX_SUPPORT 0)
set(LIEF_VDEX_SUPPORT 0)
set(LIEF_ART_SUPPORT 0)
set(LIEF_JSON_SUPPORT 0)
set(LIEF_NLOHMANN_JSON_EXTERNAL 0)
set(LIEF_LOGGING_SUPPORT 0)
set(LIEF_LOGGING_DEBUG_SUPPORT 0)
set(LIEF_FROZEN_ENABLED 0)
set(LIEF_EXTERNAL_FROZEN 0)
set(LIEF_EXTERNAL_LEAF 0)
set(LIEF_EXTERNAL_UTF8CPP 0)
set(LIEF_EXTERNAL_MBEDTLS 0)
set(LIEF_EXTERNAL_SPAN 0)
if(LIEF_ELF)
set(LIEF_ELF_SUPPORT 1)
endif()
if(LIEF_PE)
set(LIEF_PE_SUPPORT 1)
endif()
if(LIEF_MACHO)
set(LIEF_MACHO_SUPPORT 1)
endif()
if(LIEF_OAT)
set(LIEF_OAT_SUPPORT 1)
endif()
if(LIEF_DEX)
set(LIEF_DEX_SUPPORT 1)
endif()
if(LIEF_VDEX)
set(LIEF_VDEX_SUPPORT 1)
endif()
if(LIEF_ART)
set(LIEF_ART_SUPPORT 1)
endif()
if(LIEF_ENABLE_JSON)
set(LIEF_JSON_SUPPORT 1)
if(LIEF_OPT_NLOHMANN_JSON_EXTERNAL)
set(LIEF_NLOHMANN_JSON_EXTERNAL 1)
endif()
endif()
if(LIEF_LOGGING)
set(LIEF_LOGGING_SUPPORT 1)
if(LIEF_LOGGING_DEBUG)
set(LIEF_LOGGING_DEBUG_SUPPORT 1)
else()
set(LIEF_LOGGING_DEBUG_SUPPORT 0)
endif()
endif()
if(NOT LIEF_DISABLE_FROZEN)
set(LIEF_FROZEN_ENABLED 1)
if(LIEF_OPT_FROZEN_EXTERNAL)
set(LIEF_EXTERNAL_FROZEN 1)
endif()
endif()
if(LIEF_OPT_EXTERNAL_LEAF)
set(LIEF_EXTERNAL_LEAF 1)
endif()
if(LIEF_OPT_UTFCPP_EXTERNAL)
set(LIEF_EXTERNAL_UTF8CPP 1)
endif()
if(LIEF_OPT_MBEDTLS_EXTERNAL)
set(LIEF_EXTERNAL_MBEDTLS 1)
endif()
if(LIEF_OPT_EXTERNAL_SPAN)
set(LIEF_EXTERNAL_SPAN 1)
endif()
if(LIEF_PYTHON_API)
if(LIEF_OPT_PYBIND11_EXTERNAL)
set(LIEF_EXTERNAL_PYBIND11 1)
endif()
endif()
See liefproject on Dockerhub
See the Dockerlief repo.