From fccc77fcca6a815cdcf1694c0db8147ab8770d8a Mon Sep 17 00:00:00 2001 From: ye11owSub Date: Sun, 12 May 2024 11:28:15 +0300 Subject: [PATCH] moving project meta and packages search to pyproject.toml --- CMakeLists.txt | 31 -- INSTALL | 2 +- contrib/champ/meson.build | 26 ++ create_shadertext.py | 5 +- layer0/meson.build | 44 +++ layer1/meson.build | 53 +++ layer2/meson.build | 60 ++++ layer3/meson.build | 24 ++ layer4/meson.build | 10 + layer5/meson.build | 9 + layerCTest/meson.build | 33 ++ meson.build | 123 +++++++ meson_options.txt | 64 ++++ modules/pymol/__main__.py | 10 - ov/src/meson.build | 15 + pyproject.toml | 36 ++ setup.py | 672 -------------------------------------- 17 files changed, 502 insertions(+), 715 deletions(-) delete mode 100644 CMakeLists.txt create mode 100644 contrib/champ/meson.build create mode 100644 layer0/meson.build create mode 100644 layer1/meson.build create mode 100644 layer2/meson.build create mode 100644 layer3/meson.build create mode 100644 layer4/meson.build create mode 100644 layer5/meson.build create mode 100644 layerCTest/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt delete mode 100644 modules/pymol/__main__.py create mode 100644 ov/src/meson.build create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 0620b6f5f..000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 3.13) - -project(${TARGET_NAME}) - -set(CMAKE_VERBOSE_MAKEFILE on) - -add_library(${TARGET_NAME} SHARED ${ALL_SRC}) - -target_compile_options(${TARGET_NAME} PRIVATE ${ALL_COMP_ARGS}) - -set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ${SHARED_SUFFIX}) - -target_compile_features(${TARGET_NAME} PRIVATE cxx_std_17) - -set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "") - -target_include_directories(${TARGET_NAME} PUBLIC ${ALL_INC_DIR}) - -target_link_directories(${TARGET_NAME} PUBLIC ${ALL_LIB_DIR}) - - -if(APPLE) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup") -endif() - -target_link_libraries(${TARGET_NAME} - ${ALL_LIB} - ${ALL_EXT_LINK} -) - -target_compile_definitions(${TARGET_NAME} PUBLIC ${ALL_DEF}) diff --git a/INSTALL b/INSTALL index abe3c8b14..9429b4955 100644 --- a/INSTALL +++ b/INSTALL @@ -8,7 +8,7 @@ See also: http://pymolwiki.org/index.php/Linux_Install REQUIREMENTS - C++17 compiler (e.g. gcc 8+) - - CMake (3.13+) + - CMake (3.15+) - Python 3.9+ - Pmw (Python Megawidgets) (optional, for legacy GUI/plugins) https://github.com/schrodinger/pmw-patched diff --git a/contrib/champ/meson.build b/contrib/champ/meson.build new file mode 100644 index 000000000..0c2ee972d --- /dev/null +++ b/contrib/champ/meson.build @@ -0,0 +1,26 @@ +files_names = [ + 'champ.c', + 'champ_module.c', + 'chiral.c', + 'err2.c', + 'feedback2.c', + 'list.c', + 'os_memory.c', + 'sort.c', + 'strblock.c', + 'vla.c', +] +champ_src_files = [] + +foreach file_name : files_names + champ_src_files += files(file_name) +endforeach + +py = import('python').find_installation(pure: false) + +py.extension_module( + 'chempy.champ._champ', + champ_src_files, + install: true, +) + diff --git a/create_shadertext.py b/create_shadertext.py index f6857087e..d6571bd0a 100644 --- a/create_shadertext.py +++ b/create_shadertext.py @@ -8,16 +8,18 @@ from os.path import dirname from subprocess import Popen, PIPE -def create_all(generated_dir, pymoldir="."): +def create_all(pymoldir="."): ''' Generate various stuff ''' + generated_dir = os.path.join(os.environ.get("PYMOL_BLD", "build"), "generated") create_shadertext( os.path.join(pymoldir, "data", "shaders"), generated_dir, os.path.join(generated_dir, "ShaderText.h"), os.path.join(generated_dir, "ShaderText.cpp")) create_buildinfo(generated_dir, pymoldir) + print(generated_dir) class openw(object): """ @@ -129,6 +131,7 @@ def create_buildinfo(outputdir, pymoldir='.'): #define _PYMOL_BUILD_GIT_SHA "%s" ''' % (time.time(), sha), file=out) +create_all() if __name__ == "__main__": create_shadertext(*sys.argv[1:6]) create_buildinfo(dirname(sys.argv[4]), dirname(dirname(sys.argv[1]))) diff --git a/layer0/meson.build b/layer0/meson.build new file mode 100644 index 000000000..696f53cf6 --- /dev/null +++ b/layer0/meson.build @@ -0,0 +1,44 @@ +files_names = [ + 'Bezier.cpp', + 'Block.cpp', + 'CarveHelper.cpp', + 'ccealignmodule.cpp', + 'ContourSurf.cpp', + 'Crystal.cpp', + 'Err.cpp', + 'Feedback.cpp', + 'Field.cpp', + 'File.cpp', + 'GenericBuffer.cpp', + 'GFXManager.cpp', + 'GraphicsUtil.cpp', + 'Isosurf.cpp', + 'Map.cpp', + 'marching_cubes.cpp', + 'Match.cpp', + 'Matrix.cpp', + 'MemoryDebug.cpp', + 'MemoryUsage.cpp', + 'MyPNG.cpp', + 'os_gl.cpp', + 'Parse.cpp', + 'Pixmap.cpp', + 'PostProcess.cpp', + 'ShaderMgr.cpp', + 'ShaderPreprocessor.cpp', + 'ShaderPrg.cpp', + 'Sphere.cpp', + 'Tetsurf.cpp', + 'Texture.cpp', + 'Tracker.cpp', + 'Triangle.cpp', + 'TTT.cpp', + 'Util.cpp', + 'Util2.cpp', + 'Vector.cpp', + 'Word.cpp', +] + +foreach file_name : files_names + src_files += files(file_name) +endforeach diff --git a/layer1/meson.build b/layer1/meson.build new file mode 100644 index 000000000..833c16309 --- /dev/null +++ b/layer1/meson.build @@ -0,0 +1,53 @@ +files_names = [ + 'Basis.cpp', + 'ButMode.cpp', + 'Camera.cpp', + 'CGO.cpp', + 'CGOGL.cpp', + 'CGORenderer.cpp', + 'Character.cpp', + 'COLLADA.cpp', + 'Color.cpp', + 'Control.cpp', + 'Extrude.cpp', + 'Font.cpp', + 'FontGLUT.cpp', + 'FontGLUT8x13.cpp', + 'FontGLUT9x15.cpp', + 'FontGLUTHel10.cpp', + 'FontGLUTHel12.cpp', + 'FontGLUTHel18.cpp', + 'FontType.cpp', + 'Movie.cpp', + 'Ortho.cpp', + 'P.cpp', + 'PConv.cpp', + 'Picking.cpp', + 'Pop.cpp', + 'PyMOLObject.cpp', + 'Ray.cpp', + 'Rep.cpp', + 'Scene.cpp', + 'SceneMouse.cpp', + 'ScenePicking.cpp', + 'SceneRay.cpp', + 'SceneRender.cpp', + 'SceneView.cpp', + 'ScrollBar.cpp', + 'Seq.cpp', + 'Setting.cpp', + 'Shaker.cpp', + 'Symmetry.cpp', + 'SymOp.cpp', + 'SymOpPConv.cpp', + 'SymOpTools.cpp', + 'Text.cpp', + 'TypeFace.cpp', + 'View.cpp', + 'Wizard.cpp', +] + +foreach file_name : files_names + src_files += files(file_name) +endforeach + diff --git a/layer2/meson.build b/layer2/meson.build new file mode 100644 index 000000000..50d1aebaf --- /dev/null +++ b/layer2/meson.build @@ -0,0 +1,60 @@ +files_names = [ + 'AssemblyHelpers.cpp', + 'AtomInfo.cpp', + 'AtomInfoHistory.cpp', + 'BondTypeHistory.cpp', + 'CifFile.cpp', + 'CifMoleculeReader.cpp', + 'CoordSet.cpp', + 'DistSet.cpp', + 'GadgetSet.cpp', + 'HydrogenAdder.cpp', + 'MmodTyping.cpp', + 'MmtfMoleculeReader.cpp', + 'Mol2Typing.cpp', + 'MolV3000.cpp', + 'ObjectAlignment.cpp', + 'ObjectCallback.cpp', + 'ObjectCGO.cpp', + 'ObjectCurve.cpp', + 'ObjectDist.cpp', + 'ObjectGadget.cpp', + 'ObjectGadgetRamp.cpp', + 'ObjectGroup.cpp', + 'ObjectMap.cpp', + 'ObjectMesh.cpp', + 'ObjectMolecule.cpp', + 'ObjectMolecule2.cpp', + 'ObjectMolecule3.cpp', + 'ObjectSlice.cpp', + 'ObjectSurface.cpp', + 'ObjectVolume.cpp', + 'RepAngle.cpp', + 'RepCartoon.cpp', + 'RepCylBond.cpp', + 'RepDihedral.cpp', + 'RepDistDash.cpp', + 'RepDistLabel.cpp', + 'RepDot.cpp', + 'RepEllipsoid.cpp', + 'RepLabel.cpp', + 'RepMesh.cpp', + 'RepNonbonded.cpp', + 'RepNonbondedSphere.cpp', + 'RepRibbon.cpp', + 'RepSphere.cpp', + 'RepSphereGenerate.cpp', + 'RepSphereImmediate.cpp', + 'RepSurface.cpp', + 'RepWireBond.cpp', + 'Sculpt.cpp', + 'SculptCache.cpp', + 'SideChainHelper.cpp', + 'VFont.cpp', +] + + +foreach file_name : files_names + src_files += files(file_name) +endforeach + diff --git a/layer3/meson.build b/layer3/meson.build new file mode 100644 index 000000000..c47b2e4ff --- /dev/null +++ b/layer3/meson.build @@ -0,0 +1,24 @@ +files_names = [ + 'AtomIterators.cpp', + 'CifDataValueFormatter.cpp', + 'Editor.cpp', + 'Executive.cpp', + 'ExecutivePython.cpp', + 'Interactions.cpp', + 'MaeExportHelpers.cpp', + 'MoleculeExporter.cpp', + 'MovieScene.cpp', + 'PlugIOManager.cpp', + 'RingFinder.cpp', + 'Seeker.cpp', + 'Selector.cpp', + 'SelectorTmp.cpp', + 'SpecRec.cpp', + 'SpecRecSpecial.cpp', +] + + +foreach file_name : files_names + src_files += files(file_name) +endforeach + diff --git a/layer4/meson.build b/layer4/meson.build new file mode 100644 index 000000000..aa118caf4 --- /dev/null +++ b/layer4/meson.build @@ -0,0 +1,10 @@ +files_names = [ + 'Cmd.cpp', + 'Menu.cpp', + 'PopUp.cpp', +] + +foreach file_name : files_names + src_files += files(file_name) +endforeach + diff --git a/layer5/meson.build b/layer5/meson.build new file mode 100644 index 000000000..824cad84c --- /dev/null +++ b/layer5/meson.build @@ -0,0 +1,9 @@ +files_names = [ + 'main.cpp', + 'PyMOL.cpp', + 'TestPyMOL.cpp' +] + +foreach file_name : files_names + src_files += files(file_name) +endforeach diff --git a/layerCTest/meson.build b/layerCTest/meson.build new file mode 100644 index 000000000..e3e661e20 --- /dev/null +++ b/layerCTest/meson.build @@ -0,0 +1,33 @@ +files_names = [ + 'Test.cpp', + 'Test_Algorithm.cpp', + 'Test_Bezier.cpp', + 'Test_cache_ptr.cpp', + 'Test_CCrystal.cpp', + 'Test_CifFile.cpp', + 'Test_Classic_VLA.cpp', + 'Test_copyable_ptr.cpp', + 'Test_Event.cpp', + 'Test_Executive.cpp', + 'Test_Image.cpp', + 'Test_List.cpp', + 'Test_Picking.cpp', + 'Test_Result.cpp', + 'Test_ScrollBar.cpp', + 'Test_ShaderPreprocessor.cpp', + 'Test_SymOp.cpp', + 'Test_Test.cpp', + 'Test_TTT.cpp', + 'Test_type_traits.cpp', + 'Test_Util.cpp', + 'Test_VLA.cpp', + 'Test_zstring_view.cpp', +] + + +foreach file_name : files_names + src_files += files(file_name) +endforeach + +macros += '-D_PYMOL_CTEST' + diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..0abae544f --- /dev/null +++ b/meson.build @@ -0,0 +1,123 @@ +project( + 'pymol', + 'c', 'cpp', + meson_version: '>= 1.4.0', + default_options: [ + 'cpp_std=c++14', + ], +) + +py = import('python').find_installation(pure: false) + +dependencies = [ + dependency('libpng'), + dependency('freetype2') +] +include_dirs = [ + include_directories('include'), + include_directories('layer0'), + include_directories('layer1'), + include_directories('layer2'), + include_directories('layer3'), + include_directories('layer4'), + include_directories('layer5'), + include_directories('layer5'), + include_directories('ov/src'), +] +incdir_numpy = run_command(py, + [ + '-c', + 'import os, numpy; print(os.path.relpath(numpy.get_include()))' + ], + check: true +).stdout().strip() +include_dirs += include_directories(incdir_numpy) + +src_files = [] +macros = [ + '-D_PYMOL_LIBPNG', + '-D_PYMOL_FREETYPE', + '-D_PYMOL_NUMPY', +] +flags = host_machine.system() == 'windows' ? ['-WMP'] : [ + '-Werror=return-type', + '-Wunused-variable', + '-Wno-switch', + '-Wno-narrowing', + '-Wno-char-subscripts', +] + + +if get_option('use-openmp') + #dependencies += dependency('openmp') + # shouldn't it be _PYMOL_OPENMP? + macros += '-DPYMOL_OPENMP' +endif + +if not get_option('no-vmd-plugins') + include_dirs += include_directories('contrib/uiuc/plugins/include') + src_dirs += 'contrib/uiuc/plugins/molfile_plugin/src' + dependencies += dependency('netcdf') + macros += '-D_PYMOL_VMD_PLUGINS' +endif + +if not get_option('no-libxml') + dependencies += dependency('libxml-2.0') + macros += '-D_PYMOL_VMD_PLUGINS' +endif + +msg_dep = get_option('use-msgpackc') +if msg_dep != 'guess' + dependencies += dependency('msgpackc') +else + macros += '-D_PYMOL_NO_MSGPACKC' +endif + +if not get_option('no-glut') + macros += '-D_PYMOL_NO_MAIN' +endif + +if get_option('testing') + subdir('layerCTest') +endif + +if get_option('openvr') + dependencies += dependency('openvr') + macros += '-D_PYMOL_OPENVR' +endif + +# macos +if host_machine.system() == 'darwin' + dependencies += [ + dependency('GLEW'), + dependency('glut') + ] + # shouldn't it be _PYMOL_CURVE_VALIDATE? + macros += '-DPYMOL_CURVE_VALIDATE' + +endif + + +#generated_dir = run_command('./create_shadertext.py', check: true).stdout().strip() + + +subdir('ov/src') +subdir('layer0') +subdir('layer1') +subdir('layer2') +subdir('layer3') +subdir('layer4') +subdir('layer5') + +subdir('contrib/champ') + + +py.extension_module( + 'pymol._cmd', + src_files, + include_directories : include_dirs, + cpp_args: macros + flags, + dependencies: dependencies, + install: true, +) + diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 000000000..f1fdc35d7 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,64 @@ +option( + 'no-glut', + type : 'boolean', + value : true, + description : 'link with GLUT (legacy GUI)' +) + +option( + 'no-osx-frameworks', + type : 'boolean', + value : true, + description : 'on MacOS use XQuartz instead of native frameworks' +) + +option( + 'no-libxml', + type : 'boolean', + value : false, + description : 'skip libxml2 dependency, disables COLLADA export' +) + +option( + 'use-openmp', + type : 'boolean', + value : true, + description : 'Use OpenMP' +) + +option( + 'use-vtkm', + type : 'combo', + choices : ['1.5', '1.6', '1.7', 'no'], + value : 'no', + description : 'Use VTK-m for isosurface generation' +) + +option( + 'use-msgpackc', + type : 'combo', + choices : ['c++11', 'c', 'guess', 'no'], + value : 'guess', + description : 'c++11: use msgpack-c header-only library; c: link against shared library; no: disable fast MMTF load support' +) + +option( + 'testing', + type : 'boolean', + value : false, + description : 'Build C-level tests' +) + +option( + 'openvr', + type : 'boolean', + value : false +) + +option( + 'no-vmd-plugins', + type : 'boolean', + value : true, + description : 'Disable VMD molfile plugins (libnetcdf dependency)' +) + diff --git a/modules/pymol/__main__.py b/modules/pymol/__main__.py deleted file mode 100644 index 831402754..000000000 --- a/modules/pymol/__main__.py +++ /dev/null @@ -1,10 +0,0 @@ -''' -PyMOL Molecular Graphics System -Copyright (c) Schrodinger, Inc. -''' - -import sys - -if __name__ == '__main__': - import pymol - sys.exit(pymol.launch()) diff --git a/ov/src/meson.build b/ov/src/meson.build new file mode 100644 index 000000000..052931d50 --- /dev/null +++ b/ov/src/meson.build @@ -0,0 +1,15 @@ +files_names = [ + 'ov_utility.cpp', + 'OVContext.cpp', + 'OVHeap.cpp', + 'OVHeapArray.cpp', + 'OVLexicon.cpp', + 'OVOneToAny.cpp', + 'OVOneToOne.cpp', + 'OVRandom.cpp', +] + +foreach file_name : files_names + src_files += files(file_name) +endforeach + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..735ac7237 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[project] +name = "pymol" +readme = "README.md" +version="0.0.0" +requires-python = ">=3.9" +license = {file = "LICENSE"} +description = """ +PyMOL is a Python-enhanced molecular graphics tool. +It excels at 3D visualization of proteins, small molecules, density, +surfaces, and trajectories. It also includes molecular editing, +ray tracing, and movies. Open Source PyMOL is free to everyone! +""" +authors = [ + {name = "Schrodinger", email = "pymol-users@lists.sourceforge.net"}, +] + +[build-system] +requires = [ + "meson-python>=0.15.0", + "numpy>=1.26.4" +] +build-backend = "mesonpy" + +[project.scripts] +pymol = "modules.pymol:launch" + +[project.gui-scripts] +pymol-gui = "modules.pymol:launch_gui" + +[project.urls] +Homepage = "https://pymol.org" +Documentation = "https://pymol.org/dokuwiki" +Repository = "https://github.com/schrodinger/pymol-open-source" +"Bug Tracker" = "https://github.com/schrodinger/pymol-open-source/issues" +Changelog = "https://github.com/schrodinger/pymol-open-source/blob/master/ChangeLog" + diff --git a/setup.py b/setup.py deleted file mode 100644 index 83111878b..000000000 --- a/setup.py +++ /dev/null @@ -1,672 +0,0 @@ -#!/usr/bin/env python -# -# This script only applies if you are performing a Python setuptools-based -# installation of PyMOL. -# -# It may assume that all of PyMOL's external dependencies are -# pre-installed into the system. - -import argparse -import glob -import os -import pathlib -import re -import sys -import sysconfig -import shutil - -from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext -from setuptools.command.build_py import build_py -from setuptools.command.install import install - -import create_shadertext - -# non-empty DEBUG variable turns off optimization and adds -g flag -DEBUG = bool(os.getenv('DEBUG', '')) - -WIN = sys.platform.startswith('win') -MAC = sys.platform.startswith('darwin') - -# handle extra arguments - - -class options: - osx_frameworks = True - jobs = int(os.getenv('JOBS', 0)) - no_libxml = False - no_glut = True - use_msgpackc = 'guess' - testing = False - openvr = False - use_openmp = 'no' if MAC else 'yes' - use_vtkm = 'no' - vmd_plugins = True - - -parser = argparse.ArgumentParser() -parser.add_argument('--glut', dest='no_glut', action="store_false", - help="link with GLUT (legacy GUI)") -parser.add_argument('--no-osx-frameworks', dest='osx_frameworks', - help="on MacOS use XQuartz instead of native frameworks", - action="store_false") -parser.add_argument('--jobs', '-j', type=int, help="for parallel builds " - "(defaults to number of processors)") -parser.add_argument('--no-libxml', action="store_true", - help="skip libxml2 dependency, disables COLLADA export") -parser.add_argument('--use-openmp', choices=('yes', 'no'), - help="Use OpenMP") -parser.add_argument('--use-vtkm', choices=('1.5', '1.6', '1.7', 'no'), - help="Use VTK-m for isosurface generation") -parser.add_argument('--use-msgpackc', choices=('c++11', 'c', 'guess', 'no'), - help="c++11: use msgpack-c header-only library; c: link against " - "shared library; no: disable fast MMTF load support") -parser.add_argument('--testing', action="store_true", - help="Build C-level tests") -parser.add_argument('--openvr', dest='openvr', action='store_true') -parser.add_argument('--no-vmd-plugins', dest='vmd_plugins', - action='store_false', - help='Disable VMD molfile plugins (libnetcdf dependency)') -options, sys.argv[1:] = parser.parse_known_args(namespace=options) - -if False: - import monkeypatch_distutils - monkeypatch_distutils.set_parallel_jobs(options.jobs) - - -def forms_uic(build_lib='modules'): - ''' - Convert Qt UI files in "modules/pmg_qt/forms" to Python files in place - ''' - - -def get_prefix_path(): - ''' - Return a list of paths which will be searched for "include", - "include/freetype2", "lib", "lib64" etc. - ''' - try: - return os.environ['PREFIX_PATH'].split(os.pathsep) - except KeyError: - pass - - if sys.platform.startswith("freebsd"): - return ["/usr/local"] - - X11 = ['/usr/X11'] * (not options.osx_frameworks) - - if sys.platform == 'darwin': - for prefix in ['/sw', '/opt/local', '/usr/local']: - if sys.base_prefix.startswith(prefix): - return [prefix] + X11 - - if is_conda_env(): - if sys.platform.startswith('win'): - return [os.path.join(sys.prefix, 'Library')] - - return [sys.prefix] + X11 - - return ['/usr'] + X11 - - -def is_conda_env(): - return ( - 'conda' in sys.prefix or - 'conda' in sys.version or - 'Continuum' in sys.version or - sys.prefix == os.getenv('CONDA_PREFIX')) - - -def guess_msgpackc(): - for prefix in prefix_path: - for suffix in ['h', 'hpp']: - f = os.path.join(prefix, 'include', 'msgpack', f'version_master.{suffix}') - - try: - m = re.search(r'MSGPACK_VERSION_MAJOR\s+(\d+)', open(f).read()) - except EnvironmentError: - continue - - if m is not None: - major = int(m.group(1)) - if major > 1: - return 'c++11' - - return 'no' - - -class CMakeExtension(Extension): - - def __init__(self, - name, - sources, - include_dirs=[], - libraries=[], - library_dirs=[], - define_macros=[], - extra_link_args=[], - extra_compile_args=[]): - # don't invoke the original build_ext for this special extension - super().__init__(name, sources=[]) - self.sources = sources - self.include_dirs = include_dirs - self.libraries = libraries - self.library_dirs = library_dirs - self.define_macros = define_macros - self.extra_link_args = extra_link_args - self.extra_compile_args = extra_compile_args - - -class build_ext_pymol(build_ext): - def initialize_options(self) -> None: - super().initialize_options() - if DEBUG and not WIN: - self.debug = False - - def run(self): - for ext in self.extensions: - self.build_cmake(ext) - - def build_cmake(self, ext): - cwd = pathlib.Path().absolute() - - # these dirs will be created in build_py, so if you don't have - # any python sources to bundle, the dirs will be missing - name_split = ext.name.split('.') - target_name = name_split[-1] - build_temp = pathlib.Path(self.build_temp) / target_name - build_temp.mkdir(parents=True, exist_ok=True) - extdir = pathlib.Path(self.get_ext_fullpath(ext.name)) - extdirabs = extdir.absolute() - - extdir.parent.mkdir(parents=True, exist_ok=True) - - def concat_paths(paths): - return ''.join(path.replace('\\', '/') + ";" for path in paths) - - config = 'Debug' if DEBUG else 'Release' - lib_output_dir = str(extdir.parent.absolute()) - all_files = ext.sources - all_src = concat_paths(all_files) - all_defs = ''.join(mac[0] + ";" for mac in ext.define_macros) - all_libs = ''.join(f"{lib};" for lib in ext.libraries) - all_ext_link = ' '.join(ext.extra_link_args) - all_comp_args = ''.join(f"{arg};" for arg in ext.extra_compile_args) - all_lib_dirs = concat_paths(ext.library_dirs) - all_inc_dirs = concat_paths(ext.include_dirs) - - lib_mode = "RUNTIME" if WIN else "LIBRARY" - - shared_suffix = sysconfig.get_config_var('EXT_SUFFIX') - - cmake_args = [ - f"-DTARGET_NAME={target_name}", - f"-DCMAKE_{lib_mode}_OUTPUT_DIRECTORY={lib_output_dir}", - f"-DCMAKE_BUILD_TYPE={config}", - f"-DALL_INC_DIR={all_inc_dirs}", - f"-DALL_SRC={all_src}", - f"-DALL_DEF={all_defs}", - f"-DALL_LIB_DIR={all_lib_dirs}", - f"-DALL_LIB={all_libs}", - f"-DALL_COMP_ARGS={all_comp_args}", - f"-DALL_EXT_LINK={all_ext_link}", - f"-DSHARED_SUFFIX={shared_suffix}" - ] - - # example of build args - build_args = ['--config', config] - if not WIN: # Win /MP flag on compilation level - cpu_count = os.cpu_count() or 1 - build_args += [f'-j{cpu_count}'] - - os.chdir(str(build_temp)) - self.spawn(['cmake', str(cwd)] + cmake_args) - if not self.dry_run: - self.spawn(['cmake', '--build', '.'] + build_args) - - if WIN: - # Move up from VS release folder - cmake_lib_loc = pathlib.Path(lib_output_dir, "Release", f"{target_name}{shared_suffix}") - if cmake_lib_loc.exists(): - shutil.move(cmake_lib_loc, extdirabs) - - # Troubleshooting: if fail on line above then delete all possible - # temporary CMake files including "CMakeCache.txt" in top level dir. - os.chdir(str(cwd)) - - -class build_py_pymol(build_py): - def run(self): - build_py.run(self) - forms_uic(self.build_lib) - - -class install_pymol(install): - pymol_path = None - bundled_pmw = False - no_launcher = False - - user_options = install.user_options + [ - ('pymol-path=', None, 'PYMOL_PATH'), - ('bundled-pmw', None, 'install bundled Pmw module'), - ('no-launcher', None, 'skip installation of the pymol launcher'), - ] - - def finalize_options(self): - install.finalize_options(self) - - self.pymol_path_is_default = self.pymol_path is None - - if self.pymol_path is None: - self.pymol_path = os.path.join( - self.install_libbase, 'pymol', 'pymol_path') - elif self.root is not None: - self.pymol_path = install_pymol.change_root( - self.root, self.pymol_path) - - def run(self): - super().run() - self.install_pymol_path() - - if not self.no_launcher: - self.make_launch_script() - - if self.bundled_pmw: - raise Exception('--bundled-pmw has been removed, please install Pmw from ' - 'https://github.com/schrodinger/pmw-patched') - - def unchroot(self, name): - if self.root is not None and name.startswith(self.root): - return name[len(self.root):] - return name - - def copy_tree_nosvn(self, src, dst): - def ignore(src, names): return set([ - ]).intersection(names) - if os.path.exists(dst): - shutil.rmtree(dst) - print('copying %s -> %s' % (src, dst)) - shutil.copytree(src, dst, ignore=ignore) - - def copy(self, src, dst): - copy = self.copy_tree_nosvn if os.path.isdir(src) else self.copy_file - copy(src, dst) - - def install_pymol_path(self): - self.mkpath(self.pymol_path) - for name in ['LICENSE', 'data', 'test', 'examples', ]: - self.copy(name, os.path.join(self.pymol_path, name)) - - if options.openvr: - self.copy('contrib/vr/README.md', - os.path.join(self.pymol_path, 'README-VR.txt')) - - def make_launch_script(self): - if sys.platform.startswith('win'): - launch_script = 'pymol.bat' - else: - launch_script = 'pymol' - - self.mkpath(self.install_scripts) - launch_script = os.path.join(self.install_scripts, launch_script) - - python_exe = os.path.abspath(sys.executable) - pymol_file = self.unchroot(os.path.join( - self.install_libbase, 'pymol', '__init__.py')) - pymol_path = self.unchroot(self.pymol_path) - - with open(launch_script, 'w') as out: - if sys.platform.startswith('win'): - # paths relative to launcher, if possible - try: - python_exe = '%~dp0\\' + \ - os.path.relpath(python_exe, self.install_scripts) - except ValueError: - pass - try: - pymol_file = '%~dp0\\' + \ - os.path.relpath(pymol_file, self.install_scripts) - except ValueError: - pymol_file = os.path.abspath(pymol_file) - - if not self.pymol_path_is_default: - out.write(f'set PYMOL_PATH={pymol_path}' + os.linesep) - out.write('"%s" "%s"' % (python_exe, pymol_file)) - out.write(' %*' + os.linesep) - else: - out.write('#!/bin/sh' + os.linesep) - if not self.pymol_path_is_default: - out.write(f'export PYMOL_PATH="{pymol_path}"' + os.linesep) - out.write('exec "%s" "%s" "$@"' % - (python_exe, pymol_file) + os.linesep) - - os.chmod(launch_script, 0o755) - -# ============================================================================ - - -# should be something like (build_base + "/generated"), but that's only -# known to build and install instances -generated_dir = os.path.join(os.environ.get("PYMOL_BLD", "build"), "generated") - -create_shadertext.create_all(generated_dir) - -# can be changed with environment variable PREFIX_PATH -prefix_path = get_prefix_path() - -inc_dirs = [ - "include", -] - -pymol_src_dirs = [ - "ov/src", - "layer0", - "layer1", - "layer2", - "layer3", - "layer4", - "layer5", - generated_dir, -] - -def_macros = [ - ("_PYMOL_LIBPNG", None), - ("_PYMOL_FREETYPE", None), -] - -if DEBUG and not WIN: - def_macros += [ - # bounds checking in STL containers - ("_GLIBCXX_ASSERTIONS", None), - ] - -libs = ["png", "freetype"] -lib_dirs = [] -ext_comp_args = [ - "-Werror=return-type", - "-Wunused-variable", - "-Wno-switch", - "-Wno-narrowing", - # legacy stuff - '-Wno-char-subscripts', - # optimizations - "-Og" if DEBUG else "-O3", -] if not WIN else ["/MP"] -ext_link_args = [] -ext_objects = [] -data_files = [] -ext_modules = [] - -if options.use_openmp == 'yes': - def_macros += [ - ("PYMOL_OPENMP", None), - ] - if MAC: - ext_comp_args += ["-Xpreprocessor", "-fopenmp"] - libs += ["omp"] - elif WIN: - ext_comp_args += ["/openmp"] - else: - ext_comp_args += ["-fopenmp"] - ext_link_args += ["-fopenmp"] - -if options.vmd_plugins: - # VMD plugin support - inc_dirs += [ - 'contrib/uiuc/plugins/include', - ] - pymol_src_dirs += [ - 'contrib/uiuc/plugins/molfile_plugin/src', - ] - def_macros += [ - ("_PYMOL_VMD_PLUGINS", None), - ] - -if not options.no_libxml: - # COLLADA support - def_macros += [ - ("_HAVE_LIBXML", None) - ] - libs += ["xml2"] - -if options.use_msgpackc == 'guess': - options.use_msgpackc = guess_msgpackc() - -if options.use_msgpackc == 'no': - def_macros += [("_PYMOL_NO_MSGPACKC", None)] -else: - if options.use_msgpackc == 'c++11': - def_macros += [ - ("MMTF_MSGPACK_USE_CPP11", None), - ("MSGPACK_NO_BOOST", None), - ] - else: - libs += ['msgpackc'] - - pymol_src_dirs += ["contrib/mmtf-c"] - -if options.no_glut: - def_macros += [ - ("_PYMOL_NO_MAIN", None), - ] - -if options.testing: - pymol_src_dirs += ["layerCTest"] - def_macros += [("_PYMOL_CTEST", None)] - -if options.openvr: - def_macros += [("_PYMOL_OPENVR", None)] - pymol_src_dirs += [ - "contrib/vr", - ] - -inc_dirs += pymol_src_dirs - -# ============================================================================ -if MAC: - libs += ["GLEW"] - def_macros += [("PYMOL_CURVE_VALIDATE", None)] - - if options.osx_frameworks: - ext_link_args += [ - "-framework OpenGL", - ] + (not options.no_glut) * [ - "-framework GLUT", - ] - def_macros += [ - ("_PYMOL_OSX", None), - ] - else: - libs += [ - "GL", - ] + (not options.no_glut) * [ - "glut", - ] - -if WIN: - # clear - libs = [] - - def_macros += [ - ("WIN32", None), - ] - - libs += [ - "Advapi32", # Registry (RegCloseKey etc.) - "Ws2_32", # htonl - ] - - if True: - libs += [ - "glew32", - "freetype", - "libpng", - ] + (not options.no_glut) * [ - "freeglut", - ] + (not options.no_libxml) * [ - "libxml2", - ] - - if DEBUG: - ext_comp_args += ['/Z7'] - ext_link_args += ['/DEBUG'] - - libs += [ - "opengl32", - ] - # TODO: Remove when we move to setup-CMake - ext_comp_args += ["/std:c++17"] - -if not (MAC or WIN): - libs += [ - "GL", - "GLEW", - ] + (not options.no_glut) * [ - "glut", - ] - -if options.use_vtkm != "no": - for prefix in prefix_path: - vtkm_inc_dir = os.path.join( - prefix, "include", f"vtkm-{options.use_vtkm}") - if os.path.exists(vtkm_inc_dir): - break - else: - raise LookupError('VTK-m headers not found.' - f' PREFIX_PATH={":".join(prefix_path)}') - def_macros += [ - ("_PYMOL_VTKM", None), - ] - inc_dirs += [ - vtkm_inc_dir, - vtkm_inc_dir + "/vtkm/thirdparty/diy/vtkmdiy/include", - vtkm_inc_dir + "/vtkm/thirdparty/lcl/vtkmlcl", - ] + (options.use_vtkm == "1.5") * [ - vtkm_inc_dir + "/vtkm/thirdparty/diy", - vtkm_inc_dir + "/vtkm/thirdparty/taotuple", - ] - libs += [ - f"vtkm_cont-{options.use_vtkm}", - f"vtkm_filter-{options.use_vtkm}" if options.use_vtkm == "1.5" else - f"vtkm_filter_contour-{options.use_vtkm}", - ] - -if options.vmd_plugins: - libs += [ - "netcdf", - ] - -if options.openvr: - libs += [ - "openvr_api", - ] - -if True: - try: - import numpy - inc_dirs += [ - numpy.get_include(), - ] - def_macros += [ - ("_PYMOL_NUMPY", None), - ] - except ImportError: - print("numpy not available") - -if True: - for prefix in prefix_path: - for dirs, suffixes in [ - [inc_dirs, [("include",), ("include", "freetype2"), - ("include", "libxml2"), ("include", "openvr")]], - [lib_dirs, [("lib64",), ("lib",)]], - ]: - dirs.extend( - filter(os.path.isdir, [os.path.join(prefix, *s) for s in suffixes])) - -if True: - # optimization currently causes a clang segfault on OS X 10.9 when - # compiling layer2/RepCylBond.cpp - if sys.platform == 'darwin': - ext_comp_args += ["-fno-strict-aliasing"] - - -def get_pymol_version(): - return re.findall(r'_PyMOL_VERSION "(.*)"', open('layer0/Version.h').read())[0] - - -def get_sources(subdirs, suffixes=('.c', '.cpp')): - return sorted([f for d in subdirs for s in suffixes for f in glob.glob(d + '/*' + s)]) - - -def get_packages(base, parent='', r=None): - from os.path import join, exists - if r is None: - r = [] - if parent: - r.append(parent) - for name in os.listdir(join(base, parent)): - if '.' not in name and exists(join(base, parent, name, '__init__.py')): - get_packages(base, join(parent, name), r) - return r - - -package_dir = dict((x, os.path.join(base, x)) - for base in ['modules'] - for x in get_packages(base)) - -# Python includes -inc_dirs.append(sysconfig.get_paths()['include']) -inc_dirs.append(sysconfig.get_paths()['platinclude']) - -champ_inc_dirs = ['contrib/champ'] -champ_inc_dirs.append(sysconfig.get_paths()['include']) -champ_inc_dirs.append(sysconfig.get_paths()['platinclude']) - -if WIN: - # pyconfig.py forces linking against pythonXY.lib on MSVC - py_lib = pathlib.Path(sysconfig.get_paths()['stdlib']).parent / 'libs' - lib_dirs.append(str(py_lib)) - -ext_modules += [ - CMakeExtension( - name="pymol._cmd", - sources=get_sources(pymol_src_dirs), - include_dirs=inc_dirs, - libraries=libs, - library_dirs=lib_dirs, - define_macros=def_macros, - extra_link_args=ext_link_args, - extra_compile_args=ext_comp_args, - ), - - CMakeExtension( - name="chempy.champ._champ", - sources=get_sources(['contrib/champ']), - include_dirs=champ_inc_dirs, - library_dirs=lib_dirs, - ), -] - -distribution = setup( # Distribution meta-data - cmdclass={ - 'build_ext': build_ext_pymol, - 'build_py': build_py_pymol, - 'install': install_pymol, - }, - name="pymol", - version=get_pymol_version(), - author="Schrodinger", - url="http://pymol.org", - contact="pymol-users@lists.sourceforge.net", - description=("PyMOL is a Python-enhanced molecular graphics tool. " - "It excels at 3D visualization of proteins, small molecules, density, " - "surfaces, and trajectories. It also includes molecular editing, " - "ray tracing, and movies. Open Source PyMOL is free to everyone!"), - - package_dir=package_dir, - packages=list(package_dir), - package_data={'pmg_qt': ['forms/*.ui']}, - - ext_modules=ext_modules, - data_files=data_files, -)