Skip to content

Commit

Permalink
Change the build system to use standard setup.py
Browse files Browse the repository at this point in the history
This is way easier to do with scikit-build!
  • Loading branch information
Guillaume Fraux authored and Luthaf committed Dec 10, 2017
1 parent 8701b01 commit bd6f2af
Show file tree
Hide file tree
Showing 32 changed files with 143 additions and 423 deletions.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
build
_skbuild/
dist/
chemfiles.egg-info/
.tox/
MANIFEST
chemfiles/lib/
chemfiles/include/
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "C++ library"]
path = chemfiles
path = lib
url = https://github.com/chemfiles/chemfiles
95 changes: 6 additions & 89 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
cmake_minimum_required(VERSION 2.8.11)
project(chemfiles.py)
cmake_minimum_required(VERSION 2.8.12)

set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
cmake_policy(VERSION 2.8.11)

option(CHFL_PY_CODE_COVERAGE "Enable python code coverage" OFF)
option(CHFL_PY_BUILD_DOCUMENTATION "Build the python documentation" OFF)
# set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
option(CHFL_PY_INTERNAL_CHEMFILES "Use the internal version of chemfiles" OFF)

if(NOT ${CHFL_PY_INTERNAL_CHEMFILES})
Expand All @@ -25,94 +20,16 @@ if(${chemfiles_FOUND})
endif()
else()
# Use the git submodule
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/chemfiles/CMakeLists.txt")
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/CMakeLists.txt")
message(FATAL_ERROR
"The git submodule for chemfiles is not initalized.\n"
"Please run `git submodule update --init."
)
endif()

message(STATUS "Using internal chemfiles from ${CMAKE_CURRENT_SOURCE_DIR}/chemfiles")
message(STATUS "Using internal chemfiles from ${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries instead of static ones" FORCE)
add_subdirectory(chemfiles)
file(READ chemfiles/VERSION CHEMFILES_VERSION)
add_subdirectory(lib)
file(READ lib/VERSION CHEMFILES_VERSION)
string(STRIP ${CHEMFILES_VERSION} CHEMFILES_VERSION)
endif()

configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in"
"${CMAKE_CURRENT_BINARY_DIR}/setup.py"
)

find_package(PythonInterp REQUIRED)
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")

