4
0
mirror of https://github.com/QuasarApp/LIEF.git synced 2025-05-14 20:29:34 +00:00

Improve Python setup

This commit is contained in:
Romain Thomas 2019-03-31 10:15:08 +02:00
parent 57c30b8bd5
commit 0d03b4bdb8
19 changed files with 513 additions and 152 deletions

@ -91,52 +91,25 @@ install:
# Upgrade pip
- python.exe -m pip install --disable-pip-version-check --user --upgrade pip
- python.exe -m pip install --user wheel mako
- python.exe -m pip install --upgrade setuptools
build_script:
- cd %APPVEYOR_BUILD_FOLDER%
- >
cmake -A "%CMAKE_ARCH%"
-DLIEF_TESTS=on
-DLIEF_PYTHON_API=on
-DLIEF_COMPILER_JOBS=4
-DCMAKE_BUILD_TYPE=Release
-DLIEF_USE_CRT_RELEASE=MT
-DPYTHON_VERSION=%PYTHON_VERSION%
-DPYTHON_INCLUDE_DIR=%PYTHON_INCLUDE%
-DPYTHON_EXECUTABLE=%PYTHON_BINARY%
-DPYTHON_LIBRARY=%PYTHON_LIBRARY% .
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
- cmake --build . --config Release --target lief_samples -- /v:m /logger:%MSBuildLogger%
- cmake .
- cmake --build . --config Release --target ALL_BUILD -- /v:m /logger:%MSBuildLogger%
test_script:
- cmake --build . --config Release --target lief_samples -- /v:m /logger:%MSBuildLogger%
- cmake .
- cmake --build . --config Release --target check-lief -- /v:m /logger:%MSBuildLogger%
- python.exe .\setup.py --sdk --lief-test bdist_wheel && exit 0 # Ignore warnings...
after_build:
- cmake --build . --config Release --target package -- /v:m /logger:%MSBuildLogger%
- cd api\python
- python.exe .\setup.py bdist_egg && exit 0 # Ignore warnings...
- ps: if ($env:APPVEYOR_REPO_TAG -eq "true") { python.exe .\setup.py sdist --formats=zip } # Ignore warnings...
- ps: if ($env:APPVEYOR_REPO_TAG -eq "false") { python.exe .\setup.py sdist --dev --formats=zip } # Ignore warnings...
- cd ..\..
- bash ./.github/deploy.sh
artifacts:
- path: '*.zip'
- path: 'dist\*.whl'
name: python-wheel
- path: 'build\*.zip'
name: sdk
- path: 'api\python\dist\*.zip'
name: python-src
- path: 'api\python\dist\*.egg'
name: python-egg
deploy:
description: "LIEF version $(APPVEYOR_REPO_TAG_NAME)"
provider: GitHub

24
.github/deploy.sh vendored

