Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build configuration for MSVC #13

Merged
merged 8 commits into from Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yaml
Expand Up @@ -12,9 +12,10 @@ on:
jobs:
build:

runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: [3.7, 3.8, 3.9]

steps:
Expand Down
2 changes: 1 addition & 1 deletion lib/open_jtalk
103 changes: 99 additions & 4 deletions setup.py
@@ -1,7 +1,11 @@
import os
import subprocess
import sys
from distutils.errors import DistutilsExecError
from distutils.version import LooseVersion
from distutils.spawn import spawn
from glob import glob
from itertools import chain
from os.path import exists, join
from subprocess import run

Expand All @@ -10,6 +14,8 @@
import setuptools.command.develop
from setuptools import Extension, find_packages, setup

platform_is_windows = sys.platform == "win32"

version = "0.1.2"

min_cython_ver = "0.21.0"
Expand All @@ -21,6 +27,12 @@
except ImportError:
_CYTHON_INSTALLED = False


msvc_extra_compile_args_config = [
"/source-charset:utf-8",
"/execution-charset:utf-8",
]

try:
if not _CYTHON_INSTALLED:
raise ImportError("No supported version of Cython installed.")
Expand All @@ -32,13 +44,95 @@

if cython:
ext = ".pyx"
cmdclass = {"build_ext": build_ext}

def msvc_extra_compile_args(compile_args):
cas = set(compile_args)
xs = filter(lambda x: x not in cas, msvc_extra_compile_args_config)
return list(chain(compile_args, xs))

class custom_build_ext(build_ext):
def build_extensions(self):
compiler_type_is_msvc = self.compiler.compiler_type == "msvc"
for entry in self.extensions:
if compiler_type_is_msvc:
entry.extra_compile_args = msvc_extra_compile_args(
entry.extra_compile_args
if hasattr(entry, "extra_compile_args")
else []
)

build_ext.build_extensions(self)

r9y9 marked this conversation as resolved.
Show resolved Hide resolved
cmdclass = {"build_ext": custom_build_ext}
else:
ext = ".cpp"
cmdclass = {}
if not os.path.exists(join("pyopenjtalk", "openjtalk" + ext)):
raise RuntimeError("Cython is required to generate C++ code")


# Workaround for `distutils.spawn` problem on Windows python < 3.9
# See details: [bpo-39763: distutils.spawn now uses subprocess (GH-18743)]
# (https://github.com/python/cpython/commit/1ec63b62035e73111e204a0e03b83503e1c58f2e)
def test_quoted_arg_change():
child_script = """
import os
import sys
if len(sys.argv) > 5:
try:
os.makedirs(sys.argv[1], exist_ok=True)
with open(sys.argv[2], mode=sys.argv[3], encoding=sys.argv[4]) as fd:
fd.write(sys.argv[5])
r9y9 marked this conversation as resolved.
Show resolved Hide resolved
except OSError:
pass
"""

try:
# write
package_build_dir = "build"
file_name = join(package_build_dir, "quoted_arg_output")
output_mode = "w"
file_encoding = "utf8"
arg_value = '"ARG"'

spawn([
sys.executable,
"-c",
child_script,
package_build_dir,
file_name,
output_mode,
file_encoding,
arg_value
])
r9y9 marked this conversation as resolved.
Show resolved Hide resolved

# read
with open(file_name, mode="r", encoding=file_encoding) as fd:
return fd.readline() != arg_value
except (DistutilsExecError, TypeError):
return False


def escape_string_macro_arg(s):
return s.replace('\\', '\\\\').replace('"', '\\"')


def escape_macro_element(x):
(k, arg) = x
return (k, escape_string_macro_arg(arg)) if type(arg) == str else x


def escape_macros(macros):
return list(map(escape_macro_element, macros))


custom_define_macros = (
escape_macros
if platform_is_windows and test_quoted_arg_change()
else (lambda macros: macros)
)


# open_jtalk sources
src_top = join("lib", "open_jtalk", "src")

Expand Down Expand Up @@ -83,14 +177,14 @@
extra_compile_args=[],
extra_link_args=[],
language="c++",
define_macros=[
define_macros=custom_define_macros([
("HAVE_CONFIG_H", None),
("DIC_VERSION", 102),
("MECAB_DEFAULT_RC", '"dummy"'),
("PACKAGE", '"open_jtalk"'),
("VERSION", '"1.10"'),
("CHARSET_UTF_8", None),
],
]),
)
]

Expand All @@ -104,6 +198,7 @@
include_dirs=[np.get_include(), join(htsengine_src_top, "include")],
extra_compile_args=[],
extra_link_args=[],
libraries=["winmm"] if platform_is_windows else [],
language="c++",
)
]
Expand Down Expand Up @@ -150,7 +245,7 @@ def run(self):
cmdclass["develop"] = develop


with open("README.md", "r") as fd:
with open("README.md", "r", encoding="utf8") as fd:
long_description = fd.read()

setup(
Expand Down