From 575c45d5c02598d178f3d06f55ccb4c593906622 Mon Sep 17 00:00:00 2001 From: Nezar Abdennur Date: Sun, 12 Mar 2023 00:35:10 -0500 Subject: [PATCH] Re-incorporate libkent into package build process --- MANIFEST.in | 10 +++--- Makefile | 12 +++----- pyproject.toml | 22 +++---------- setup.py | 84 ++++++++++++++++++++++++++++++++++++-------------- src/makefile | 14 ++++++--- 5 files changed, 85 insertions(+), 57 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index ebc6036..25e48dd 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,13 +1,13 @@ include LICENSE include README.md include Makefile -graft tests -graft include +include bbi/cbbi.pyx +include bbi/cbbi.pxd graft src +graft include +graft tests -global-include *.pyx -global-include *.pxd - +recursive-exclude venv * global-exclude __pycache__/* global-exclude *.o global-exclude *.a diff --git a/Makefile b/Makefile index 55b9f11..5c74e0d 100644 --- a/Makefile +++ b/Makefile @@ -5,26 +5,24 @@ UNAME_S := $(shell uname -s) ifeq (${MACHTYPE},) MACHTYPE:=$(shell uname -m) -# $(info MACHTYPE was empty, set to: ${MACHTYPE}) -endif -ifneq (,$(findstring -,$(MACHTYPE))) -# $(info MACHTYPE has - sign ${MACHTYPE}) - MACHTYPE:=$(shell uname -m) -# $(info MACHTYPE has - sign set to: ${MACHTYPE}) endif export MACHTYPE export CC ?= gcc export COPTS=-g -pthread -fPIC -static export CFLAGS=-Wall $(shell pkg-config --static --cflags-only-other openssl zlib libpng) +export DEFS=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -DMACHTYPE_${MACHTYPE} -DUSE_SSL export LDFLAGS=-L${current_dir}/src/${MACHTYPE} $(shell pkg-config --static --libs openssl zlib libpng) export INC=-I${current_dir}/include $(shell pkg-config --static --cflags-only-I openssl zlib libpng) -export DEFS=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -DMACHTYPE_${MACHTYPE} -DUSE_SSL # pass through COREDUMP ifneq (${COREDUMP},) DEFS+=-DCOREDUMP endif +# Append values to CFLAGS and LDFLAGS +CFLAGS += $(shell echo $$CFLAGS) +LDFLAGS += $(shell echo $$LDFLAGS) + all: build diff --git a/pyproject.toml b/pyproject.toml index c49682a..ad0585b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,27 +71,15 @@ repository = "https://github.com/nvictus/pybbi" [tool.cibuildwheel] build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*"] skip = "*-musllinux*" - +build-verbosity = 3 [tool.cibuildwheel.linux] archs = ["x86_64", "aarch64"] before-all = "yum install -y gcc make zlib-devel openssl-devel libpng-devel" -before-build = "make build-ucsc" - -[tools.cibuildwheel.linux.environment] -LDFLAGS = "-Wl,--no-as-needed" [tool.cibuildwheel.macos] -archs = ["x86_64"] -before-all = "brew install pkg-config openssl libpng" -before-build = "make build-ucsc" - -[tool.cibuildwheel.macos.environment] -LDFLAGS = "-L/usr/local/opt/openssl/lib -L/opt/homebrew/opt/openssl/lib" -CPPFLAGS = "-I/usr/local/opt/openssl/include -I/opt/homebrew/opt/openssl/include" -PATH = "/usr/local/opt/openssl/bin:/opt/homebrew/opt/openssl/bin:$PATH" -PKG_CONFIG_PATH = "/usr/local/opt/openssl/lib/pkgconfig:/opt/homebrew/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" -C_INCLUDE_PATH = "/usr/local/include/libpng:/usr/local/opt/openssl/include:$C_INCLUDE_PATH" -BLDSHARED = 'gcc -bundle -undefined dynamic_lookup -arch x86_64 -g' -LDSHARED = 'gcc -bundle -undefined dynamic_lookup -arch x86_64 -g' +archs = ["x86_64"] # "arm64" is not yet supported by GitHub Actions (Needs M1 runner) +before-all = """ +brew install pkg-config openssl libpng # -> /usr/local (x86_64) +""" diff --git a/setup.py b/setup.py index 7e1ba7b..2b847fb 100644 --- a/setup.py +++ b/setup.py @@ -1,29 +1,71 @@ import os -import os.path import pathlib +import subprocess import sys -import numpy -import pkgconfig -from Cython.Build import cythonize -from Cython.Distutils.build_ext import new_build_ext as cython_build_ext from setuptools import Extension, setup -ARCH = os.uname().machine +# Determine architecture for build; defaults to machine architecture. +# cibuildwheel sets ARCHFLAGS on macos runners +# user can also set ARCH to override +MACHINE_ARCH = os.uname().machine +if sys.platform == "darwin" and "ARCHFLAGS" in os.environ: + ARCH = os.environ["ARCHFLAGS"].split()[-1] +elif "ARCH" in os.environ: + ARCH = os.environ["ARCH"] +else: + ARCH = MACHINE_ARCH -deps = {} -if "sdist" not in sys.argv: + +if "sdist" in sys.argv: + # Skip compilation when building a source distribution + setup() + +else: + import numpy + import pkgconfig + from Cython.Build import cythonize + from Cython.Distutils.build_ext import new_build_ext as cython_build_ext + + # 1. Compile the UCSC library (libkent.a) + # Pass the target architecture to the makefile + os.environ["MACHTYPE"] = ARCH + + # Platform and architecture-specific flags + if sys.platform == "darwin": + brew_optdir = None + if ARCH.startswith("arm"): + brew_optdir = "/opt/homebrew/opt" + else: + brew_optdir = "/usr/local/opt" + os.environ["CFLAGS"] = f"-arch {ARCH}" + if brew_optdir is not None: + os.environ["LDFLAGS"] = f"-L{brew_optdir}/openssl/lib {os.environ.get('LDFLAGS', '')}" + os.environ["C_INCLUDE_PATH"] = f"{brew_optdir}/openssl/include:{brew_optdir}/libpng/include:{os.environ.get('C_INCLUDE_PATH', '')}" + os.environ["PKG_CONFIG_PATH"] = f"{brew_optdir}/openssl/lib/pkgconfig:{os.environ.get('PKG_CONFIG_PATH', '')}" + + # Parse pkg-config dependencies + # This will let us know if something is missing deps = pkgconfig.parse("zlib openssl libpng") + # Build the UCSC library if not pathlib.Path("src", ARCH, "libkent.a").exists(): - raise RuntimeError( - f"src/{ARCH}/libkent.a not found. " - "Please run `make build-ucsc`." - ) + subprocess.run(["make", "clean-ucsc"]) + ret = subprocess.run(["make", "build-ucsc"], check=True) + if ret.returncode != 0: + raise RuntimeError("Failed to build UCSC library.") -def get_extension_modules(): - ext_modules = [ + # 2. Compile cython extension module, link to libkent and other dependencies + # Platform and architecture-specific linker flags + if sys.platform == "darwin": + os.environ["BLDSHARED"] = f'gcc -bundle -undefined dynamic_lookup -arch {ARCH} -g' + os.environ["LDSHARED"] = f'gcc -bundle -undefined dynamic_lookup -arch {ARCH} -g' + elif sys.platform == "linux": + os.environ["LDFLAGS"] = f"-Wl,--no-as-needed {os.environ.get('LDFLAGS', '')}" + + # Configure and cythonize pyx to C extension module + ext_modules = cythonize([ Extension( name="bbi.cbbi", sources=[os.path.join("bbi", "cbbi.pyx")], @@ -39,14 +81,10 @@ def get_extension_modules(): + deps.pop("include_dirs", []), **deps, ), - ] - if "sdist" in sys.argv: - return ext_modules - else: - return cythonize(ext_modules) + ]) -setup( - ext_modules=get_extension_modules(), - build_ext=cython_build_ext, -) + setup( + ext_modules=ext_modules, + build_ext=cython_build_ext, + ) diff --git a/src/makefile b/src/makefile index e57a9e3..1513e94 100644 --- a/src/makefile +++ b/src/makefile @@ -54,17 +54,21 @@ $(MACHTYPE)/libkent.a: $(O) $(MACHTYPE) $(MACHTYPE): mkdir $(MACHTYPE) +.PHONY: all +all: $(MACHTYPE)/libkent.a + +%.o: %.c + ${CC} ${COPTS} ${CFLAGS} ${DEFS} ${LDFLAGS} ${INC} -o $@ -c $< + +.PHONY: test test: cd tests && ${MAKE} test +.PHONY: clean clean: rm -f ${O} $(MACHTYPE)/libkent.a cd tests && ${MAKE} clean +.PHONY: tags tags: etags ../inc/*.h ../lib/*.h ../lib/*.c ../hg/inc/*.h ../hg/lib/*.h ../hg/lib/*.c ../hg/hgTracks/*.c ../hg/hgc/*.c ../hg/hgTrackUi/*.c - -%.o: %.c - ${CC} ${COPTS} ${CFLAGS} ${DEFS} ${LDFLAGS} ${INC} -o $@ -c $< - -all: $(MACHTYPE)/libkent.a \ No newline at end of file