Repository: lucy-clownfish Updated Branches: refs/heads/master 105f76c1e -> 9dc3a0e60
Refactor compiler setup.py for static archive. Use the Charmonizer-based build setup which creates a static archive, then link that archive into the python bindings. By using the Charmonizer-generated Makefile, we can avoid having to do a lot of custom compilation and cleanup in setup.py. Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/4ff87561 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/4ff87561 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/4ff87561 Branch: refs/heads/master Commit: 4ff87561435f283dda5002d4c5873e63b1de0361 Parents: 22246a3 Author: Marvin Humphrey <[email protected]> Authored: Sun Dec 14 10:41:39 2014 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Wed Jan 6 17:41:07 2016 -0800 ---------------------------------------------------------------------- compiler/python/setup.py | 83 +++++++++++-------------------------------- 1 file changed, 20 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/4ff87561/compiler/python/setup.py ---------------------------------------------------------------------- diff --git a/compiler/python/setup.py b/compiler/python/setup.py index b5d5c10..072c337 100644 --- a/compiler/python/setup.py +++ b/compiler/python/setup.py @@ -37,8 +37,9 @@ compiler_type = distutils.ccompiler.get_default_compiler() # 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 -BASE_DIR = os.path.abspath(os.path.join(os.pardir, os.pardir, os.pardir)) +BASE_DIR = os.path.abspath(os.path.join(os.pardir, os.pardir)) PARENT_DIR = os.path.abspath(os.pardir) CFC_SOURCE_DIR = os.path.join(PARENT_DIR, 'src') CFC_INCLUDE_DIR = os.path.join(PARENT_DIR, 'include') @@ -47,57 +48,21 @@ 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' -LEMON_DIR = os.path.join(BASE_DIR, 'lemon') -LEMON_EXE_NAME = compiler.executable_filename('lemon') -LEMON_EXE_PATH = os.path.join(LEMON_DIR, LEMON_EXE_NAME) +LIBCFC_NAME = 'libcfc.a' # TODO portability +LIBCFC_PATH = os.path.abspath(os.path.join(os.curdir, LIBCFC_NAME)) -# Accumulate lists of source files and target files. -c_filepaths = [] -y_filepaths = [] +c_filepaths = [os.path.join('clownfish', '_cfc.c')] paths_to_clean = [ CHARMONIZER_EXE_PATH, CHARMONY_H_PATH, '_charm*', ] -c_filepaths.append(os.path.join('clownfish', '_cfc.c')) -for (dirpath, dirnames, files) in os.walk(CFC_SOURCE_DIR): - for filename in files: - if filename.endswith('.y'): - path = os.path.join(dirpath, filename) - y_filepaths.append(path) - path = re.sub(r'y$', 'h', path) - paths_to_clean.append(path) - path = re.sub(r'h$', 'c', path) - paths_to_clean.append(path) - c_filepaths.append(path) - path = compiler.object_filenames([path])[0] - paths_to_clean.append(path) - if filename.endswith('.c'): - path = os.path.join(dirpath, filename) - c_filepaths.append(path) - path = compiler.object_filenames([path])[0] - paths_to_clean.append(path) def _quotify(text): text = text.replace('\\', '\\\\') text = text.replace('"', '\\"') return '"' + text + '"' -def _run_make(command=[], directory=None): - current_directory = os.getcwd(); - if (directory != None): - os.chdir(directory) - if (compiler_type == 'msvc'): - command.insert(0, 'Makefile.MSVC') - command.insert(0, '-f') - elif (platform.system() == 'Windows'): - command.insert(0, 'Makefile.MinGW') - command.insert(0, '-f') - command.insert(0, "make") - subprocess.check_call(command) - if (directory != None): - os.chdir(current_directory) - class charmony(_Command): description = "Build and run charmonizer" user_options = [] @@ -123,6 +88,8 @@ class charmony(_Command): CHARMONIZER_EXE_PATH, '--cc=' + _quotify(compiler_name), '--enable-c', + '--host=python', + '--enable-makefile', '--', cflags ] @@ -131,35 +98,26 @@ class charmony(_Command): print(" ".join(command)) subprocess.check_call(command) -class lemon(_Command): - description = "Compile the Lemon parser generator" +class libcfc(_Command): + description = "Build CFC as a static archive." user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): - if not os.path.exists(LEMON_EXE_PATH): - _run_make(['CC=' + _quotify(compiler_name)], directory=LEMON_DIR) - -class parsers(_Command): - description = "Run .y files through lemon" - user_options = [] - def initialize_options(self): - pass - def finalize_options(self): - pass - def run(self): - for y_path in y_filepaths: - target = re.sub(r'y$', 'c', y_path) - if newer_group([y_path], target): - command = [LEMON_EXE_PATH, '-c', y_path] - subprocess.check_call(command) + self.run_command('charmony') + subprocess.check_call([make_command, '-j', 'static']) + # Touch Python binding file if the library has changed. + cfc_c = os.path.join('clownfish', '_cfc.c') + if newer_group(['libcfc.a'], cfc_c): + os.utime(cfc_c, None) class my_clean(_clean): def run(self): _clean.run(self) - _run_make(command=['clean'], directory=LEMON_DIR) + if os.path.isfile("Makefile"): + subprocess.check_call([make_command, 'distclean']) for elem in paths_to_clean: for path in glob.glob(elem): print("removing " + path) @@ -171,8 +129,7 @@ class my_clean(_clean): class my_build(_build): def run(self): self.run_command('charmony') - self.run_command('lemon') - self.run_command('parsers') + self.run_command('libcfc') _build.run(self) cfc_extension = Extension('clownfish._cfc', @@ -182,6 +139,7 @@ cfc_extension = Extension('clownfish._cfc', CFC_SOURCE_DIR, os.curdir, ], + extra_link_args = [LIBCFC_PATH], sources = c_filepaths) setup(name = 'clownfish-cfc', @@ -195,9 +153,8 @@ setup(name = 'clownfish-cfc', cmdclass = { 'build': my_build, 'clean': my_clean, - 'lemon': lemon, 'charmony': charmony, - 'parsers': parsers, + 'libcfc': libcfc, }, ext_modules = [cfc_extension])
