From a6c85beaf9b5ee3529ec325ca3206ea3d4a3daa3 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Thu, 14 Sep 2023 13:18:35 +0100 Subject: [PATCH 1/5] Added actions workflow Changed CMakeLists --- .github/workflows/main.yml | 40 +++++++++++ CMakeLists.txt | 70 ++++++++++++------- setup_test.py | 138 +++++++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 setup_test.py 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, +) + From a8c3f82f32da88021b50f8abe8dd48bcacc177bc Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:28:33 +0100 Subject: [PATCH 2/5] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 71b8c19b..5d53bd0f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ![ScreenShot](/logo.png) # Privateer +![Privateer Build](https://github.com/glycojones/privateer/actions/workflows/main.yml/badge.svg) Privateer is a tool for carbohydrate structure validation, re-refinement and graphical analysis. It carries out automatic assignments of ring conformation (IUPAC nomenclature), anomeric form, absolute configuration and comparison to reference values for validation. It computes omit mFo-DFc maps and calculates a correlation coefficient between model and electron density. For structure refinement, it is able to generate chemical dictionaries with unimodal torsion restraints which will help keep the lowest energy conformation. In terms of graphical analysis, it will produce vector diagrams in SNFG nomenclature (SVG format), which are annotated using the validation information (ring conformation, anomeric form, etc). Privateer is implemented in C++11 and Python3 (via pybind11), and produces Scheme and Python scripts for use with Coot (https://github.com/pemsley/coot). From 552be0162395775160989b17f51d3697aea82f9a Mon Sep 17 00:00:00 2001 From: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:29:39 +0100 Subject: [PATCH 3/5] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5d53bd0f..babb89cd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ # Privateer ![Privateer Build](https://github.com/glycojones/privateer/actions/workflows/main.yml/badge.svg) + Privateer is a tool for carbohydrate structure validation, re-refinement and graphical analysis. It carries out automatic assignments of ring conformation (IUPAC nomenclature), anomeric form, absolute configuration and comparison to reference values for validation. It computes omit mFo-DFc maps and calculates a correlation coefficient between model and electron density. For structure refinement, it is able to generate chemical dictionaries with unimodal torsion restraints which will help keep the lowest energy conformation. In terms of graphical analysis, it will produce vector diagrams in SNFG nomenclature (SVG format), which are annotated using the validation information (ring conformation, anomeric form, etc). Privateer is implemented in C++11 and Python3 (via pybind11), and produces Scheme and Python scripts for use with Coot (https://github.com/pemsley/coot). From f2d837521e8413ae9753cc4b30956113f1d99368 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Thu, 14 Sep 2023 15:57:57 +0100 Subject: [PATCH 4/5] Updated workflow to be only on master push --- .github/workflows/main.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c0d7432a..385e473e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,10 +1,18 @@ -name: Privateer Build + + me: Privateer Build on: push: - branches: [ "action_test" ] + branches: [ "master" ] + paths: + - src/** + - CMakeLists.txt + pull_request: - branches: [ "action_test" ] + branches: [ "master" ] + paths: + - src/** + - CMakeLists.txt jobs: build: From e5955fe5da28f6ecf9a702754977fad74519f17b Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Thu, 14 Sep 2023 16:00:00 +0100 Subject: [PATCH 5/5] Updated main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 385e473e..58e1029b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,5 @@ - me: Privateer Build +name: Privateer Build on: push: