Migrated Python pkg mgmt to Poetry

This commit is contained in:
Boston Walker
2021-12-31 10:31:35 -05:00
parent 13740f9767
commit 894e52ab6c
9 changed files with 204 additions and 19218 deletions

142
pkg/pypi/build.py Normal file
View File

@@ -0,0 +1,142 @@
"""
Poetry build.py
See: https://stackoverflow.com/questions/60073711/how-to-build-c-extensions-via-poetry
"""
import os
import shutil
import subprocess
from distutils.command.build_ext import build_ext
from distutils.errors import DistutilsPlatformError, CCompilerError, DistutilsExecError
from distutils.extension import Extension
from glob import glob
DIR = os.path.dirname(os.path.realpath(__file__))
ROOT_DIR = os.path.abspath(os.path.join(DIR, "..", ".."))
INCLUDE_DIRS = [
os.path.join(ROOT_DIR, "include"),
os.path.join(ROOT_DIR, "src"),
os.path.join(ROOT_DIR, "src/bindings/python"),
os.path.join(ROOT_DIR, "ext/concurrentqueue"),
os.path.join(ROOT_DIR, "ext/lwip/src/include"),
os.path.join(ROOT_DIR, "ext/lwip-contrib/ports/unix/port/include"),
os.path.join(ROOT_DIR, "ext/ZeroTierOne/include"),
os.path.join(ROOT_DIR, "ext/ZeroTierOne"),
os.path.join(ROOT_DIR, "ext/ZeroTierOne/node"),
os.path.join(ROOT_DIR, "ext/ZeroTierOne/service"),
os.path.join(ROOT_DIR, "ext/ZeroTierOne/osdep"),
os.path.join(ROOT_DIR, "ext/ZeroTierOne/controller"),
]
class LibztModule(Extension):
"""Libzt extension module"""
def __init__(self):
sources = [
*glob(os.path.join(ROOT_DIR, "src/bindings/python/*.cxx")),
*glob(os.path.join(ROOT_DIR, "src/bindings/python/zt.i")),
*glob(os.path.join(ROOT_DIR, "src/*.cpp")),
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/node/*.cpp")),
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/osdep/OSUtils.cpp")),
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/osdep/PortMapper.cpp")),
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/osdep/ManagedRoute.cpp")),
]
# noinspection PyUnresolvedReferences
assert len(sources) > 0, "no sources found"
# noinspection PyTypeChecker
super().__init__(
"libzt._libzt",
sources=sources,
include_dirs=INCLUDE_DIRS,
extra_compile_args=[
"-std=c++11",
"-DZTS_ENABLE_PYTHON=1",
"-DZT_SDK",
"-Wno-parentheses-equality",
"-Wno-macro-redefined",
"-Wno-tautological-overlap-compare",
"-Wno-tautological-constant-out-of-range-compare",
],
swig_opts=[
"-c++",
f"-I{os.path.join(ROOT_DIR, 'include')}",
],
)
def cstuff():
"""C library"""
sources = [
# libnatpmp
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/ext/libnatpmp/natpmp.c")),
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/ext/libnatpmp/wingettimeofday.c")),
*glob(os.path.join(ROOT_DIR, "ext/ZeroTierOne/ext/libnatpmp/getgateway.c")),
# miniupnpc
*glob(os.path.join(ROOT_DIR, "ext/miniupnpc/*.c")),
# lwip
*glob(os.path.join(ROOT_DIR, "ext/lwip/src/netif/*.c")),
*glob(os.path.join(ROOT_DIR, "ext/lwip/src/api/*.c")),
*glob(os.path.join(ROOT_DIR, "ext/lwip/src/core/*.c")),
*glob(os.path.join(ROOT_DIR, "ext/lwip/src/core/ipv4/*.c")),
*glob(os.path.join(ROOT_DIR, "ext/lwip/src/core/ipv6/*.c")),
*glob(os.path.join(ROOT_DIR, "ext/lwip/src/netif/*.c")),
*glob(os.path.join(ROOT_DIR, "ext/lwip-contrib/ports/unix/port/sys_arch.c")),
]
# noinspection PyUnresolvedReferences
assert len(sources) > 0, "no sources"
return ("cstuff", {
"sources": sources,
"include_dirs": INCLUDE_DIRS,
})
class BuildFailed(Exception):
pass
class ExtBuilder(build_ext):
def run(self):
try:
build_ext.run(self)
except (DistutilsPlatformError, FileNotFoundError):
raise BuildFailed('File not found. Could not compile C extension.')
def build_extension(self, ext):
try:
build_ext.build_extension(self, ext)
except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError):
raise BuildFailed('Could not compile C extension.')
def build(setup_kwargs):
"""Build """
assert os.getcwd() == DIR, f"must be invoked from {DIR}"
# Ensure git submodules are loaded
subprocess.run(["git", "submodule", "update", "--init"])
# Copy Python files into packaging directory
src_dir = os.path.join(ROOT_DIR, "src", "bindings", "python")
dst_dir = os.path.join(DIR, "libzt")
for filename in os.listdir(src_dir):
if os.path.isfile(os.path.join(src_dir, filename)) and filename.endswith(".py"):
shutil.copy(os.path.join(src_dir, filename), os.path.join(dst_dir, filename))
# LICENSE file
shutil.copy(os.path.join(ROOT_DIR, "LICENSE.txt"), os.path.join(DIR, "LICENSE"))
# Pass up extensions information
setup_kwargs["libraries"] = [cstuff()]
setup_kwargs["ext_modules"] = [LibztModule()]
setup_kwargs["cmdclass"] = {"build_ext": ExtBuilder}

View File

@@ -1,39 +0,0 @@
#!/bin/bash
PYBIN=python3
# Build the extension module
ext()
{
# Symbolic link to source tree so that sdist structure makes sense
ln -s ../../ native
# Re-build wrapper to export C symbols
swig -c++ -python -o native/src/bindings/python/zt_wrap.cxx -I./native/include native/src/bindings/python/zt.i
# Copy language bindings into module directory
cp -f native/src/bindings/python/*.py libzt/
cp -f native/LICENSE.txt LICENSE
# Build C libraries (and then) C++ extension
$PYBIN setup.py build_clib --verbose build_ext -i --verbose
}
# Build a wheel
wheel()
{
ext
$PYBIN setup.py bdist_wheel
}
clean()
{
find . -name '*.so' -type f -delete
find . -name '*.pyc' -type f -delete
find . -name '__pycache__' -type d -delete
rm -rf libzt/sockets.py
rm -rf libzt/libzt.py
rm -rf libzt/node.py
rm -rf src ext build dist native
rm -rf libzt.egg-info
rm -rf LICENSE
}
"$@"

View File

@@ -1 +1,2 @@
__version__ = "1.8.4" import pkg_resources
__version__ = pkg_resources.get_distribution("libzt").version

60
pkg/pypi/pyproject.toml Normal file
View File

@@ -0,0 +1,60 @@
[tool.poetry]
name = "libzt"
version = "1.8.4"
description = "ZeroTier"
authors = ["ZeroTier, Inc."]
license = "BUSL 1.1"
readme = "README.md"
homepage = "https://www.zerotier.com/"
repository = "https://github.com/zerotier/libzt/"
documentation = "https://docs.zerotier.com/"
keywords = [
"zerotier",
"p2p",
"peer-to-peer",
"sdwan",
"sdn",
"virtual",
"network",
"socket",
"tcp",
"udp",
"zt",
"encryption",
"encrypted",
]
classifiers = [
"Topic :: Internet",
"Topic :: System :: Networking",
"Topic :: Security :: Cryptography",
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Intended Audience :: System Administrators",
"Intended Audience :: Telecommunications Industry",
"Intended Audience :: End Users/Desktop",
"License :: Free for non-commercial use",
"Operating System :: MacOS",
"Operating System :: POSIX :: BSD",
"Operating System :: POSIX :: Linux",
"Operating System :: Unix",
"Programming Language :: C",
"Programming Language :: Python",
"Programming Language :: C++",
]
packages = [
{ include = "libzt" },
]
build = "build.py"
[tool.poetry.dependencies]
python = "^3.5"
[tool.poetry.dev-dependencies]
[tool.poetry.urls]
"GitHub" = "https://github.com/zerotier/libzt/"
"Issue Tracker" = "https://github.com/zerotier/libzt/issues"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

View File

@@ -1,6 +0,0 @@
[metadata]
version = attr: libzt.__version__
description_file = README.md
license_files =
native/LICENSE.txt
native/ext/THIRDPARTY.txt

View File

@@ -1,133 +0,0 @@
#!/usr/bin/env python
from setuptools import setup, Extension, Command, Distribution
from distutils.util import convert_path
import glob
import os
main_ns = {}
ver_path = convert_path('libzt/version.py')
with open(ver_path) as ver_file:
exec(ver_file.read(), main_ns)
from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
class BinaryDistribution(Distribution):
def is_pure(self):
return False
# monkey-patch for parallel compilation
# Copied from: https://stackoverflow.com/a/13176803
def parallelCCompile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None):
# those lines are copied from distutils.ccompiler.CCompiler directly
macros, objects, extra_postargs, pp_opts, build = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs)
cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
# parallel code
N=16 # number of parallel compilations
import multiprocessing.pool
def _single_compile(obj):
try: src, ext = build[obj]
except KeyError: return
self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
# convert to list, imap is evaluated on-demand
list(multiprocessing.pool.ThreadPool(N).imap(_single_compile,objects))
return objects
import distutils.ccompiler
distutils.ccompiler.CCompiler.compile=parallelCCompile
# Build
cpp_glob = []
c_glob = []
# Windows
if os.name == 'nt':
print('TODO')
#extra_compile_args=['/std:c++14', '-DNOMINMAX=1', '-DZT_SDK', '-DSDK'],
#extra_link_args=['/LIBPATH:.', 'WS2_32.Lib', 'ShLwApi.Lib', 'iphlpapi.Lib','lwip.lib'],
# Everything else
else:
cpp_glob.extend(list(glob.glob('native/src/bindings/python/*.cxx')))
cpp_glob.extend(list(glob.glob('native/src/*.cpp')))
cpp_glob.extend(list(glob.glob('native/ext/ZeroTierOne/node/*.cpp')))
cpp_glob.extend(list(glob.glob('native/ext/ZeroTierOne/osdep/OSUtils.cpp')))
cpp_glob.extend(list(glob.glob('native/ext/ZeroTierOne/osdep/PortMapper.cpp')))
cpp_glob.extend(list(glob.glob('native/ext/ZeroTierOne/osdep/ManagedRoute.cpp')))
my_include_dirs=['native/include',
'native/src',
'native/src/bindings/python',
'native/ext/concurrentqueue',
'native/ext/lwip/src/include',
'native/ext/lwip-contrib/ports/unix/port/include',
'native/ext/ZeroTierOne/include',
'native/ext/ZeroTierOne',
'native/ext/ZeroTierOne/node',
'native/ext/ZeroTierOne/service',
'native/ext/ZeroTierOne/osdep',
'native/ext/ZeroTierOne/controller']
libzt_module = Extension('libzt._libzt',
extra_compile_args=['-std=c++11', '-DZTS_ENABLE_PYTHON=1', '-DZT_SDK', '-Wno-parentheses-equality', '-Wno-macro-redefined', '-Wno-tautological-overlap-compare', '-Wno-tautological-constant-out-of-range-compare'],
sources=cpp_glob, include_dirs=my_include_dirs)
# Separate C library, this is needed since C++ compiler flags are applied
# to everything in the extension module regardless of type.
# libnatpmp
c_glob.extend(list(glob.glob('native/ext/ZeroTierOne/ext/libnatpmp/natpmp.c')))
c_glob.extend(list(glob.glob('native/ext/ZeroTierOne/ext/libnatpmp/wingettimeofday.c')))
c_glob.extend(list(glob.glob('native/ext/ZeroTierOne/ext/libnatpmp/getgateway.c')))
# miniupnpc
c_glob.extend(list(glob.glob('native/ext/miniupnpc/*.c')))
# lwip
c_glob.extend(list(glob.glob('native/ext/lwip/src/netif/*.c')))
c_glob.extend(list(glob.glob('native/ext/lwip/src/api/*.c')))
c_glob.extend(list(glob.glob('native/ext/lwip/src/core/*.c')))
c_glob.extend(list(glob.glob('native/ext/lwip/src/core/ipv4/*.c')))
c_glob.extend(list(glob.glob('native/ext/lwip/src/core/ipv6/*.c')))
c_glob.extend(list(glob.glob('native/ext/lwip/src/netif/*.c')))
c_glob.extend(list(glob.glob('native/ext/lwip-contrib/ports/unix/port/sys_arch.c')))
cstuff = ('cstuff', {'sources':
c_glob, 'include_dirs': my_include_dirs})
setup(
name = 'libzt',
version = main_ns['__version__'],
description = 'ZeroTier',
long_description=long_description,
long_description_content_type='text/markdown',
author = 'ZeroTier, Inc.',
author_email = 'joseph@zerotier.com',
url = 'https://github.com/zerotier/libzt',
license='BUSL 1.1',
download_url = 'https://github.com/zerotier/libzt/releases',
keywords = 'zerotier p2p peer-to-peer sdwan sdn virtual network socket tcp udp zt encryption encrypted',
py_modules = ['libzt'],
packages = ['libzt'],
classifiers = ['Topic :: Internet',
'Topic :: System :: Networking',
'Topic :: Security :: Cryptography',
'Intended Audience :: Developers',
'Intended Audience :: Information Technology',
'Intended Audience :: System Administrators',
'Intended Audience :: Telecommunications Industry',
'Intended Audience :: End Users/Desktop',
'License :: Free for non-commercial use',
'Operating System :: MacOS',
'Operating System :: POSIX :: BSD',
'Operating System :: POSIX :: Linux',
'Operating System :: Unix',
'Programming Language :: C',
'Programming Language :: C++',
'Programming Language :: Python'
],
distclass=BinaryDistribution,
libraries=[cstuff],
ext_modules = [libzt_module],
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,60 +0,0 @@
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
* Version 4.0.2
*
* This file is not intended to be easily readable and contains a number of
* coding conventions designed to improve portability and efficiency. Do not make
* changes to this file unless you know what you are doing--modify the SWIG
* interface file instead.
* ----------------------------------------------------------------------------- */
#ifndef SWIG_libzt_WRAP_H_
#define SWIG_libzt_WRAP_H_
#include <map>
#include <string>
class SwigDirector_PythonDirectorCallbackClass : public PythonDirectorCallbackClass, public Swig::Director {
public:
SwigDirector_PythonDirectorCallbackClass(PyObject *self);
virtual void on_zerotier_event(zts_event_msg_t *msg);
virtual ~SwigDirector_PythonDirectorCallbackClass();
/* Internal director utilities */
public:
bool swig_get_inner(const char *swig_protected_method_name) const {
std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);
return (iv != swig_inner.end() ? iv->second : false);
}
void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {
swig_inner[swig_protected_method_name] = swig_val;
}
private:
mutable std::map<std::string, bool> swig_inner;
#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
/* VTable implementation */
PyObject *swig_get_method(size_t method_index, const char *method_name) const {
PyObject *method = vtable[method_index];
if (!method) {
swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);
method = PyObject_GetAttr(swig_get_self(), name);
if (!method) {
std::string msg = "Method in class PythonDirectorCallbackClass doesn't exist, undefined ";
msg += method_name;
Swig::DirectorMethodException::raise(msg.c_str());
}
vtable[method_index] = method;
}
return method;
}
private:
mutable swig::SwigVar_PyObject vtable[1];
#endif
};
#endif