]> granicus.if.org Git - liblinear/blob - python/setup.py
updated setup.py for license
[liblinear] / python / setup.py
1 #!/usr/bin/env python
2
3 import sys, os
4 from os import path
5 from shutil import copyfile, rmtree
6 from glob import glob
7
8 from setuptools import setup, Extension
9 from distutils.command.clean import clean as clean_cmd
10
11 # a technique to build a shared library on windows
12 from distutils.command.build_ext import build_ext
13
14 build_ext.get_export_symbols = lambda x, y: []
15
16
17 PACKAGE_DIR = "liblinear"
18 PACKAGE_NAME = "liblinear-official"
19 VERSION = "2.45.0"
20 cpp_dir = "cpp-source"
21 # should be consistent with dynamic_lib_name in liblinear/liblinear.py
22 dynamic_lib_name = "clib"
23
24 # sources to be included to build the shared library
25 source_codes = [
26     path.join("blas", "daxpy.c"),
27     path.join("blas", "ddot.c"),
28     path.join("blas", "dnrm2.c"),
29     path.join("blas", "dscal.c"),
30     "linear.cpp",
31     "newton.cpp",
32 ]
33 headers = [
34     path.join("blas", "blas.h"),
35     path.join("blas", "blasp.h"),
36     "newton.h",
37     "linear.h",
38     "linear.def",
39 ]
40
41 # license parameters
42 license_source = path.join("..", "COPYRIGHT")
43 license_file = "LICENSE"
44 license_name = "BSD-3-Clause"
45
46 kwargs_for_extension = {
47     "sources": [path.join(cpp_dir, f) for f in source_codes],
48     "depends": [path.join(cpp_dir, f) for f in headers],
49     "include_dirs": [cpp_dir],
50     "language": "c++",
51 }
52
53 # see ../Makefile.win
54 if sys.platform == "win32":
55     kwargs_for_extension.update(
56         {
57             "define_macros": [("_WIN64", ""), ("_CRT_SECURE_NO_DEPRECATE", "")],
58             "extra_link_args": ["-DEF:{}\linear.def".format(cpp_dir)],
59         }
60     )
61
62
63 def create_cpp_source():
64     for f in source_codes + headers:
65         src_file = path.join("..", f)
66         tgt_file = path.join(cpp_dir, f)
67         # ensure blas directory is created
68         os.makedirs(path.dirname(tgt_file), exist_ok=True)
69         copyfile(src_file, tgt_file)
70
71
72 class CleanCommand(clean_cmd):
73     def run(self):
74         clean_cmd.run(self)
75         to_be_removed = ["build/", "dist/", "MANIFEST", cpp_dir, "{}.egg-info".format(PACKAGE_NAME), license_file]
76         to_be_removed += glob("./{}/{}.*".format(PACKAGE_DIR, dynamic_lib_name))
77         for root, dirs, files in os.walk(os.curdir, topdown=False):
78             if "__pycache__" in dirs:
79                 to_be_removed.append(path.join(root, "__pycache__"))
80             to_be_removed += [f for f in files if f.endswith(".pyc")]
81
82         for f in to_be_removed:
83             print("remove {}".format(f))
84             if f == ".":
85                 continue
86             elif path.isfile(f):
87                 os.remove(f)
88             elif path.isdir(f):
89                 rmtree(f)
90
91 def main():
92     if not path.exists(cpp_dir):
93         create_cpp_source()
94
95     if not path.exists(license_file):
96         copyfile(license_source, license_file)
97
98     with open("README") as f:
99         long_description = f.read()
100
101     setup(
102         name=PACKAGE_NAME,
103         packages=[PACKAGE_DIR],
104         version=VERSION,
105         description="Python binding of LIBLINEAR",
106         long_description=long_description,
107         long_description_content_type="text/plain",
108         author="ML group @ National Taiwan University",
109         author_email="cjlin@csie.ntu.edu.tw",
110         url="https://www.csie.ntu.edu.tw/~cjlin/liblinear",
111         license=license_name,
112         install_requires=["scipy"],
113         ext_modules=[
114             Extension(
115                 "{}.{}".format(PACKAGE_DIR, dynamic_lib_name), **kwargs_for_extension
116             )
117         ],
118         cmdclass={"clean": CleanCommand},
119     )
120
121
122 main()
123