From 458611e8c4e5f8daa29e2903744770c81ceb2ecb Mon Sep 17 00:00:00 2001 From: "Leonardo de Oliveira Martins (QIB)" Date: Mon, 20 Jul 2020 23:08:16 +0100 Subject: [PATCH] pip now installs successfully --- .gitignore | 3 +-- README.md | 52 ++++++++++++++++++++++----------------------- clean_dist.sh | 2 +- setup.py | 33 ++++++++++------------------ src/tauari_module.c | 2 +- tauari/__init__.py | 1 + tauari/tauari.py | 9 +++++--- 7 files changed, 47 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 457b28e..7c16387 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -/biomcmc-lib -/build +/build/* ## suggested by github # Byte-compiled / optimized / DLL files diff --git a/README.md b/README.md index ed8b72d..72196c6 100644 --- a/README.md +++ b/README.md @@ -10,54 +10,54 @@ It will contain python bindings for the low-level [biomcmc-lib](https://github.c phylogenetic library in C. Very beta at the moment. Empty, to be precise. - **tauari** is the name of an endangered Brazilian timber tree. Tree → towa-ree → tauari. +### Dependencies + +* python development package (with the API python/C library). Installed with your python conda installation or as `python-dev` from linux. +* `automake`, the `check` unit test framework, and `zlib` are required for installing the lowlevel `biomcmc-lib`. +* python > 3.6 and a C compiler, e.g. `gcc` +* The lowlevel phylogenetic library [biomcmc-lib](https://github.com/quadram-institute-bioscience/biomcmc-lib), which should be included here +(it will be compiled as well). +For a more up-to-date list you may need to check the conda/docker files once they are complete. + # Installation Make sure you clone this repository recursively: ``` git clone --recursive https://github.com/leomrtns/tauari.git ``` -Right now I am testing two ways of installing it, I'll probably use the second one (autotools). -Needless to say the instructions are incomplete at this point. - -### Dependencies -* development package with the API python/C library, which is installed with your python conda installation or as `python-dev` from linux. -* `automake`, the `check` unit test framework, and `zlib` are required for installing the lowlevel `biomcmc-lib`. -* python > 3.6 and a C compiler, e.g. `gcc` -* The lowlevel phylogenetic library [biomcmc-lib](https://github.com/quadram-institute-bioscience/biomcmc-lib), which is installed together - -## installation using `pip` - -You can create a conda environment +**tl;dr:** You can create a conda environment (or not) and then run `pip install .` ```bash conda update -n base -c defaults conda # probably not needed, but some machines complained about it conda env create -f environment.yml conda activate tauari pip install . -## since this software is under development, these two commands are also quite useful: +## since this software is under development, I find these two commands quite useful: conda env update -f environment.yml # updat conda evironment after changing dependencies pip install -e . # installs in development mode (modifications to python files are live) python setup.py develop # same as above, but more verbose and overwriting ./build_setup directory ``` -However this method assumes that `biomcmc-lib` is installed globally, which is not its original or main purpose (to be -an auxiliary, lowlevel library). -I won't write the details here because I'll probably abandon this approach. - ## autotools-based installation -This will probably be the default approach once this software becomes useful, since it compiles the lowlevel -`biomcmc-lib` together with the C components of *tauari* and generates a dynamic library. -It still needs `setuptools` to install the python components. - -`autotools` can find the shared library installation path relative to the environment root (e.g. `conda info --base` when installing -locally or `/` if installing it system-wide). -Or it can install a regular libotool library (the difference is `pyexec_LTLIBRARIES` or `lib_`) -I plan to also generate a pre-install step in `setup.py` that runs autotools if library is absent. + +Originally `biomcmc-lib` is an auxiliary, lowlevel library, and as such should not be directly exposed to the user or +shared system-wide (you can do it, btw, but it's intended as a "subdir" for autotools). +Therefore **tauari** compiles `biomcmc-lib` together with its C components, generating a dynamic library. +Just like [setuptools.Extension](https://docs.python.org/3/extending/building.html), but using autotools. +It still needs `setuptools` to install the python components and move the library to the correct location. + +Calling `pip install .` (or `python setup.py install`) will run autotools in the background, but if you want you can run it by hand: +```bash +cd build_setup +../configure --prefix="." +make && make install +ls lib/ +``` +The file "tauari_c.so" can be imported in python. # License SPDX-License-Identifier: GPL-3.0-or-later diff --git a/clean_dist.sh b/clean_dist.sh index 983a0d7..623ac0f 100755 --- a/clean_dist.sh +++ b/clean_dist.sh @@ -1,6 +1,6 @@ #!/bin/sh rm -f build_setup/config.log build_setup/config.status build_setup/libtool build_setup/Makefile -rm -rf build_setup/lib build_setup/include +rm -rf build_setup/lib build_setup/include build_setup/src build_setup/build_setup rm -rf build_setup/lib.* build_setup/temp.* rm -rf build_setup/tests rm -rf tauari.egg-info diff --git a/setup.py b/setup.py index 194c275..864ef9d 100644 --- a/setup.py +++ b/setup.py @@ -21,22 +21,10 @@ readme_file = base_dir/"README.md" build_path = f"{base_dir}/build_setup" biomcmc_path = f"{build_path}/biomcmc-lib" -source_files = ["tauari_module.c"] -source_files = [f"src/{x}" for x in source_files] # Eval the version file to get __version__; avoids importing our own package with readme_file.open(encoding = "utf-8") as f: long_description = f.read() -module_c = setuptools.Extension('_tauari_c', - include_dirs = ["build_setup/include/biomcmc"], - library_dirs = ["build_setup/lib"], - runtime_library_dirs = ["build_setup/lib"], - libraries = ['biomcmc'], # dynamic libraries only - undef_macros = [ "NDEBUG" ], - extra_objects = ["build_setup/lib/libbiomcmc.so", "build_setup/lib/libbiomcmc.a"], # redundant with 'libraries' tbh - #extra_compile_args = ["-Bstatic -lbiomcmc -Wl"], - sources = source_files) - if not os.path.exists(biomcmc_path): # developers can have their own links (without submodule) source = f"{base_dir}/submodules/biomcmc-lib/" if not os.path.exists(source): @@ -44,10 +32,12 @@ print (f"Tauari:: Creating a link '{biomcmc_path}' pointing to '{source}'") os.symlink(source, biomcmc_path) -def biomc2_compilation (options = ""): - autoconf_path = f"{biomcmc_path}/configure" - subprocess.call(f"{autoconf_path} --prefix={build_path} {options}".split(), cwd=build_path) # --program-prefix=PREFIX - subprocess.call(f"make install".split(), cwd=build_path) # libbiomcmc.a will be installed in {build_path} +def biomc2_compilation (options = ""): + if not os.path.isfile(f"{build_path}/lib/tauari_c.so"): + subprocess.call(f"../configure --prefix={build_path} {options}".split(), cwd=build_path) # --program-prefix=PREFIX + subprocess.call(f"make".split(), cwd=build_path) + subprocess.call(f"make install".split(), cwd=build_path) # tauari_c.so* will be installed in {build_path} + class PrePostDevelopCompile(setuptools.command.develop.develop): """pre- and post-compilation for development mode (only pre- currently)""" def run(self): @@ -78,9 +68,8 @@ def run(self): "Source": "https://github.com/quadram-institute-bioscience", }, packages = setuptools.find_packages(), - #include_package_data=True, - package_dir = {'tauari':"build_setup/lib"}, ## copy to root (site-packages) - package_data = {'': ["libbiomcmc.so*"]}, # , "build_setup/include/*", "build_setup/include/biomcmc/*"]}, # relative paths to setup.py only +# package_dir = {'tauari':"build_setup/lib"}, # copy to site-packages/tauari + package_data = {'tauari': ["build_setup/lib/tauari_c.so*"]}, # relative paths to setup.py only data_files = [("", ["LICENSE"])], python_requires = '>={}'.format('.'.join(str(n) for n in min_version)), license='GPLv3+', @@ -97,11 +86,11 @@ def run(self): "Programming Language :: Python :: 3.8", ], # Install a "tauari" program which calls tauari.__main__.main() - #entry_points = { "console_scripts": ["tauari = tauari.tauari:main"]}, + # entry_points = { "console_scripts": ["tauari = tauari.tauari:main"]}, + # ext_modules = [module_c], cmdclass={ 'develop': PrePostDevelopCompile, 'install': PrePostInstallCompile, 'egg_info': PrePostEggInfoCompile, - }, - ext_modules = [module_c] + } ) diff --git a/src/tauari_module.c b/src/tauari_module.c index 8444565..6553162 100644 --- a/src/tauari_module.c +++ b/src/tauari_module.c @@ -52,7 +52,7 @@ PyInit_tauari_c (void) /* it has to be named PyInit_ */ m = PyModule_Create(&tauarimodule); if (m == NULL) return NULL; - TauariError = PyErr_NewException("_tauari_c.error", NULL, NULL); + TauariError = PyErr_NewException("tauari_c.error", NULL, NULL); Py_INCREF(TauariError); PyModule_AddObject(m, "error", TauariError); return m; diff --git a/tauari/__init__.py b/tauari/__init__.py index b8023d8..0775c7b 100644 --- a/tauari/__init__.py +++ b/tauari/__init__.py @@ -1 +1,2 @@ +from .tauari import * __version__ = '0.0.1' diff --git a/tauari/tauari.py b/tauari/tauari.py index b446f5c..c3cd1bd 100644 --- a/tauari/tauari.py +++ b/tauari/tauari.py @@ -1,7 +1,10 @@ -import _tauari_c +try: + import tauari_c +except: + print ("Tauari:: could not load C library 'tauari_c', maybe it's not compiled yet") def tauaritest(s1 = None, s2 = None): - print(_tauari_c.testfunction(s1, s2)) + print(tauari_c.testfunction(s1, s2)) def tauaritest2(): - print(_tauari_c.test2()) + print(tauari_c.test2())