file(GLOB_RECURSE PYTHON_SRC src/chemfiles/**.py)
set(SETUP_PY_BUILD_OUTPUT "")
set(COPY_SRC_OUTPUT "")
foreach(_file_ ${PYTHON_SRC})
file(RELATIVE_PATH _path_ ${CMAKE_CURRENT_SOURCE_DIR} ${_file_})
list(APPEND COPY_SRC_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_path_})

file(RELATIVE_PATH _path_ ${CMAKE_CURRENT_SOURCE_DIR}/src/chemfiles ${_file_})
list(APPEND SETUP_PY_BUILD_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/build/lib/${_path_})
endforeach()

add_custom_command(
OUTPUT ${COPY_SRC_OUTPUT}
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/src/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/ ${CMAKE_CURRENT_BINARY_DIR}/src/
DEPENDS ${PYTHON_SRC}
COMMENT "Copying python sources"
)

# We configure the same file twice: the one in `build/lib` will be the one
# installed, and the one in `src/chemfiles` will be used for testing.
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/chemfiles/location.py"
COMMAND ${CMAKE_COMMAND}
-DLOCATION_PY_PATH=${CMAKE_CURRENT_BINARY_DIR}/src/
-DCHEMFILES_LOCATION=$<TARGET_FILE:chemfiles>
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate_location.cmake
COMMENT "Generating test location.py"
)

add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/lib/chemfiles/location.py"
COMMAND ${CMAKE_COMMAND}
-DLOCATION_PY_PATH=${CMAKE_CURRENT_BINARY_DIR}/build/lib
-DCHEMFILES_LOCATION=${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/$<TARGET_FILE_NAME:chemfiles>
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate_location.cmake
COMMENT "Generating install location.py"
)

add_custom_target(location.py ALL
DEPENDS ${COPY_SRC_OUTPUT}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/src/chemfiles/location.py
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/build/lib/chemfiles/location.py
)

add_custom_command(
OUTPUT ${SETUP_PY_BUILD_OUTPUT}
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build
DEPENDS location.py
COMMENT "Running python setup.py build"
)

set(ADDITIONAL_CLEANUP "${CMAKE_CURRENT_BINARY_DIR}/build/")
if(NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(ADDITIONAL_CLEANUP "${ADDITIONAL_CLEANUP};${CMAKE_CURRENT_BINARY_DIR}/src/")
endif()
set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ADDITIONAL_CLEANUP})

add_custom_target(chemfiles.py ALL DEPENDS ${SETUP_PY_BUILD_OUTPUT})
add_dependencies(chemfiles.py chemfiles)

install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install --prefix=${CMAKE_INSTALL_PREFIX})")

enable_testing()
add_subdirectory(tests)

if(${CHFL_PY_BUILD_DOCUMENTATION})
add_subdirectory(doc)
endif()
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
recursive-include chemfiles *
recursive-include lib *
include requirements.txt
24 changes: 7 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,21 @@ conda install -c conda-forge chemfiles
### Source compilation

You can install this python module from sources if you have all the
[dependencies][installation] of the C++ chemfiles library installed on your
computer.
[dependencies] of the C++ chemfiles library installed on your computer.

```bash
# To get the latest developement version:
git clone https://github.com/chemfiles/chemfiles.py
cd chemfiles.py
git submodule update --init
mkdir build
cd build
cmake .. <options> # see below for configuration options.
make
# Optionally
make test
make install
# Install developement dependencies
pip install -r dev-requirements.txt
pip install .
# Optionally run the test suite
tox
```

You can use the same [configuration options][installation] as the C++ chemfiles
library. Additionally, you may also want to specify which python interpreter and
installation to use with `-DPYTHON_EXECUTABLE=/full/path/to/python`, and where
to install the code with `-DCMAKE_INSTALL_PREFIX=<PREFIX>`. The C++ library will
be installed to `PREFIX/lib/`; and the python code will be installed in
`PREFIX/lib/python<x.y>/site-packages/`.

[installation]: http://chemfiles.readthedocs.org/en/latest/installation.html
[dependencies]: http://chemfiles.readthedocs.org/en/latest/installation.html

## Usage example

Expand Down
8 changes: 1 addition & 7 deletions src/chemfiles/__init__.py → chemfiles/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,4 @@
from .selection import Selection
from .property import Property

# Setup work
from .utils import _set_default_warning_callback
from .clib import _get_c_library
_set_default_warning_callback()

__version__ = _get_c_library().chfl_version().decode("utf8")
assert(__version__.startswith("0.8"))
__version__ = "0.8.0"
File renamed without changes.
File renamed without changes.
45 changes: 25 additions & 20 deletions src/chemfiles/clib.py → chemfiles/clib.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
# -* coding: utf-8 -*
import os
import sys
import struct
from ctypes import cdll, c_double, POINTER
from ctypes import sizeof, c_voidp

from .location import CHEMFILES_LOCATION, __file__ as location_file_path


class FindChemfilesLibrary(object):
def __init__(self):
self._cache = None

def __call__(self):
if self._cache is None:
check_dll(CHEMFILES_LOCATION)
try:
self._cache = cdll.LoadLibrary(CHEMFILES_LOCATION)
except OSError:
if location_file_path.endswith(".pyc"):
path = location_file_path[:-1]
else:
path = location_file_path
raise ImportError(
"Could not find chemfiles c++ library. " +
"Please check the path defined in " + path
)
path = _lib_path()
self._cache = cdll.LoadLibrary(path)

from .ffi import set_interface
from .ffi import CHFL_FRAME, CHFL_ATOM, chfl_vector3d
Expand All @@ -36,15 +23,33 @@ def __call__(self):
POINTER(CHFL_FRAME), POINTER(CHFL_ATOM),
chfl_vector3d, POINTER(c_double)
]

from .utils import _set_default_warning_callback
_set_default_warning_callback()
return self._cache


def check_dll(path):
if not sys.platform.startswith("win"):
return
if not os.path.isfile(path):
return
def _lib_path():
root = os.path.dirname(__file__)
if sys.platform.startswith("darwin"):
return os.path.join(root, "lib", "libchemfiles.dylib")
elif sys.platform.startswith("linux"):
return os.path.join(root, "lib", "libchemfiles.so")
elif sys.platform.startswith("win"):
candidates = [
os.path.join(root, "bin", "libchemfiles.dll"), # MinGW
os.path.join(root, "bin", "chemfiles.dll"), # MSVC
]
for path in candidates:
if os.path.isfile(path):
_check_dll(path)
return path
raise ImportError("Could not find chemfiles DLL")
else:
raise ImportError("Unknown platform. Please edit this file")


def _check_dll(path):
import struct

IMAGE_FILE_MACHINE_I386 = 332
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
140 changes: 0 additions & 140 deletions cmake/FindSphinx.cmake

This file was deleted.

Loading

0 comments on commit bd6f2af

Please sign in to comment.