Fix Python build under MSVC
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/09e9fc65 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/09e9fc65 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/09e9fc65 Branch: refs/heads/master Commit: 09e9fc654dc4c2e368e189a1dd2c1330fffa301b Parents: aad2186 Author: Nick Wellnhofer <[email protected]> Authored: Fri Aug 26 18:07:52 2016 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Fri Aug 26 19:19:32 2016 +0200 ---------------------------------------------------------------------- compiler/python/setup.py | 22 ++++++++++++++-------- compiler/src/CFCPython.c | 17 ++++++++++++----- runtime/common/charmonizer.c | 20 ++++++++++++++++++-- runtime/common/charmonizer.main | 20 ++++++++++++++++++-- runtime/python/setup.py | 25 ++++++++++++++++++------- 5 files changed, 80 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/09e9fc65/compiler/python/setup.py ---------------------------------------------------------------------- diff --git a/compiler/python/setup.py b/compiler/python/setup.py index b9d3e28..7f64c1a 100644 --- a/compiler/python/setup.py +++ b/compiler/python/setup.py @@ -38,8 +38,15 @@ compiler_type = distutils.ccompiler.get_default_compiler() # There's no public way to get a string representing the compiler executable # out of distutils, but the member variable has been in the same place for a # long time, so violating encapsulation may be ok. -compiler_name = " ".join(compiler.compiler) -make_command = "make" # TODO portability +if compiler_type == 'unix': + compiler_name = "".join(compiler.compiler) + make_command = ["make", "-j"] # TODO portability + LIBCFC_NAME = 'libcfc.a' # TODO portability +elif compiler_type == 'msvc': + compiler.initialize() + compiler_name = compiler.cc + make_command = ["nmake"] + LIBCFC_NAME = 'cfc.lib' BASE_DIR = os.path.abspath(os.path.join(os.pardir, os.pardir)) PARENT_DIR = os.path.abspath(os.pardir) @@ -50,7 +57,6 @@ CHARMONIZER_C = os.path.join(COMMON_SOURCE_DIR, 'charmonizer.c') CHARMONIZER_EXE_NAME = compiler.executable_filename('charmonizer') CHARMONIZER_EXE_PATH = os.path.join(os.curdir, CHARMONIZER_EXE_NAME) CHARMONY_H_PATH = 'charmony.h' -LIBCFC_NAME = 'libcfc.a' # TODO portability LIBCFC_PATH = os.path.abspath(os.path.join(os.curdir, LIBCFC_NAME)) c_filepaths = [os.path.join('src', 'cfc', '_cfc.c')] @@ -92,9 +98,9 @@ class charmony(_Command): '--enable-c', '--host=python', '--enable-makefile', - '--', - cflags ] + if cflags is not None: + command.extend(('--', cflags)); if 'CHARM_VALGRIND' in os.environ: command[0:0] = "valgrind", "--leak-check=yes"; print(" ".join(command)) @@ -109,17 +115,17 @@ class libcfc(_Command): pass def run(self): self.run_command('charmony') - subprocess.check_call([make_command, '-j', 'static']) + subprocess.check_call(make_command + ['static']) # Touch Python binding file if the library has changed. cfc_c = os.path.join('src', 'cfc', '_cfc.c') - if newer_group(['libcfc.a'], cfc_c): + if newer_group([LIBCFC_NAME], cfc_c): os.utime(cfc_c, None) class my_clean(_clean): def run(self): _clean.run(self) if os.path.isfile("Makefile"): - subprocess.check_call([make_command, 'distclean']) + subprocess.check_call(make_command + ['distclean']) for elem in paths_to_clean: for path in glob.glob(elem): print("removing " + path) http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/09e9fc65/compiler/src/CFCPython.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPython.c b/compiler/src/CFCPython.c index f81cfd4..cbc301c 100644 --- a/compiler/src/CFCPython.c +++ b/compiler/src/CFCPython.c @@ -459,6 +459,7 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) { CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy); CFCParcel **parcels = CFCParcel_all_parcels(); + char *privacy_syms = CFCUtil_strdup(""); char *callbacks = S_gen_callbacks(self, parcel, ordered); char *type_linkups = S_gen_type_linkups(self, parcel, ordered); char *pound_includes = CFCUtil_strdup(""); @@ -467,9 +468,12 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) { char *pytype_ready_calls = CFCUtil_strdup(""); char *module_adds = CFCUtil_strdup(""); - // Add parcel bootstrapping calls. + // Add privacy defines and parcel bootstrapping calls. for (size_t i = 0; parcels[i]; ++i) { if (!CFCParcel_included(parcels[i])) { + const char *privacy_sym = CFCParcel_get_privacy_sym(parcels[i]); + privacy_syms = CFCUtil_cat(privacy_syms, "#define ", privacy_sym, + "\n", NULL); const char *prefix = CFCParcel_get_prefix(parcels[i]); parcel_boots = CFCUtil_cat(parcel_boots, " ", prefix, "bootstrap_parcel();\n", NULL); @@ -503,6 +507,8 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) { const char pattern[] = "%s\n" "\n" + "%s" + "\n" "#include \"Python.h\"\n" "#include \"cfish_parcel.h\"\n" "#include \"CFBind.h\"\n" @@ -542,10 +548,10 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) { "\n"; char *content - = CFCUtil_sprintf(pattern, self->header, pound_includes, callbacks, - helper_mod_name, class_bindings, type_linkups, - last_component, pytype_ready_calls, parcel_boots, - module_adds, self->footer); + = CFCUtil_sprintf(pattern, self->header, privacy_syms, pound_includes, + callbacks, helper_mod_name, class_bindings, + type_linkups, last_component, pytype_ready_calls, + parcel_boots, module_adds, self->footer); char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "_%s.c", dest, last_component); @@ -562,6 +568,7 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) { FREEMEM(pound_includes); FREEMEM(type_linkups); FREEMEM(callbacks); + FREEMEM(privacy_syms); FREEMEM(ordered); } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/09e9fc65/runtime/common/charmonizer.c ---------------------------------------------------------------------- diff --git a/runtime/common/charmonizer.c b/runtime/common/charmonizer.c index 558befa..bb15cd3 100644 --- a/runtime/common/charmonizer.c +++ b/runtime/common/charmonizer.c @@ -8977,8 +8977,16 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { * library. */ compile_flags = chaz_MakeBinary_get_compile_flags(self->lib); - chaz_CFlags_compile_shared_library(compile_flags); + if (chaz_CC_msvc_version_num()) { + /* Python uses /MT. */ + chaz_CFlags_append(compile_flags, "/MT"); + } + else { + chaz_CFlags_compile_shared_library(compile_flags); + } chaz_CFlags_add_define(compile_flags, "CFP_CFISH", NULL); + /* Test code isn't separated yet. */ + chaz_CFlags_add_define(compile_flags, "CFP_TESTCFISH", NULL); } } @@ -9023,8 +9031,16 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { * library. */ compile_flags = chaz_MakeBinary_get_compile_flags(self->test_lib); - chaz_CFlags_compile_shared_library(compile_flags); + if (chaz_CC_msvc_version_num()) { + /* Python uses /MT. */ + chaz_CFlags_append(compile_flags, "/MT"); + } + else { + chaz_CFlags_compile_shared_library(compile_flags); + } chaz_CFlags_add_define(compile_flags, "CFP_TESTCFISH", NULL); + /* Test code isn't separated yet. */ + chaz_CFlags_add_define(compile_flags, "CFP_CFISH", NULL); } } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/09e9fc65/runtime/common/charmonizer.main ---------------------------------------------------------------------- diff --git a/runtime/common/charmonizer.main b/runtime/common/charmonizer.main index cfe8c21..806bdfa 100644 --- a/runtime/common/charmonizer.main +++ b/runtime/common/charmonizer.main @@ -398,8 +398,16 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { * library. */ compile_flags = chaz_MakeBinary_get_compile_flags(self->lib); - chaz_CFlags_compile_shared_library(compile_flags); + if (chaz_CC_msvc_version_num()) { + /* Python uses /MT. */ + chaz_CFlags_append(compile_flags, "/MT"); + } + else { + chaz_CFlags_compile_shared_library(compile_flags); + } chaz_CFlags_add_define(compile_flags, "CFP_CFISH", NULL); + /* Test code isn't separated yet. */ + chaz_CFlags_add_define(compile_flags, "CFP_TESTCFISH", NULL); } } @@ -444,8 +452,16 @@ cfish_MakeFile_write(cfish_MakeFile *self, chaz_CFlags *extra_link_flags) { * library. */ compile_flags = chaz_MakeBinary_get_compile_flags(self->test_lib); - chaz_CFlags_compile_shared_library(compile_flags); + if (chaz_CC_msvc_version_num()) { + /* Python uses /MT. */ + chaz_CFlags_append(compile_flags, "/MT"); + } + else { + chaz_CFlags_compile_shared_library(compile_flags); + } chaz_CFlags_add_define(compile_flags, "CFP_TESTCFISH", NULL); + /* Test code isn't separated yet. */ + chaz_CFlags_add_define(compile_flags, "CFP_CFISH", NULL); } } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/09e9fc65/runtime/python/setup.py ---------------------------------------------------------------------- diff --git a/runtime/python/setup.py b/runtime/python/setup.py index 1d015f5..26380df 100644 --- a/runtime/python/setup.py +++ b/runtime/python/setup.py @@ -19,6 +19,7 @@ from distutils.command.clean import clean as _clean from distutils.cmd import Command as _Command from distutils.dep_util import newer_group import distutils.ccompiler +import distutils.sysconfig import os import glob import platform @@ -39,14 +40,26 @@ def ext_build_dir(base): # CFLAGS. Add the Python headers include dir to CFLAGS. compiler = distutils.ccompiler.new_compiler() cflags = sysconfig.get_config_var('CFLAGS') -cflags = cflags + " -I" + distutils.sysconfig.get_python_inc() +if cflags is None: + cflags = "-I" + distutils.sysconfig.get_python_inc() +else: + cflags = cflags + " -I" + distutils.sysconfig.get_python_inc() compiler_type = distutils.ccompiler.get_default_compiler() # There's no public way to get a string representing the compiler executable # out of distutils, but the member variable has been in the same place for a # long time, so violating encapsulation may be ok. -compiler_name = " ".join(compiler.compiler) -make_command = "make" # TODO portability +if compiler_type == 'unix': + compiler_name = "".join(compiler.compiler) + make_command = ["make", "-j"] # TODO portability + CORELIB_NAME = 'libclownfish.a' # TODO portability + TESTLIB_NAME = 'libtestcfish.a' # TODO portability +elif compiler_type == 'msvc': + compiler.initialize() + compiler_name = compiler.cc + make_command = ["nmake"] + CORELIB_NAME = 'clownfish.lib' + TESTLIB_NAME = 'testcfish.lib' BASE_DIR = os.path.abspath(os.path.join(os.pardir, os.pardir)) PARENT_DIR = os.path.abspath(os.pardir) @@ -58,9 +71,7 @@ CHARMONIZER_C = os.path.join(COMMON_SOURCE_DIR, 'charmonizer.c') CHARMONIZER_EXE_NAME = compiler.executable_filename('charmonizer') CHARMONIZER_EXE_PATH = os.path.join(os.curdir, CHARMONIZER_EXE_NAME) CHARMONY_H_PATH = 'charmony.h' -CORELIB_NAME = 'libclownfish.a' # TODO portability CORELIB_PATH = os.path.abspath(os.path.join(os.curdir, CORELIB_NAME)) -TESTLIB_NAME = 'libtestcfish.a' # TODO portability TESTLIB_PATH = os.path.abspath(os.path.join(os.curdir, TESTLIB_NAME)) AUTOGEN_INCLUDE = os.path.join('autogen', 'include') CFC_DIR = os.path.join(BASE_DIR, 'compiler', 'python') @@ -128,7 +139,7 @@ class libclownfish(_Command): def run(self): self.run_command('charmony') self.run_cfc() - subprocess.check_call([make_command, '-j', 'static']) + subprocess.check_call(make_command + ['static']) def run_cfc(self): sys.path.append(CFC_DIR) @@ -151,7 +162,7 @@ class my_clean(_clean): def run(self): _clean.run(self) if os.path.isfile("Makefile"): - subprocess.check_call([make_command, 'distclean']) + subprocess.check_call(make_command + ['distclean']) for elem in paths_to_clean: for path in glob.glob(elem): print("removing " + path)