@ -62,6 +62,7 @@ case $branch in
devel*) ;;
master*) ;;
deploy*) ;;
"enhancement/setup") ;;
*) exit 0;;
esac
@ -73,7 +74,7 @@ rev=$(git rev-parse --verify HEAD)
timestamp=$(git log -n1 --format='%at' $rev)
date=$(TZ=UTC0 date -d "@$timestamp" '+%Y%m%d-%H%M%S')
#branch="$branch-$date-${rev:0:6}"
branch="lief-$branch-latest"
branch="gh-pages"
if [[ -n $APPVEYOR_JOB_ID ]]; then
branch="$branch"
git_user="AppVeyor CI"
@ -117,19 +118,29 @@ if [[ $new_branch == 1 ]]; then
git reset --hard || true
fi
git reset --soft `git rev-list --all | tail -1`
#git reset --soft `git rev-list --all | tail -1`
git reset --soft ebacb6adf12a5866db66346ce591f634333bde24
git ls-files -v
mkdir -p lief && cd lief
/bin/cp -rf ${LIEF_SRCDIR}/dist/*.zip . || true
/bin/cp -rf ${LIEF_SRCDIR}/dist/*.egg . || true
/bin/cp -rf ${LIEF_SRCDIR}/dist/*.whl . || true
/bin/cp -rf $LIEF_BUILDDIR/api/python/dist/*.zip .
/bin/cp -rf $LIEF_BUILDDIR/api/python/dist/*.egg .
${PYTHON_BINARY} ${LIEF_SRCDIR}/.github/make_index.py --output=./index.html --base "packages/lief" .
git add .
cd .. && mkdir -p sdk && cd sdk
if [[ -n $APPVEYOR_JOB_ID ]]; then
/bin/cp -rf $LIEF_BUILDDIR/*.zip .
/bin/cp -rf ${LIEF_SRCDIR}/build/*.zip . || true
else
/bin/cp -rf $LIEF_BUILDDIR/*.tar.gz .
/bin/cp -rf ${LIEF_SRCDIR}/build/*.tar.gz . || true
fi
${PYTHON_BINARY} ${LIEF_SRCDIR}/.github/make_index.py --output=./index.html --base "packages/sdk" .
git add .
if git diff --cached --exit-code --quiet >/dev/null; then
@ -143,6 +154,7 @@ git commit --date="$now" -m "Automatic build - ${rev:0:7} - Python ${PYTHON_VERS
git ls-files -v
git log --pretty=fuller
cd ..
umask 077
[[ -d ~/.ssh ]] || mkdir ~/.ssh
fix_home_ssh_perms

42
.github/make_index.py vendored Normal file

@ -0,0 +1,42 @@
""" Build index from directory listing
From: https://stackoverflow.com/questions/39048654/how-to-enable-directory-indexing-on-github-pages
make_index.py </path/to/directory>
"""
INDEX_TEMPLATE = r"""
<html>
<title>Links for lief</title>
<body>
<h1>Links for lief</h1>
% for name in names:
<a href="${base_url}/${base}/${name}">${name}</a><br />
% endfor
</body>
</html>
"""
EXCLUDED = ['index.html', '.gitkeep']
BASE_URL = "https://lief-project.github.io"
import os
import argparse
# May need to do "pip install mako"
from mako.template import Template
def main():
parser = argparse.ArgumentParser()
parser.add_argument("directory")
parser.add_argument("--base")
parser.add_argument("--output")
args = parser.parse_args()
fnames = [fname for fname in sorted(os.listdir(args.directory))
if fname not in EXCLUDED]
html = Template(INDEX_TEMPLATE).render(names=fnames, base_url=BASE_URL, base=args.base)
with open(args.output, "w") as f:
f.write(html)
if __name__ == '__main__':
main()

@ -117,7 +117,7 @@ matrix:
# OSX 10.12 - xcode 8.3 - Python 3.7
- os: osx
osx_image: xcode8.3
osx_image: xcode10.1
compiler: clang
env: >
[
@ -168,7 +168,7 @@ before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "2.7" ]]; then pyenv install 2.7.12; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.5" ]]; then pyenv install 3.5.0; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.6" ]]; then pyenv install 3.6.0; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then pyenv install 3.7.0a1; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then pyenv install 3.7.0; fi
#- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then ls -alR $(pyenv root)/versions/3.7.0a1; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "2.7" ]]; then export PYTHON_INCLUDE_DIR=$(pyenv root)/versions/2.7.12/include/python2.7 ;fi
@ -183,9 +183,9 @@ before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.6" ]]; then export PYTHON_LIBRARY=$(pyenv root)/versions/3.6.0/lib/libpython3.dylib ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.6" ]]; then export PYTHON_BINARY=$(pyenv root)/versions/3.6.0/bin/python3.6 ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then export PYTHON_INCLUDE_DIR=$(pyenv root)/versions/3.7.0a1/include/python3.7m ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then export PYTHON_LIBRARY=$(pyenv root)/versions/3.7.0a1/lib/libpython3.7m.dylib ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then export PYTHON_BINARY=$(pyenv root)/versions/3.7.0a1/bin/python3.7 ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then export PYTHON_INCLUDE_DIR=$(pyenv root)/versions/3.7.0/include/python3.7m ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then export PYTHON_LIBRARY=$(pyenv root)/versions/3.7.0/lib/libpython3.7m.dylib ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$PYTHON_VERSION" == "3.7" ]]; then export PYTHON_BINARY=$(pyenv root)/versions/3.7.0/bin/python3.7 ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then $PYTHON_BINARY -m pip install --upgrade pip ;fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then $PYTHON_BINARY -m pip install --upgrade setuptools ;fi
@ -204,33 +204,20 @@ install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget --no-check-certificate https://bootstrap.pypa.io/get-pip.py ;fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo -H $PYTHON_BINARY ./get-pip.py ;fi
# Prepare build
- mkdir build
- cd build
script:
- >
cmake
-DCMAKE_C_COMPILER=$C_COMPILER
-DCMAKE_CXX_COMPILER=$CXX_COMPILER
-DPYTHON_VERSION=$PYTHON_VERSION
-DPYTHON_INCLUDE_DIR=$PYTHON_INCLUDE_DIR
-DPYTHON_LIBRARY=$PYTHON_LIBRARY
-DPYTHON_EXECUTABLE=$PYTHON_BINARY
-DLIEF_TESTS=on
-DLIEF_PYTHON_API=on
-DLIEF_EXAMPLES=on
..
- make -j3 lief_samples
- cmake ..
- make -j3 all
- make -j3 check-lief
- export CC=$C_COMPILER
- export CXX=$CXX_COMPILER
- sudo $PYTHON_BINARY -m pip install setuptools
- sudo $PYTHON_BINARY -m pip install wheel
- sudo $PYTHON_BINARY -m pip install --upgrade setuptools
- sudo $PYTHON_BINARY -m pip install --upgrade pip
- $PYTHON_BINARY ./setup.py --lief-test --sdk build -j8 bdist_wheel
after_success:
- make package
- sudo $PYTHON_BINARY -m pip install setuptools
- sudo $PYTHON_BINARY -m pip install requests
- sudo $PYTHON_BINARY -m pip install setuptools requests mako
- sudo $PYTHON_BINARY -m pip install wheel
- sudo $PYTHON_BINARY -m pip install --upgrade setuptools
- cd api/python
- $PYTHON_BINARY setup.py bdist_egg

23
MANIFEST.in Normal file

@ -0,0 +1,23 @@
include README.md setup.cfg CMakeLists.txt
# Examples
recursive-include examples *
# LIEF Sources
recursive-include src *
recursive-include include *
recursive-include third-party *
recursive-include cmake *
recursive-include scripts *
# Bindings
recursive-include api *
prune api/python/build
# Global exclude
recursive-exclude *.egg-info *.so
# Documentation
recursive-include doc *

@ -62,27 +62,27 @@ Main features:
## Downloads / Install
First:
First make sur to have an updated version of setuptools:
```bash
```console
pip install setuptools --upgrade
```
To install the latest **version**:
To install the latest **version** (release):
```python
```console
pip install lief
```
To install the latest **commit**:
To install nightlty build:
```python
pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
```console
pip install [--user] --index-url https://lief-project.github.io/packages lief
```
### Packages
<table>
<tr><td colspan="4"><img src="https://img.shields.io/badge/release-master-brightgreen.svg?style=default"></td></tr>
<tr><td colspan="4"><a href="https://lief-project.github.io/packages/sdk"><img src="https://img.shields.io/badge/release-master-brightgreen.svg?style=default"></a></td></tr>
<tr>
<th>Linux</th>
<th>Windows - x86</th>
@ -91,14 +91,14 @@ pip install https://github.com/lief-project/packages/raw/lief-master-latest/pyli
</tr>
<tr>
<td><a href="https://github.com/lief-project/packages/raw/lief-master-latest/LIEF-0.9.0-Linux.tar.gz">SDK</a></td>
<td><a href="https://github.com/lief-project/packages/raw/lief-master-latest/LIEF-0.9.0-win32.zip">SDK</a></td>
<td><a href="https://github.com/lief-project/packages/raw/lief-master-latest/LIEF-0.9.0-win64.zip">SDK</a></td>
<td><a href="https://github.com/lief-project/packages/raw/lief-master-latest/LIEF-0.9.0-Darwin.tar.gz">SDK</a></td>
<td><a href="https://lief-project.github.io/packages/sdk/LIEF-0.9.0-Linux.tar.gz">SDK</a></td>
<td><a href="https://lief-project.github.io/packages/sdk/LIEF-0.9.0-win32.zip">SDK</a></td>
<td><a href="https://lief-project.github.io/packages/sdk/LIEF-0.9.0-win64.zip">SDK</a></td>
<td><a href="https://lief-project.github.io/packages/sdk/LIEF-0.9.0-Darwin.tar.gz">SDK</a></td>
</tr>
<tr>
<td colspan="4"><p align="center"><a href="https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip">Python</a></p></td>
<td colspan="4"><p align="center"><a href="https://lief-project.github.io/packages/lief">Python</a></p></td>
</tr>
</table>

@ -25,8 +25,8 @@ message(STATUS "Python lib: ${PYTHON_LIBRARY}")
message(STATUS "Python include: ${PYTHON_INCLUDE_DIR}")
message(STATUS "Python interpreter: ${PYTHON_EXECUTABLE}")
set(PYBIND11_VERSION 2.2.1)
set(PYBIND11_SHA256 SHA256=53c373d7d0b0711fea96beba666a9985269dc9e43e6088ea73faaa89b07b972e)
set(PYBIND11_VERSION 2.2.4)
set(PYBIND11_SHA256 SHA256=c62073cd8d4f9209ad64092279e757f5fd83327a5b17a72c04fd0fea27d0d593)
set(PYBIND11_URL "${THIRD_PARTY_DIRECTORY}/pybind11-${PYBIND11_VERSION}.zip" CACHE STRING "URL to the Pybind11 repo")
ExternalProject_Add(lief_pybind11
URL ${PYBIND11_URL}
@ -139,7 +139,7 @@ endif()
ADD_FLAG_IF_SUPPORTED("-Wno-macro-redefined" NO_MACRO_REDEFINED)
ADD_FLAG_IF_SUPPORTED("-Wno-deprecated-declarations" NO_DEPRECATED_DECLARATIONS)
set_target_properties(pyLIEF PROPERTIES PREFIX "" OUTPUT_NAME "_pylief")
set_target_properties(pyLIEF PROPERTIES PREFIX "" OUTPUT_NAME "lief")
add_dependencies(pyLIEF lief_pybind11)
if(APPLE)
@ -186,19 +186,19 @@ if (CMAKE_BUILD_TYPE MATCHES Release AND UNIX)
)
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in" "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in" "${CMAKE_CURRENT_BINARY_DIR}/lief/__init__.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/README" "${CMAKE_CURRENT_BINARY_DIR}/README")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.in" "${CMAKE_CURRENT_BINARY_DIR}/MANIFEST.in")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/setup.cfg" "${CMAKE_CURRENT_BINARY_DIR}/setup.cfg")
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in" "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in" "${CMAKE_CURRENT_BINARY_DIR}/lief/__init__.py")
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/README" "${CMAKE_CURRENT_BINARY_DIR}/README")
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.in" "${CMAKE_CURRENT_BINARY_DIR}/MANIFEST.in")
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/setup.cfg" "${CMAKE_CURRENT_BINARY_DIR}/setup.cfg")
MESSAGE(STATUS "OS: ${CMAKE_HOST_SYSTEM}")
find_program(ENV_BINARY "env")
if (UNIX AND ENV_BINARY AND LIEF_INSTALL_PYTHON)
install(CODE "execute_process(COMMAND ${ENV_BINARY} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py install)"
COMPONENT python)
endif()
#find_program(ENV_BINARY "env")
#
#if (UNIX AND ENV_BINARY AND LIEF_INSTALL_PYTHON)
# install(CODE "execute_process(COMMAND ${ENV_BINARY} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py install)"
# COMPONENT python)
#endif()

@ -50,11 +50,14 @@
#include "platforms/android/pyAndroid.hpp"
py::module LIEF_module("_pylief", "Python API for LIEF");
py::module LIEF_module("lief", "Python API for LIEF");
PYBIND11_MODULE(_pylief, LIEF_module) {
PYBIND11_MODULE(lief, LIEF_module) {
LIEF_module.attr("__version__") = py::str(LIEF_VERSION);
LIEF_module.attr("__tag__") = py::str(LIEF_TAG);
LIEF_module.attr("__is_tagged__") = py::bool_(LIEF_TAGGED);
LIEF_module.attr("__version__") = py::str(LIEF_VERSION);
init_LIEF_Object_class(LIEF_module);
init_LIEF_iterators(LIEF_module);

@ -1,5 +1,5 @@
# - Find python libraries
# This module finds the libraries corresponding to the Python interpeter
# This module finds the libraries corresponding to the Python interpreter
# FindPythonInterp provides.
# This code sets the following variables:
#
@ -100,11 +100,14 @@ if(NOT _PYTHON_SUCCESS MATCHES 0)
endif()
# Convert the process output into a list
if(WIN32)
string(REGEX REPLACE "\\\\" "/" _PYTHON_VALUES ${_PYTHON_VALUES})
endif()
string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
list(GET _PYTHON_VALUES 1 PYTHON_PREFIX)
list(GET _PYTHON_VALUES 2 _PYTHON_INCLUDE_DIR)
list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG)
@ -135,18 +138,18 @@ list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)
# Make sure all directory separators are '/'
string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
string(REGEX REPLACE "\\\\" "/" _PYTHON_INCLUDE_DIR ${_PYTHON_INCLUDE_DIR})
string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR})
string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES})
if(CMAKE_HOST_WIN32)
set(_PYTHON_LIBRARY
set(PYTHON_LIBRARY
"${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
# when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the
# original python installation. They may be found relative to PYTHON_INCLUDE_DIR.
if(NOT EXISTS "${_PYTHON_LIBRARY}")
get_filename_component(_PYTHON_ROOT ${_PYTHON_INCLUDE_DIR} DIRECTORY)
set(_PYTHON_LIBRARY
if(NOT EXISTS "${PYTHON_LIBRARY}")
get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)
set(PYTHON_LIBRARY
"${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
endif()
@ -164,14 +167,14 @@ else()
#message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}")
# Probably this needs to be more involved. It would be nice if the config
# information the python interpreter itself gave us were more complete.
find_library(_PYTHON_LIBRARY
find_library(PYTHON_LIBRARY
NAMES "python${PYTHON_LIBRARY_SUFFIX}"
PATHS ${_PYTHON_LIBS_SEARCH}
NO_DEFAULT_PATH)
# If all else fails, just set the name/version and let the linker figure out the path.
if(NOT _PYTHON_LIBRARY)
set(_PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})
if(NOT PYTHON_LIBRARY)
set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})
endif()
endif()
@ -184,14 +187,12 @@ MARK_AS_ADVANCED(
# cache entries because they are meant to specify the location of a single
# library. We now set the variables listed by the documentation for this
# module.
SET(PYTHON_INCLUDE_DIRS "${_PYTHON_INCLUDE_DIR}" CACHE PATH "")
SET(PYTHON_INCLUDE_DIR "${_PYTHON_INCLUDE_DIR}" CACHE PATH "")
SET(PYTHON_LIBRARIES "${_PYTHON_LIBRARY}" CACHE PATH "")
SET(PYTHON_LIBRARY "${_PYTHON_LIBRARY}" CACHE PATH "")
SET(PYTHON_DEBUG_LIBRARIES "${_PYTHON_DEBUG_LIBRARY}" CACHE PATH "")
SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
find_package_message(PYTHON
"Found PythonLibs: ${_PYTHON_LIBRARY}"
"Found PythonLibs: ${PYTHON_LIBRARY}"
"${PYTHON_EXECUTABLE}${PYTHON_VERSION}")
set(PYTHONLIBS_FOUND TRUE)

@ -25,11 +25,10 @@ Libraries only (SDK)
$ cd build
$ cmake -DLIEF_PYTHON_API=off -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --target LIB_LIEF_STATIC --config Release
$ cmake --build . --target LIB_LIEF_SHARED --config Release # for the shared one
.. warning::
On Windows with can choose the CRT to use by setting the ``LIEF_USE_CRT_<RELEASE;DEBUG;..>`` variable:
On Windows on can choose the CRT to use by setting the ``LIEF_USE_CRT_<RELEASE;DEBUG;..>`` variable:
.. code-block:: console
@ -46,7 +45,6 @@ Library and Python bindings
$ cd build
$ cmake -DLIEF_PYTHON_API=on -DPYTHON_VERSION=3.6 -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --target LIB_LIEF_STATIC --config Release
$ cmake --build . --target LIB_LIEF_SHARED --config Release # for the shared one
$ cmake --build . --target pyLIEF --config Release
.. warning::
@ -70,6 +68,11 @@ If you want to enable tests, add ``-DLIEF_TESTS=on`` at CMake configuration step
The Doxygen documentation will be located at ``build/doc/doxygen/html`` and the sphinx documentation at ``build/doc/sphinx-doc``
CMake Options
-------------
.. literalinclude:: ../../../cmake/LIEFOptions.cmake
Docker
------

@ -17,7 +17,7 @@ import sys
import os
import re
import six
import lief
from datetime import datetime
from docutils import nodes
#from docutils.parsers.rst import directives
@ -62,7 +62,7 @@ master_doc = 'index'
# General information about the project.
project = u'LIEF'
copyright = u'2017, Quarkslab'
copyright = u'2018, Quarkslab'
author = 'Romain Thomas'
# The version info for the project you're documenting, acts as replacement for
@ -70,14 +70,10 @@ author = 'Romain Thomas'
# built documents.
#
# The short X.Y version.
version = None
version = lief.__tag__ if lief.__is_tagged__ else lief.__version__
version = '@LIEF_VERSION_MAJOR@.@LIEF_VERSION_MINOR@.@LIEF_VERSION_PATCH@'
if not @LIEF_IS_TAGGED@:
version += "-@LIEF_COMMIT_HASH@"
# The full version, including alpha/beta/rc tags.
release = version
# The full version, including alpha/beta/rc tags
release = lief.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

@ -44,14 +44,14 @@ C++
#include <LIEF/LIEF.hpp>
int main(int argc, const char** argv) {
LIEF::ELF::Binary* elf = LIEF::ELF::Parser::parse("/usr/bin/ls");
LIEF::PE::Binary* pe = LIEF::PE::Parser::parse("C:\\Windows\\explorer.exe");
LIEF::MachO::Binary* macho = LIEF::MachO::Parser::parse("/usr/bin/ls");
std::unique_ptr<LIEF::ELF::Binary> elf = LIEF::ELF::Parser::parse("/usr/bin/ls");
std::unique_ptr<LIEF::PE::Binary> pe = LIEF::PE::Parser::parse("C:\\Windows\\explorer.exe");
std::unique_ptr<LIEF::MachO::Binary> macho = LIEF::MachO::Parser::parse("/usr/bin/ls");
LIEF::OAT::Binary* oat = LIEF::OAT::Parser::parse("android.odex");
LIEF::DEX::File* dex = LIEF::DEX::Parser::parse("classes.dex");
LIEF::OAT::File* vdex = LIEF::VDEX::Parser::parse("classes.vdex");
LIEF::OAT::File* art = LIEF::ART::Parser::parse("boot.art");
std::unique_ptr<LIEF::OAT::Binary> oat = LIEF::OAT::Parser::parse("android.odex");
std::unique_ptr<LIEF::DEX::File> dex = LIEF::DEX::Parser::parse("classes.dex");
std::unique_ptr<LIEF::OAT::File> vdex = LIEF::VDEX::Parser::parse("classes.vdex");
std::unique_ptr<LIEF::OAT::File> art = LIEF::ART::Parser::parse("boot.art");
std::cout << *elf << std::endl;
std::cout << *pe << std::endl;
@ -61,14 +61,6 @@ C++
std::cout << *dex << std::endl;
std::cout << *vdex << std::endl;
std::cout << *art << std::endl;
delete elf;
delete pe;
delete macho;
delete oat;
delete dex;
delete vdex;
delete art;
}

@ -4,29 +4,46 @@ Installation and Integration
SDK
---
For each platform there is a SDK which contains
For each platform there is an SDK that contains:
* Static library
* Shared library
* Headers
* Examples
To install the static or shared library one have to copy them in the right folder. For instance, on Linux it would be in ``/usr/lib`` and ``/usr/include``.
Nightly build can be downloaded here: https://lief-project.github.io/packages/sdk while releases are available here: https://github.com/lief-project/LIEF/releases.
Python
------
Since 0.10.0
************
From 0.8.0
**********
To install the **dev** package (master release):
To install nightly build (master):
.. code-block:: console
$ pip install pylief-VERSION.dev.zip
$ pip install [--user] --index-url https://lief-project.github.io/packages lief
Dev packages can be found here: `lief-master-latest <https://github.com/lief-project/packages/tree/lief-master-latest>`_
Python packages can be found here: https://lief-project.github.io/packages/lief
To install **release** package
.. code-block:: console
$ pip install lief
Release packages can be found here: `Releases <https://github.com/lief-project/LIEF/releases>`_
Using ``setup.py``, one can build and install lief as follows:
.. code-block:: console
$ python ./setup.py [--user] install
From 0.8.0 to 0.9.0
*******************
To install **release** package
@ -39,7 +56,6 @@ To install **release** package
Release packages can be found here: `Releases <https://github.com/lief-project/LIEF/releases>`_
Before 0.8.0
************

@ -23,6 +23,8 @@
#endif
#define LIEF_VERSION "@LIEF_VERSION_MAJOR@.@LIEF_VERSION_MINOR@.@LIEF_VERSION_PATCH@-@LIEF_COMMIT_HASH@"
#define LIEF_TAGGED @LIEF_IS_TAGGED@
#define LIEF_TAG "@LIEF_GIT_TAG@"
#define HUMAN_VERSION " v" LIEF_VERSION
#define HUMAN_NAME NAME HUMAN_VERSION

30
setup.cfg Normal file

@ -0,0 +1,30 @@
[metadata]
name = lief
author = Romain Thomas
author_email = rthomas@quarkslab.com
classifiers =
Development Status :: 4 - Beta
Programming Language :: Python
Programming Language :: C++
Topic :: Software Development :: Libraries
[options]
zip_safe = False
packages = find:
include_package_data = True
python_requires = >=2.7
install_requires =
sphinx
colored
sphinx-paramlinks
sphinx_rtd_theme
[build_sphinx]
project = LIEF
source-dir = doc/sphinx
config-dir = doc/sphinx
build-dir = doc/sphinx/_build
fresh-env = True
[build_ext]
inplace=1

281
setup.py Normal file

@ -0,0 +1,281 @@
import os
import re
import sys
import platform
import subprocess
import glob
import setuptools
import pathlib
from pkg_resources import Distribution, get_distribution
from setuptools import setup, Extension
from setuptools import Extension
from setuptools.command.build_ext import build_ext, copy_file
from distutils import log
from distutils.version import LooseVersion
MIN_SETUPTOOLS_VERSION = "31.0.0"
assert (LooseVersion(setuptools.__version__) >= LooseVersion(MIN_SETUPTOOLS_VERSION)), "LIEF requires a setuptools version '{}' or higher (pip install setuptools --upgrade)".format(MIN_SETUPTOOLS_VERSION)
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
PACKAGE_NAME = "lief"
class LiefDistribution(setuptools.Distribution):
global_options = setuptools.Distribution.global_options + [
('lief-test', None, 'Build and make tests'),
('ninja', None, 'Use Ninja as build system'),
('sdk', None, 'Build SDK package'),
]
def __init__(self, attrs=None):
self.lief_test = False
self.ninja = False
self.sdk = False
super().__init__(attrs)
class Module(Extension):
def __init__(self, name, sourcedir='', *args, **kwargs):
Extension.__init__(self, name, sources=[])
self.sourcedir = os.path.abspath(os.path.join(CURRENT_DIR))
class BuildLibrary(build_ext):
def run(self):
try:
out = subprocess.check_output(['cmake', '--version'])
except OSError:
raise RuntimeError("CMake must be installed to build the following extensions: " +
", ".join(e.name for e in self.extensions))
#if platform.system() == "Windows":
# cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1))
# if cmake_version < '3.1.0':
# raise RuntimeError("CMake >= 3.1.0 is required on Windows")
for ext in self.extensions:
self.build_extension(ext)
self.copy_extensions_to_source()
@staticmethod
def has_ninja():
try:
subprocess.check_call(['ninja', '--version'])
return True
except Exception as e:
return False
@staticmethod
def sdk_suffix():
if platform.system() == "Windows":
return "zip"
return "tar.gz"
def build_extension(self, ext):
if self.distribution.lief_test:
log.info("LIEF tests enabled!")
fullname = self.get_ext_fullname(ext.name)
filename = self.get_ext_filename(fullname)
jobs = self.parallel if self.parallel else 1
source_dir = ext.sourcedir
build_temp = self.build_temp
extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
cmake_library_output_directory = os.path.abspath(os.path.dirname(build_temp))
cfg = 'Debug' if self.debug else 'Release'
is64 = sys.maxsize > 2**32
cmake_args = [
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}'.format(cmake_library_output_directory),
'-DPYTHON_EXECUTABLE={}'.format(sys.executable),
'-DLIEF_PYTHON_API=on',
]
if self.distribution.lief_test:
cmake_args += ["-DLIEF_TESTS=on"]
build_args = ['--config', cfg]
if platform.system() == "Windows":
cmake_args += [
'-DCMAKE_BUILD_TYPE={}'.format(cfg),
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), cmake_library_output_directory),
'-DLIEF_USE_CRT_RELEASE=MT',
]
cmake_args += ['-A', 'x64'] if is64 else []
# Specific to appveyor
#if os.getenv("APPVEYOR", False):
# build_args += ['--', '/v:m']
# logger = os.getenv("MSBuildLogger", None)
# if logger:
# build_args += ['/logger:{}'.format(logger)]
#else:
build_args += ['--', '/m']
else:
cmake_args += ['-DCMAKE_BUILD_TYPE={}'.format(cfg)]
env = os.environ.copy()
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
build_with_ninja = False
if self.has_ninja() and self.distribution.ninja:
cmake_args += ["-G", "Ninja"]
build_with_ninja = True
# 1. Configure
configure_cmd = ['cmake', ext.sourcedir] + cmake_args
log.info(" ".join(configure_cmd))
subprocess.check_call(configure_cmd, cwd=self.build_temp, env=env)
# 2. Build
targets = {
'python_bindings': 'pyLIEF',
}
if self.distribution.sdk:
targets['sdk'] = "package"
if platform.system() == "Windows":
build_cmd = ['cmake', '--build', '.', '--target', "lief_samples"] + build_args
#log.info(" ".join(build_cmd))
if self.distribution.lief_test:
subprocess.check_call(['cmake', '--build', '.', '--target', "lief_samples"] + build_args, cwd=self.build_temp, env=env)
subprocess.check_call(configure_cmd, cwd=self.build_temp, env=env)
subprocess.check_call(['cmake', '--build', '.', '--target', "ALL_BUILD"] + build_args, cwd=self.build_temp, env=env)
subprocess.check_call(['cmake', '--build', '.', '--target', "check-lief"] + build_args, cwd=self.build_temp, env=env)
else:
subprocess.check_call(['cmake', '--build', '.', '--target', targets['python_bindings']] + build_args, cwd=self.build_temp, env=env)
if 'sdk' in targets:
subprocess.check_call(['cmake', '--build', '.', '--target', targets['sdk']] + build_args, cwd=self.build_temp, env=env)
else:
if build_with_ninja:
if self.distribution.lief_test:
subprocess.check_call(['ninja', "lief_samples"], cwd=self.build_temp)
subprocess.check_call(configure_cmd, cwd=self.build_temp)
subprocess.check_call(['ninja'], cwd=self.build_temp)
subprocess.check_call(['ninja', "check-lief"], cwd=self.build_temp)
else:
subprocess.check_call(['ninja', targets['python_bindings']], cwd=self.build_temp)
if 'sdk' in targets:
subprocess.check_call(['ninja', targets['sdk']], cwd=self.build_temp)
else:
log.info("Using {} jobs".format(jobs))
if self.distribution.lief_test:
subprocess.check_call(['make', '-j', str(jobs), "lief_samples"], cwd=self.build_temp)
subprocess.check_call(configure_cmd, cwd=self.build_temp)
subprocess.check_call(['make', '-j', str(jobs), "all"], cwd=self.build_temp)
subprocess.check_call(['make', '-j', str(jobs), "check-lief"], cwd=self.build_temp)
else:
subprocess.check_call(['make', '-j', str(jobs), targets['python_bindings']], cwd=self.build_temp)
if 'sdk' in targets:
subprocess.check_call(['make', '-j', str(jobs), targets['sdk']], cwd=self.build_temp)
pylief_dst = os.path.join(self.build_lib, self.get_ext_filename(self.get_ext_fullname(ext.name)))
libsuffix = pylief_dst.split(".")[-1]
pylief_path = os.path.join(cmake_library_output_directory, "{}.{}".format(PACKAGE_NAME, libsuffix))
if platform.system() == "Windows":
pylief_path = os.path.join(cmake_library_output_directory, "Release", "api", "python", "Release", "{}.{}".format(PACKAGE_NAME, libsuffix))
if not os.path.exists(self.build_lib):
os.makedirs(self.build_lib)
log.info("Copying {} into {}".format(pylief_path, pylief_dst))
copy_file(
pylief_path, pylief_dst, verbose=self.verbose,
dry_run=self.dry_run)
# SDK
# ===
if self.distribution.sdk:
sdk_path = list(pathlib.Path(self.build_temp).rglob("LIEF-*.{}".format(self.sdk_suffix())))
if len(sdk_path) == 0:
log.error("Unable to find SDK archive")
sys.exit(1)
sdk_path = str(sdk_path.pop())
sdk_output = str(pathlib.Path(CURRENT_DIR) / "build")
copy_file(
sdk_path, sdk_output, verbose=self.verbose,
dry_run=self.dry_run)
# From setuptools-git-version
command = 'git describe --tags --long --dirty'
is_tagged_cmd = 'git tag --list --points-at=HEAD'
fmt = '{tag}.dev0'
fmt_tagged = '{tag}'
def format_version(version, fmt=fmt):
parts = version.split('-')
assert len(parts) in (3, 4)
dirty = len(parts) == 4
tag, count, sha = parts[:3]
if count == '0' and not dirty:
return tag
return fmt.format(tag=tag, gitsha=sha.lstrip('g'))
def get_git_version(is_tagged):
git_version = subprocess.check_output(command.split()).decode('utf-8').strip()
if is_tagged:
return format_version(version=git_version, fmt=fmt_tagged)
return format_version(version=git_version, fmt=fmt)
def check_if_tagged():
output = subprocess.check_output(is_tagged_cmd.split()).decode('utf-8').strip()
return output != ""
def get_pkg_info_version(pkg_info_file):
dist_info = Distribution.from_filename(os.path.join(CURRENT_DIR, "{}.egg-info".format(PACKAGE_NAME)))
pkg = get_distribution('lief')
return pkg.version
def get_version():
version = "0.0.0"
pkg_info = os.path.join(CURRENT_DIR, "{}.egg-info".format(PACKAGE_NAME), "PKG-INFO")
git_dir = os.path.join(CURRENT_DIR, ".git")
if os.path.isdir(git_dir):
is_tagged = False
try:
is_tagged = check_if_tagged()
except:
is_tagged = False
try:
return get_git_version(is_tagged)
except:
pass
if os.path.isfile(pkg_info):
return get_pkg_info_version(pkg_info)
version = get_version()
cmdclass = {
'build_ext': BuildLibrary,
}
setup(
distclass=LiefDistribution,
ext_modules=[Module(PACKAGE_NAME)],
cmdclass=cmdclass,
version=version
)

@ -171,7 +171,7 @@ if(UNIX)
add_test(${name}
"bash"
"-c"
"PYTHONPATH=\"${PROJECT_BINARY_DIR}/api/python\" ${command} ${ARGN}")
"PYTHONPATH=\"${PROJECT_BINARY_DIR}/api/python:${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\" ${command} ${ARGN}")
endif()
if(WIN32)

@ -1,5 +1,5 @@
@echo on
set PYTHONPATH=%PYTHONPATH%;@PROJECT_BINARY_DIR@/api/python
set PYTHONPATH=%PYTHONPATH%;@PROJECT_BINARY_DIR@/api/python;@CMAKE_LIBRARY_OUTPUT_DIRECTORY@;@CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE@;
%1 %~2