From 5981a7402102cc268f5bceb54fda46a34542d1d5 Mon Sep 17 00:00:00 2001 From: jay <jlaura@usgs.gov> Date: Fri, 17 Aug 2018 07:44:16 -0700 Subject: [PATCH] Conda build and hopefully deploy via travis. --- .travis.yml | 12 ++-- python/CMakeLists.txt | 45 +++++++------- python/FindPythonAnaconda.cmake | 102 ++++++++++++++++++++++++++++++++ python/__init__.py | 1 + python/setup.py.in | 28 +-------- recipe/build.sh | 7 ++- recipe/meta.yaml | 18 +++--- 7 files changed, 153 insertions(+), 60 deletions(-) create mode 100644 python/FindPythonAnaconda.cmake create mode 100644 python/__init__.py diff --git a/.travis.yml b/.travis.yml index cf7700c..cfe7f45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,13 @@ os: fi - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - - conda install -y -c usgs-astrogeology libcsm - - conda install -y -c conda-forge cmake pytest + # Add the channels that conda build is going to use + - conda config --add channels usgs-astrogeology + - conda config --add channels conda-forge + # Setup to do the build + - conda install -y -q conda-build anaconda-client + - conda config --set anaconda_upload yes script: - - .run_build.sh - - pytest tests + # Build and upload on success + - conda build --token $CONDA_UPLOAD_TOKEN recipe -q diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 9b0fe30..50ac80a 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,44 +1,47 @@ # Include python -find_package(PythonLibs REQUIRED) -include_directories(${PYTHON_INCLUDE_PATH}) - +include(FindPythonAnaconda.cmake) +include_directories(${PYTHON_INCLUDE_DIR}) set(CMAKE_SWIG_FLAGS "") +set(CMAKE_SWIG_OUTDIR csmapi) set_source_files_properties(../csmapi.i PROPERTIES CPLUSPLUS ON) +#Find dependencies find_path(CSM_INCLUDE_DIR NAMES csm.h PATH_SUFFIXES csm - PATHS $ENV{CONDA_PREFIX}/include) -find_library(CSM_LIBRARY NAMES csmapi - PATHS $ENV{CONDA_PREFIX}/lib) + PATHS ${PYTHON_INCLUDE_DIR}/../) +find_library(CSM_LIBRARY NAMES csmapi) +message("-- Found CSM Include: ${CSM_INCLUDE_DIR}") +message("-- Found CSM Lib: ${CSM_LIBRARY}") include_directories(${CSM_INCLUDE_DIR}) -# Add swig module +# Add and link swig_add_library(csmapi LANGUAGE python SOURCES ../csmapi.i) +set_target_properties(_csmapi PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SWIG_OUTDIR}) +swig_link_libraries(csmapi ${CSM_LIBRARY} ${PYTHON_LIBRARY}) +#set_target_properties(csmapi PROPERTIES +# RUNTIME_OUTPUT_DIRECTORY python/csmapi) -swig_link_libraries(csmapi ${CSM_LIBRARY} ${PYTHON_LIBRARIES}) - -# Files to install with Python -set(PYTHON_INSTALL_FILES - ${CMAKE_CURRENT_BINARY_DIR}/csmapi.py - ${CMAKE_CURRENT_BINARY_DIR}/_csmapi.so) +# Build out a standard directory structure +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests) -# Configure setup.py and copy to output directory -set(SETUP_PY_IN ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in) -set(SETUP_PY_OUT ${CMAKE_CURRENT_BINARY_DIR}/setup.py) -configure_file(${SETUP_PY_IN} ${SETUP_PY_OUT}) +# Move the static files to move +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in + ${CMAKE_CURRENT_BINARY_DIR}/setup.py) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py + ${CMAKE_CURRENT_BINARY_DIR}/csmapi/__init__.py) # Declare install target for python -#install(TARGETS swig_example +#install(TARGETS csmapi # COMMAND "${PYTHON_EXECUTABLE} setup.py" # COMPONENT swig-python) # Install target to call setup.py -add_custom_target(install-python - DEPENDS _csmapi -COMMAND python ${SETUP_PY_OUT} install) +#add_custom_target(install-python +# DEPENDS _csmapi +#COMMAND python ${SETUP_PY_OUT} install) diff --git a/python/FindPythonAnaconda.cmake b/python/FindPythonAnaconda.cmake new file mode 100644 index 0000000..f310937 --- /dev/null +++ b/python/FindPythonAnaconda.cmake @@ -0,0 +1,102 @@ +# tested on OSX Yosemite and Ubuntu 14.04 LTS +# handle anaconda dependencies +cmake_minimum_required(VERSION 3.7) + +option(ANACONDA_PYTHON_VERBOSE "Anaconda dependency info" OFF) + +if(NOT CMAKE_FIND_ANACONDA_PYTHON_INCLUDED) + set(CMAKE_FIND_ANACONDA_PYTHON_INCLUDED 1) + + # find anaconda installation + set(_cmd conda info --root) + execute_process( + COMMAND ${_cmd} + RESULT_VARIABLE _r + OUTPUT_VARIABLE _o + ERROR_VARIABLE _e + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + + if(ANACONDA_PYTHON_VERBOSE) + message("Executing conda info --root") + message("_r = ${_r}") + message("_o = ${_o}") + message("_e = ${_e}") + endif() + + IF(IS_DIRECTORY ${_o}) + set(ANACONDA_PYTHON_FOUND True) + endif() + + if(ANACONDA_PYTHON_FOUND) + set( ANACONDA_PYTHON_DIR ${_o} ) + message( "Found anaconda root directory ${ANACONDA_PYTHON_DIR}" ) + + # find python version + # + set(_cmd python --version) + execute_process( + COMMAND ${_cmd} + RESULT_VARIABLE _r + OUTPUT_VARIABLE _o + ERROR_VARIABLE _o + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + + if(ANACONDA_PYTHON_VERBOSE) + message("Executing python --version") + message("_r = ${_r}") + # Different python version pipe to stdout vs. stderr + message("_o = ${_o}") + message("_e = ${_o}") + endif() + + string (REGEX MATCH "Python ([0-9]+)[.]([0-9]+)[.]([0-9]+)" _py_version_found "${_o}") + #message("_py_version_found = ${_py_version_found}") + #message("CMAKE_MATCH_0 = ${CMAKE_MATCH_0}") + set( _py_version_major ${CMAKE_MATCH_1} ) + set( _py_version_minor ${CMAKE_MATCH_2} ) + set( _py_version_patch ${CMAKE_MATCH_3} ) + set( ANACONDA_PYTHON_VERSION ${_py_version_major}.${_py_version_minor} ) + + + if( ${_py_version_major} MATCHES 2 ) + set( _py_ext "") + else() + set( _py_ext "m") + endif() + + set(_py_id "python${ANACONDA_PYTHON_VERSION}${_py_ext}") + + if( NOT DEFINED ENV{CONDA_PREFIX} ) + set( env_CONDA_DEFAULT_ENV "root" ) + message( WARNING "Could not find anaconda environment setting; using default root" ) + else() + set( env_CONDA_DEFAULT_ENV $ENV{CONDA_PREFIX} ) + endif() + + message( "Using anaconda ${env_CONDA_DEFAULT_ENV} environment" ) + if( env_CONDA_DEFAULT_ENV STREQUAL "root" ) + set(PYTHON_INCLUDE_DIR "${ANACONDA_PYTHON_DIR}/include/${_py_id}" CACHE INTERNAL "") + set(PYTHON_LIBRARY "${ANACONDA_PYTHON_DIR}/lib/lib${_py_id}${CMAKE_SHARED_LIBRARY_SUFFIX}" CACHE INTERNAL "") + else() + set(PYTHON_INCLUDE_DIR "${env_CONDA_DEFAULT_ENV}/include/${_py_id}" CACHE INTERNAL "") + set(PYTHON_LIBRARY "${env_CONDA_DEFAULT_ENV}/lib/lib${_py_id}${CMAKE_SHARED_LIBRARY_SUFFIX}" CACHE INTERNAL "") + endif() + + set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") + set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") + + set(FOUND_PYTHONLIBS TRUE) + else() + message( "Not found: anaconda root directory..." ) + message( "Trying system python install..." ) + FindPythonLibs() + endif() + + message( "PYTHON_INCLUDE_DIR = ${PYTHON_INCLUDE_DIR}") + message( "PYTHON_LIBRARY = ${PYTHON_LIBRARY}") +endif() + diff --git a/python/__init__.py b/python/__init__.py new file mode 100644 index 0000000..799e34c --- /dev/null +++ b/python/__init__.py @@ -0,0 +1 @@ +from csmapi import * diff --git a/python/setup.py.in b/python/setup.py.in index 886b272..2857d4d 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -1,35 +1,13 @@ -import setuptools.command.install -import shutil -from distutils.sysconfig import get_python_lib - -class CompiledLibInstall(setuptools.command.install.install): - """ - Specialized install to install to python libs - """ - - def run(self): - """ - Run method called by setup - :return: - """ - # Get filenames from CMake variable - filenames = '${PYTHON_INSTALL_FILES}'.split(';') - - # Directory to install to - install_dir = get_python_lib() - - # Install files - [shutil.copy(filename, install_dir) for filename in filenames] +import setuptools if __name__ == '__main__': setuptools.setup( name='csmapi', version='0.1.0', packages=['csmapi'], - cmdclass={'install':CompiledLibInstall}, + package_data={'':['_csmapi.so']}, license='UnLicense', author='jlaura', - zip_safe=False, author_email='jlaura@usgs.gov' ) - \ No newline at end of file + diff --git a/recipe/build.sh b/recipe/build.sh index b2f212e..2bcd129 100644 --- a/recipe/build.sh +++ b/recipe/build.sh @@ -1,6 +1,7 @@ -source activate base +#!/bin/bash + mkdir build && cd build -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PREFIX .. +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PREFIX -DANACONDA_PYTHON_VERBOSE=ON .. make cd python -python setup.py install +$PYTHON setup.py install --single-version-externally-managed --record=/tmp/record.txt \ No newline at end of file diff --git a/recipe/meta.yaml b/recipe/meta.yaml index c7a094d..8566697 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -1,22 +1,26 @@ package: - name: csmwrapper + name: csmapi version: "0.1.0" source: - git_url: https://github.com/USGS-Astrogeology/CSM-Swig.git + # git_url: https://github.com/USGS-Astrogeology/CSM-Swig.git + path: ../ requirements: build: - - {{ compiler('cxx') }} + - {{ compiler('cxx') }} # [linux] - cmake >=3.10 - libcsm - run + - python + host: + - python + run: - libcsm + - python test: - commands: - - import csmapi - - import csmapi.Isd + imports: + - csmapi about: home: https://github.com/USGS-Astrogeology/CSM-Swig -- GitLab