liba 0.1.0-rc2

An algorithm library based on C/C++ language
#!/usr/bin/env python
'''
 @file setup.py
 @brief Setup this algorithm library using Cython.
 @copyright Copyright (C) 2020-present tqfx, All rights reserved.
'''
from sys import argv, executable, version_info
from subprocess import Popen
import time
import os

script = os.path.abspath(argv[0])
os.chdir(os.path.dirname(script))
if len(argv) < 2:
    exit(Popen([executable, script, "build_ext", "--inplace"]).wait())
from setuptools.command.build_ext import build_ext
from setuptools import setup, Extension
from glob import glob
import re


class Build(build_ext):
    def build_extensions(self):
        if not self.compiler.compiler_type == "msvc":
            for e in self.extensions:
                if e.language == "c++":
                    e.extra_compile_args += ["-std=c++11"]
                elif e.language == "c":
                    e.extra_compile_args += ["-std=c11"]
        if self.compiler.compiler_type == "msvc":
            for e in self.extensions:
                if e.language == "c":
                    e.extra_compile_args += ["/std:c11"]
        if self.compiler.compiler_type == "mingw32":
            for e in self.extensions:
                e.extra_link_args += [
                    "-static-libgcc",
                    "-static-libstdc++",
                    "-Wl,-Bstatic,--whole-archive",
                    "-lwinpthread",
                    "-Wl,--no-whole-archive",
                ]
        super(Build, self).build_extensions()


try:
    from Cython.Build import cythonize

    USE_CYTHON = True
except:
    USE_CYTHON = False
if USE_CYTHON and os.path.exists("ffi/python/src/ac.pyx"):
    source_c = ["ffi/python/src/ac.pyx"]
else:
    source_c = ["ffi/python/src/ac.c"]
if USE_CYTHON and os.path.exists("ffi/python/src/ax.pyx"):
    source_cc = ["ffi/python/src/ax.pyx"]
else:
    source_cc = ["ffi/python/src/ax.cpp"]

with open("setup.cfg", "r") as f:
    version = re.findall(r"version = (.*)", f.read())[0]
major, minor, patch = version.split('.')[:3]
tweak = time.strftime("%Y%m%d%H%M")
text = '''/*!
 @file a.config.h
 @brief algorithm library configuration
 @details it is autogenerated by setup.py
 @copyright Copyright (C) 2020-present tqfx, All rights reserved.
*/

#ifndef __A_CONFIG_H__
#define __A_CONFIG_H__

#define A_VERSION_MAJOR {}
#define A_VERSION_MINOR {}
#define A_VERSION_PATCH {}
#define A_VERSION_TWEAK {}

/*! algorithm library version string */
#define A_VERSION "{}"

#endif /* __A_CONFIG_H__ */
'''.format(
    major, minor, patch, tweak, version
)
with open("include/a.config.h", "wb") as f:
    f.write(text.encode("UTF-8"))

header_h = []
header_hh = []
suffix_c = (".c",)
suffix_h = (".h",)
suffix_cc = (".cc", ".cpp", ".cxx")
suffix_hh = (".hh", ".hpp", ".hxx")
define_macros = [("A_EXPORTS", None)]

for source in glob("src/**"):
    if not os.path.isfile(source):
        continue
    prefix, suffix = os.path.splitext(source)
    if suffix in suffix_cc:
        source_cc.append(source)
    if suffix in suffix_c:
        source_c.append(source)
for header in glob("include/**"):
    if not os.path.isfile(header):
        continue
    prefix, suffix = os.path.splitext(header)
    if suffix in suffix_hh:
        header_hh.append(header)
    if suffix in suffix_h:
        header_h.append(header)

ext_modules = [
    Extension(
        name="libac",
        language="c",
        sources=source_c,
        include_dirs=["include"],
        define_macros=define_macros,
    ),
    Extension(
        name="libax",
        language="c++",
        sources=source_cc,
        include_dirs=["include"],
        define_macros=define_macros,
    ),
]

if USE_CYTHON:
    from Cython.Build import cythonize

    ext_modules = cythonize(
        ext_modules,
        language_level=version_info[0],
        annotate=True,
        quiet=True,
    )

setup(
    ext_modules=ext_modules,
    cmdclass={"build_ext": Build},
)