diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..c0d7432a --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,40 @@ +name: Privateer Build + +on: + push: + branches: [ "action_test" ] + pull_request: + branches: [ "action_test" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.7' + repo-token: ${{secrets.GITHUB_TOKEN}} + + - name: Check out dependencies + run : | + git clone https://github.com/Dialpuri/privateer_dependencies.git + + - name: Source Environment + run: source ccp4.envsetup-sh + + - name: Load python environment + run : pip install -r requirements.txt + + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v1.13 + + - name: Build + run : | + pwd + export CLIBD=privateer_dependencies/lib/data + + python setup_test.py install + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 60445892..d8592b93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,41 +19,63 @@ set(PRIVATEERDATA ${CMAKE_SOURCE_DIR}/data) set(CLIBDENV $ENV{CLIBD}) ## Find Privateer's dependencies that have been compiled locally. -# -find_library(MMDB2DEP NAMES mmdb2 - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CCP4CDEP NAMES ccp4c - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CCP4SRSDEP NAMES ccp4srs - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CLIPPERCOREDEP NAMES clipper-core - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CLIPPERMMDBDEP NAMES clipper-mmdb - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CLIPPERMINIMOLDEP NAMES clipper-minimol - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CLIPPERCONTRIBDEP NAMES clipper-contrib - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CLIPPERCCP4DEP NAMES clipper-ccp4 - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) -find_library(CLIPPERCIFDEP NAMES clipper-cif - HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) - -add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/pybind11) - +if (MODE STREQUAL "TESTING") + set (MMDB2DEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libmmdb2.so) + set (CCP4CDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libccp4srs.so) + set (CCP4SRSDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libccp4c.so) + set (CLIPPERCOREDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libclipper-core.so) + set (CLIPPERMMDBDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libclipper-mmdb.so) + set (CLIPPERMINIMOLDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libclipper-minimol.so) + set (CLIPPERCONTRIBDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libclipper-contrib.so) + set (CLIPPERCCP4DEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libclipper-ccp4.so) + set (CLIPPERCIFDEP ${CMAKE_SOURCE_DIR}/privateer_dependencies/lib/libclipper-cif.so) +else() + find_library(MMDB2DEP NAMES mmdb2 + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CCP4CDEP NAMES ccp4c + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CCP4SRSDEP NAMES ccp4srs + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CLIPPERCOREDEP NAMES clipper-core + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CLIPPERMMDBDEP NAMES clipper-mmdb + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CLIPPERMINIMOLDEP NAMES clipper-minimol + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CLIPPERCONTRIBDEP NAMES clipper-contrib + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CLIPPERCCP4DEP NAMES clipper-ccp4 + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) + find_library(CLIPPERCIFDEP NAMES clipper-cif + HINTS ${CMAKE_SOURCE_DIR}/dependencies/lib) +endif() + +if (MODE STREQUAL "TESTING") + add_subdirectory(${CMAKE_SOURCE_DIR}/privateer_dependencies/pybind11) +else() + add_subdirectory(${CMAKE_SOURCE_DIR}/dependencies/pybind11) +endif() find_package(Threads REQUIRED) - #Find Privateer's main.cpp file set(PRIVATEER_SOURCE ${PRIVATEER_SOURCE_DIR}/cpp/privateer.cpp) #Location of include files to be linked -include_directories(${CMAKE_SOURCE_DIR}/dependencies/include +if (MODE STREQUAL "TESTING") + include_directories(${CMAKE_SOURCE_DIR}/privateer_dependencies/include + ${CMAKE_SOURCE_DIR}/privateer_dependencies/gemmi/include + ${PYBIND11_INCLUDE_DIR} + ${PYTHON_INCLUDE_DIRS} + ${PRIVATEER_SOURCE_DIR}/cpp + ${PRIVATEER_SOURCE_DIR}/cpp/pybind11) +else() + include_directories(${CMAKE_SOURCE_DIR}/dependencies/include ${CMAKE_SOURCE_DIR}/dependencies/gemmi/include ${PYBIND11_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS} ${PRIVATEER_SOURCE_DIR}/cpp ${PRIVATEER_SOURCE_DIR}/cpp/pybind11) +endif() file(COPY ${PRIVATEERDATA}/glycomics/privateer_glycomics_database.json DESTINATION ${CLIBDENV}) diff --git a/setup_test.py b/setup_test.py new file mode 100644 index 00000000..21f238ca --- /dev/null +++ b/setup_test.py @@ -0,0 +1,138 @@ +import os +import re +import sys +import platform +import subprocess +import shutil + +from distutils.version import LooseVersion +import distutils.command.build +from setuptools import setup, find_packages, Extension, Command +import setuptools.command.develop +import setuptools.command.install +from setuptools.command.build_ext import build_ext + + +class CMakeExtension(Extension): + def __init__(self, name, sourcedir=''): + Extension.__init__(self, name, sources=[]) + self.sourcedir = os.path.abspath(sourcedir) + + +class CMakeBuild(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) + + def build_extension(self, ext): + extdir = os.path.abspath( + os.path.dirname(self.get_ext_fullpath(ext.name))) + cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + '-DPYTHON_EXECUTABLE=' + sys.executable] + + cfg = 'Debug' if self.debug else 'Release' + build_args = ['--config', cfg] + + if platform.system() == "Windows": + cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format( + cfg.upper(), + extdir)] + if sys.maxsize > 2**32: + cmake_args += ['-A', 'x64'] + build_args += ['--', '/m'] + else: + cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] + build_args += ['--', '-j2'] + + if platform.system() == "Darwin" : + if shutil.which('brew') == '/usr/local/bin/brew': + cmake_args += ['-DCMAKE_C_COMPILER=/usr/local/bin/gcc-12', '-DCMAKE_CXX_COMPILER=/usr/local/bin/g++-12'] + else: + cmake_args += ['-DCMAKE_C_COMPILER=/opt/homebrew/bin/gcc-12', '-DCMAKE_CXX_COMPILER=/opt/homebrew/bin/g++-12'] + + env = os.environ.copy() + env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format( + env.get('CXXFLAGS', ''), + self.distribution.get_version()) + exedir = 'build/executable' + if not os.path.exists(exedir): + os.makedirs(exedir) + + cmake_args += ["-D MODE=TESTING"] + + subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, + cwd=exedir, env=env) + subprocess.check_call(['cmake', '--build', '.'] + build_args, + cwd=exedir) + print() # Add an empty line for cleaner output + + + +# This function downloads and builds the shared-library +# def run_privateer_install_script(): + # build_privateer_cmd = ['bash', 'DependencyInstaller.sh'] + # if subprocess.call(build_privateer_cmd) != 0: + # sys.exit("Failed to build Privateer's dependencies") + +# I make a new command that will build the shared-library +class build_privateerdeps(Command): + user_options = [] + def initialize_options(self): + pass + def finalize_options(self): + pass + def run(self): + pass + # run_privateer_install_script() + +# I subclass install so that it will call my new command +class install(setuptools.command.install.install): + def run(self): + self.run_command('build_privateerdeps') + setuptools.command.install.install.run(self) + +# I do the same for build... +class build(distutils.command.build.build): + sub_commands = [ + ('build_privateerdeps', lambda self: True), + ] + distutils.command.build.build.sub_commands + +# ...and the same for develop +class develop(setuptools.command.develop.develop): + def run(self): + self.run_command('build_privateerdeps') + setuptools.command.develop.develop.run(self) + + +setup( + name='privateer', + version='0.4', + author='Jon Agirre', + author_email='jon.agirre@york.ac.uk', + description='The Swiss Army knife for carbohydrate structure validation, refinement and analysis', + long_description='', + packages=find_packages('src'), + package_dir={'':'src'}, + ext_modules=[CMakeExtension('privateer/privateer')], + cmdclass={ + 'install': install, + 'build_privateerdeps': build_privateerdeps, 'build': build, + 'develop': develop, + 'build_ext': CMakeBuild, + }, + zip_safe=False, +) +