2018-07-15 00:01:37 +02:00
2018-07-15 12:12:05 +02:00
"""
KLayout standalone Python module setup script
2022-01-04 21:20:04 +01:00
Copyright ( C ) 2006 - 2022 Matthias Koefferlein
2018-07-15 12:12:05 +02:00
2018-07-16 07:16:36 +02:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
2018-07-15 12:12:05 +02:00
2018-07-16 07:16:36 +02:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2018-07-15 12:12:05 +02:00
2018-07-16 07:16:36 +02:00
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
2018-07-15 12:12:05 +02:00
This script provides distutils - based deployment for KLayout ' s
standalone Python modules .
The standalone libraries are basically extension modules .
Build requirements are :
* curl library
* expat library
2022-05-12 01:53:16 +02:00
* png library
2018-07-15 12:12:05 +02:00
The main challenge is to map KLayout ' s shared object architecture.
The structure consists of the Python extension libraries and a bunch
2018-07-16 07:12:11 +02:00
of libraries providing the actual implementation part .
2018-07-15 12:12:05 +02:00
The Python extension libraries reference the implementation libraries .
The extension libraries are prefixed with an underscore .
For example :
2018-07-16 07:16:36 +02:00
tl ( Python ) - > _tl , _gsi
2018-07-15 12:12:05 +02:00
2018-07-16 07:12:11 +02:00
There is a specific issue with the building of the extension
2018-07-15 12:12:05 +02:00
libraries : distutils only allows building of shared objects
as extension libraries and does not provide a intrinsic feature
2018-07-16 07:12:11 +02:00
for linking other libraries into the extension library .
2018-07-15 12:12:05 +02:00
Hence we need to add the dependencies through " extra_objects " .
2018-07-16 07:12:11 +02:00
On Linux there is a specific issue : The shared objects produced
2018-07-15 12:12:05 +02:00
for extension libraries are not matching the Linux name conventions .
2018-07-16 07:12:11 +02:00
So we have to add them as . so link objects including the path .
If we do so , the runtime loading will look them up by their path
and won ' t find them. So we need to take away the path with
2018-07-15 12:12:05 +02:00
" -Wl,-soname " on Linux ( see Config . link_args ) .
"""
2018-10-22 18:15:02 +02:00
from setuptools import setup , Distribution , find_packages
2018-10-18 09:41:38 +02:00
from setuptools . extension import Extension , Library
2018-07-15 00:01:37 +02:00
import glob
2018-07-15 00:30:12 +02:00
import os
2019-11-09 00:34:15 +01:00
import re
2020-11-28 22:15:44 +01:00
import sys
2018-07-15 16:42:01 +02:00
import platform
2018-08-02 04:29:35 +02:00
from distutils . errors import CompileError
2018-10-09 06:35:28 +02:00
import distutils . command . build_ext
2018-10-20 22:44:56 +02:00
import setuptools . command . build_ext
2018-08-02 01:54:20 +02:00
import multiprocessing
2021-10-30 18:45:44 +02:00
# for Jenkins we do not want to be greedy
multicore = os . getenv ( " KLAYOUT_SETUP_MULTICORE " )
if multicore :
N_cores = int ( multicore )
else :
N_cores = multiprocessing . cpu_count ( )
2018-07-15 00:01:37 +02:00
2018-12-17 23:56:04 +01:00
2018-08-01 01:06:20 +02:00
# monkey-patch for parallel compilation
# from https://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils
def parallelCCompile ( self , sources , output_dir = None , macros = None , include_dirs = None , debug = 0 , extra_preargs = None , extra_postargs = None , depends = None ) :
# those lines are copied from distutils.ccompiler.CCompiler directly
2018-08-02 01:54:20 +02:00
macros , objects , extra_postargs , pp_opts , build = self . _setup_compile (
output_dir , macros , include_dirs , sources , depends , extra_postargs )
2018-08-01 01:06:20 +02:00
cc_args = self . _get_cc_args ( pp_opts , debug , extra_preargs )
# parallel code
2018-08-01 21:58:53 +02:00
2018-08-02 02:24:10 +02:00
N = min ( N_cores , len ( objects ) / / 2 , 8 ) # number of parallel compilations
2018-08-02 04:29:35 +02:00
N = max ( N , 1 )
2018-08-02 02:24:10 +02:00
print ( " Compiling with " , N , " threads. " )
2018-08-01 01:06:20 +02:00
import multiprocessing . pool
2018-08-02 01:54:20 +02:00
2018-08-01 01:06:20 +02:00
def _single_compile ( obj ) :
2018-08-02 01:54:20 +02:00
try :
src , ext = build [ obj ]
except KeyError :
return
2018-08-02 04:29:35 +02:00
n_tries = 2
while n_tries > 0 :
try :
2018-12-17 23:56:04 +01:00
print ( " Building " , obj )
2018-08-02 04:29:35 +02:00
self . _compile ( obj , src , ext , cc_args , extra_postargs , pp_opts )
except CompileError :
n_tries - = 1
print ( " Building " , obj , " has failed. Trying again. " )
else :
break
2018-08-01 01:06:20 +02:00
# convert to list, imap is evaluated on-demand
2018-12-17 23:56:04 +01:00
list ( multiprocessing . pool . ThreadPool ( N ) . map ( _single_compile , objects ) )
2018-08-01 01:06:20 +02:00
return objects
2018-08-02 01:54:20 +02:00
2018-08-02 04:29:35 +02:00
# only if python version > 2.6, somehow the travis compiler hangs in 2.6
2020-11-28 22:15:44 +01:00
if sys . version_info [ 0 ] * 100 + sys . version_info [ 1 ] > 206 :
2018-08-02 04:29:35 +02:00
import distutils . ccompiler
distutils . ccompiler . CCompiler . compile = parallelCCompile
2018-07-15 00:01:37 +02:00
2018-10-09 06:35:28 +02:00
2020-11-28 22:15:44 +01:00
# put a path in quotes if required
def quote_path ( path ) :
# looks like disutils don't need path quoting in version >= 3.9:
if " " in path and sys . version_info [ 0 ] * 100 + sys . version_info [ 1 ] < 309 :
return " \" " + path + " \" "
else :
return path
2018-10-20 23:21:00 +02:00
# TODO: delete (Obsolete)
# patch get_ext_filename
2018-10-09 06:35:28 +02:00
from distutils . command . build_ext import build_ext
_old_get_ext_filename = build_ext . get_ext_filename
def patched_get_ext_filename ( self , ext_name ) :
r """ Convert the name of an extension (eg. " foo.bar " ) into the name
of the file from which it will be loaded ( eg . " foo/bar.so " , or
" foo \b ar.pyd " ) .
"""
filename = _old_get_ext_filename ( self , ext_name )
# Making sure this matches qmake's default extension .dylib, instead of .so
if platform . system ( ) == " Darwin " and ' _dbpi ' in ext_name :
filename = filename . replace ( ' .so ' , ' .dylib ' )
return filename
distutils . command . build_ext . build_ext . get_ext_filename = patched_get_ext_filename
2018-10-20 22:44:56 +02:00
2018-10-20 23:21:00 +02:00
# end patch get_ext_filename
# patch CCompiler's library_filename for _dbpi libraries (SOs)
# Its default is to have .so for shared objects, instead of dylib,
# hence the patch
from distutils . ccompiler import CCompiler
old_library_filename = CCompiler . library_filename
def patched_library_filename ( self , libname , lib_type = ' static ' , # or 'shared'
strip_dir = 0 , output_dir = ' ' ) :
if platform . system ( ) == " Darwin " and ' _dbpi ' in libname :
lib_type = ' dylib '
return old_library_filename ( self , libname , lib_type = lib_type ,
strip_dir = strip_dir , output_dir = output_dir )
distutils . ccompiler . CCompiler . library_filename = patched_library_filename
# end patch CCompiler's library_filename for _dbpi libraries (SOs)
# despite its name, setuptools.command.build_ext.link_shared_object won't
# link a shared object on Linux, but a static library and patches distutils
2018-10-20 22:44:56 +02:00
# for this ... We're patching this back now.
def always_link_shared_object (
2018-12-17 23:56:04 +01:00
self , objects , output_libname , output_dir = None , libraries = None ,
library_dirs = None , runtime_library_dirs = None , export_symbols = None ,
debug = 0 , extra_preargs = None , extra_postargs = None , build_temp = None ,
target_lang = None ) :
2018-10-20 22:44:56 +02:00
self . link (
self . SHARED_LIBRARY , objects , output_libname ,
output_dir , libraries , library_dirs , runtime_library_dirs ,
export_symbols , debug , extra_preargs , extra_postargs ,
build_temp , target_lang
)
2018-12-17 23:56:04 +01:00
2018-10-20 22:44:56 +02:00
setuptools . command . build_ext . libtype = " shared "
setuptools . command . build_ext . link_shared_object = always_link_shared_object
2018-07-15 12:12:05 +02:00
# ----------------------------------------------------------------------------------------
2018-07-15 00:42:18 +02:00
2018-07-16 07:16:36 +02:00
class Config ( object ) :
2018-07-15 00:30:12 +02:00
2018-07-15 12:12:05 +02:00
"""
2018-07-16 07:16:36 +02:00
Provides some configuration - specific methods
2018-07-15 12:12:05 +02:00
"""
2018-07-15 00:30:12 +02:00
2018-07-16 07:16:36 +02:00
def __init__ ( self ) :
# TODO: is this really how we get the build paths?
build_cmd = Distribution ( ) . get_command_obj ( ' build ' )
build_cmd . finalize_options ( )
self . build_platlib = build_cmd . build_platlib
2018-10-18 09:41:38 +02:00
self . build_temp = build_cmd . build_temp
if platform . system ( ) == " Windows " :
# Windows uses separate temp build folders for debug and release
if build_cmd . debug :
self . build_temp = os . path . join ( self . build_temp , " Debug " )
else :
self . build_temp = os . path . join ( self . build_temp , " Release " )
2018-07-16 07:16:36 +02:00
2018-10-21 05:46:12 +02:00
build_ext_cmd = Distribution ( ) . get_command_obj ( ' build_ext ' )
2018-10-09 06:35:28 +02:00
2018-10-21 05:46:12 +02:00
build_ext_cmd . initialize_options ( )
build_ext_cmd . setup_shlib_compiler ( )
self . build_ext_cmd = build_ext_cmd
2018-07-20 01:02:37 +02:00
2018-07-16 07:16:36 +02:00
self . root = " klayout "
2018-10-21 05:46:12 +02:00
def add_extension ( self , ext ) :
self . build_ext_cmd . ext_map [ ext . name ] = ext
def libname_of ( self , mod , is_lib = None ) :
2018-07-16 07:16:36 +02:00
"""
Returns the library name for a given module
The library name is usually decorated ( i . e . " tl " - > " tl.cpython-35m-x86_64-linux-gnu.so " ) .
2018-10-21 05:46:12 +02:00
This code was extracted from the source in setuptools . command . build_ext . build_ext
2018-07-16 07:16:36 +02:00
"""
2018-10-21 05:46:12 +02:00
libtype = setuptools . command . build_ext . libtype
full_mod = self . root + ' . ' + mod
if is_lib is True :
# Here we are guessing it is a library and that the filename
# is to be computed by shlib_compiler.
# See source code of setuptools.command.build_ext.build_ext.get_ext_filename
filename = self . build_ext_cmd . get_ext_filename ( full_mod )
fn , ext = os . path . splitext ( filename )
ext_path = self . build_ext_cmd . shlib_compiler . library_filename ( fn , libtype )
2018-10-20 22:44:56 +02:00
else :
2018-10-21 05:46:12 +02:00
# This assumes that the Extension/Library object was added to the
# ext_map dictionary via config.add_extension.
assert full_mod in self . build_ext_cmd . ext_map
ext_path = self . build_ext_cmd . get_ext_filename ( full_mod )
ext_filename = os . path . basename ( ext_path )
# Exception for database plugins, which will always be dylib.
2018-10-09 06:35:28 +02:00
if platform . system ( ) == " Darwin " and ' _dbpi ' in mod :
2018-10-21 05:46:12 +02:00
ext_filename = ext_filename . replace ( ' .so ' , ' .dylib ' )
return ext_filename
2018-07-16 07:16:36 +02:00
2018-10-18 09:41:38 +02:00
def path_of ( self , mod , mod_src_path ) :
2018-07-16 07:16:36 +02:00
"""
Returns the build path of the library for a given module
"""
2018-10-18 09:41:38 +02:00
if platform . system ( ) == " Windows " :
# On Windows, the library to link is the import library
( dll_name , dll_ext ) = os . path . splitext ( self . libname_of ( mod ) )
return os . path . join ( self . build_temp , mod_src_path , dll_name + " .lib " )
else :
return os . path . join ( self . build_platlib , self . root , self . libname_of ( mod ) )
2018-07-16 07:16:36 +02:00
def compile_args ( self , mod ) :
"""
Gets additional compiler arguments
"""
if platform . system ( ) == " Windows " :
2018-10-18 09:41:38 +02:00
bits = os . getenv ( " KLAYOUT_BITS " )
if bits :
2020-11-28 22:15:44 +01:00
return [ quote_path ( " -I " + os . path . join ( bits , " zlib " , " include " ) ) ,
quote_path ( " -I " + os . path . join ( bits , " ptw " , " include " ) ) ,
2022-05-12 01:53:16 +02:00
quote_path ( " -I " + os . path . join ( bits , " png " , " include " ) ) ,
2020-11-28 22:15:44 +01:00
quote_path ( " -I " + os . path . join ( bits , " expat " , " include " ) ) ,
quote_path ( " -I " + os . path . join ( bits , " curl " , " include " ) ) ]
2018-10-18 09:41:38 +02:00
else :
return [ ]
2018-07-16 07:16:36 +02:00
else :
2018-09-22 18:45:43 +02:00
return [ " -Wno-strict-aliasing " , # Avoids many "type-punned pointer" warnings
2018-10-08 07:20:17 +02:00
" -std=c++11 " , # because we use unordered_map/unordered_set
2018-09-22 18:45:43 +02:00
]
2018-07-16 07:16:36 +02:00
2018-10-18 09:41:38 +02:00
def libraries ( self , mod ) :
"""
Gets the libraries to add
"""
if platform . system ( ) == " Windows " :
if mod == " _tl " :
2022-06-01 07:41:29 +02:00
return [ " libcurl " , " expat " , " pthreadVCE2 " , " zlib " , " wsock32 " , " libpng16 " ]
2018-10-18 09:41:38 +02:00
else :
if mod == " _tl " :
2022-06-01 07:41:29 +02:00
return [ " curl " , " expat " , " png " ]
2018-10-18 09:41:38 +02:00
return [ ]
2018-07-16 07:16:36 +02:00
def link_args ( self , mod ) :
"""
Gets additional linker arguments
"""
if platform . system ( ) == " Windows " :
2018-10-18 09:41:38 +02:00
args = [ " /DLL " ]
bits = os . getenv ( " KLAYOUT_BITS " )
if bits :
2022-05-16 21:14:23 +02:00
args + = [ quote_path ( " /LIBPATH: " + os . path . join ( bits , " zlib " , " lib " ) ) ,
2020-11-28 22:15:44 +01:00
quote_path ( " /LIBPATH: " + os . path . join ( bits , " ptw " , " libraries " ) ) ,
2022-05-12 01:53:16 +02:00
quote_path ( " /LIBPATH: " + os . path . join ( bits , " png " , " libraries " ) ) ,
2020-11-28 22:15:44 +01:00
quote_path ( " /LIBPATH: " + os . path . join ( bits , " expat " , " libraries " ) ) ,
quote_path ( " /LIBPATH: " + os . path . join ( bits , " curl " , " libraries " ) ) ]
2018-10-18 09:41:38 +02:00
return args
2018-07-16 07:16:36 +02:00
elif platform . system ( ) == " Darwin " :
# For the dependency modules, make sure we produce a dylib.
# We can only link against such, but the bundles produced otherwise.
args = [ ]
if mod [ 0 ] == " _ " :
2018-10-21 05:46:12 +02:00
args + = [ " -Wl,-dylib " , ' -Wl,-install_name,@rpath/ %s ' % self . libname_of ( mod , is_lib = True ) ]
2018-07-16 07:52:51 +02:00
args + = [ ' -Wl,-rpath,@loader_path/ ' ]
2018-07-16 07:16:36 +02:00
return args
else :
# this makes the libraries suitable for linking with a path -
# i.e. from path_of('_tl'). Without this option, the path
# will be included in the reference and at runtime the loaded
# will look for the path-qualified library. But that's the
# build path and the loader will fail.
2018-07-17 01:44:30 +02:00
args = [ ]
2018-10-21 05:46:12 +02:00
args + = [ ' -Wl,-soname, ' + self . libname_of ( mod , is_lib = True ) ]
2018-09-22 18:45:43 +02:00
if ' _dbpi ' not in mod :
2018-07-18 21:11:36 +02:00
loader_path = ' $ORIGIN '
else :
loader_path = ' $ORIGIN/.. '
args + = [ ' -Wl,-rpath, ' + loader_path ]
2019-04-03 04:39:12 +02:00
# default linux shared object compilation uses the '-g' flag,
# which generates unnecessary debug information
# removing with strip-all during the linking stage
args + = [ ' -Wl,--strip-all ' ]
2018-07-17 01:44:30 +02:00
return args
2018-07-16 07:16:36 +02:00
def macros ( self ) :
"""
Returns the macros to use for building
"""
2022-05-12 01:53:16 +02:00
return [ ( ' HAVE_PNG ' , 1 ) , ( ' HAVE_CURL ' , 1 ) , ( ' HAVE_EXPAT ' , 1 ) , ( ' KLAYOUT_MAJOR_VERSION ' , self . major_version ( ) ) , ( ' KLAYOUT_MINOR_VERSION ' , self . minor_version ( ) ) ]
2021-02-01 22:57:55 +01:00
def minor_version ( self ) :
"""
Gets the version string
"""
# this will obtain the version string from the "version.sh" file which
# is the central point of configuration
version_file = os . path . join ( os . path . dirname ( __file__ ) , " version.sh " )
with open ( version_file , " r " ) as file :
version_txt = file . read ( )
rm = re . search ( r " KLAYOUT_VERSION \ s*= \ s* \" (.*?) \ .(.*?)( \ ..*)? \" .* " , version_txt )
if rm :
version_string = rm . group ( 2 )
return version_string
raise RuntimeError ( " Unable to obtain version string from version.sh " )
def major_version ( self ) :
"""
Gets the version string
"""
# this will obtain the version string from the "version.sh" file which
# is the central point of configuration
version_file = os . path . join ( os . path . dirname ( __file__ ) , " version.sh " )
with open ( version_file , " r " ) as file :
version_txt = file . read ( )
rm = re . search ( r " KLAYOUT_VERSION \ s*= \ s* \" (.*?) \ .(.*?)( \ ..*)? \" .* " , version_txt )
if rm :
version_string = rm . group ( 1 )
return version_string
raise RuntimeError ( " Unable to obtain version string from version.sh " )
2018-07-16 07:16:36 +02:00
def version ( self ) :
"""
Gets the version string
"""
2019-11-09 00:34:15 +01:00
# this will obtain the version string from the "version.sh" file which
# is the central point of configuration
version_file = os . path . join ( os . path . dirname ( __file__ ) , " version.sh " )
with open ( version_file , " r " ) as file :
version_txt = file . read ( )
2019-11-12 00:04:40 +01:00
rm = re . search ( r " KLAYOUT_PYPI_VERSION \ s*= \ s* \" (.*?) \" .* " , version_txt )
2019-11-09 00:34:15 +01:00
if rm :
version_string = rm . group ( 1 )
return version_string
raise RuntimeError ( " Unable to obtain version string from version.sh " )
2018-10-07 03:22:08 +02:00
2018-07-15 12:12:05 +02:00
2018-07-15 00:30:12 +02:00
config = Config ( )
2018-07-15 00:01:37 +02:00
# ------------------------------------------------------------------
2018-07-15 12:12:05 +02:00
# _tl dependency library
2018-07-15 00:01:37 +02:00
2018-09-02 00:40:35 +02:00
_tl_path = os . path . join ( " src " , " tl " , " tl " )
2018-10-08 09:07:52 +02:00
_tl_sources = set ( glob . glob ( os . path . join ( _tl_path , " *.cc " ) ) )
2018-07-15 00:01:37 +02:00
# Exclude sources which are compatible with Qt only
2018-10-08 09:07:52 +02:00
# Caveat, in source distribution tarballs from pypi, these files will
# not exist. So we need an error-free discard method instead of list's remove.
_tl_sources . discard ( os . path . join ( _tl_path , " tlHttpStreamQt.cc " ) )
_tl_sources . discard ( os . path . join ( _tl_path , " tlHttpStreamNoQt.cc " ) )
_tl_sources . discard ( os . path . join ( _tl_path , " tlFileSystemWatcher.cc " ) )
_tl_sources . discard ( os . path . join ( _tl_path , " tlDeferredExecutionQt.cc " ) )
2018-07-15 00:01:37 +02:00
2018-10-18 09:41:38 +02:00
_tl = Library ( config . root + ' ._tl ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_TL_LIBRARY ' , 1 ) ] ,
language = ' c++ ' ,
libraries = config . libraries ( ' _tl ' ) ,
extra_link_args = config . link_args ( ' _tl ' ) ,
extra_compile_args = config . compile_args ( ' _tl ' ) ,
sources = list ( _tl_sources ) )
2018-07-15 00:01:37 +02:00
2018-10-21 05:46:12 +02:00
config . add_extension ( _tl )
2018-07-15 00:01:37 +02:00
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# _gsi dependency library
2018-10-18 09:41:38 +02:00
_gsi_path = os . path . join ( " src " , " gsi " , " gsi " )
_gsi_sources = set ( glob . glob ( os . path . join ( _gsi_path , " *.cc " ) ) )
2018-07-15 00:01:37 +02:00
2018-10-18 09:41:38 +02:00
_gsi = Library ( config . root + ' ._gsi ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_GSI_LIBRARY ' , 1 ) ] ,
include_dirs = [ _tl_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) ] ,
language = ' c++ ' ,
2022-05-12 01:53:16 +02:00
libraries = config . libraries ( ' _gsi ' ) ,
2018-10-18 09:41:38 +02:00
extra_link_args = config . link_args ( ' _gsi ' ) ,
extra_compile_args = config . compile_args ( ' _gsi ' ) ,
sources = list ( _gsi_sources ) )
2018-10-21 05:46:12 +02:00
config . add_extension ( _gsi )
2018-07-15 00:01:37 +02:00
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# _pya dependency library
2018-10-18 09:41:38 +02:00
_pya_path = os . path . join ( " src " , " pya " , " pya " )
_pya_sources = set ( glob . glob ( os . path . join ( _pya_path , " *.cc " ) ) )
2018-07-15 00:01:37 +02:00
2018-10-18 09:41:38 +02:00
_pya = Library ( config . root + ' ._pya ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_PYA_LIBRARY ' , 1 ) ] ,
include_dirs = [ _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) ] ,
language = ' c++ ' ,
2022-05-12 01:53:16 +02:00
libraries = config . libraries ( ' _pya ' ) ,
2018-10-18 09:41:38 +02:00
extra_link_args = config . link_args ( ' _pya ' ) ,
extra_compile_args = config . compile_args ( ' _pya ' ) ,
sources = list ( _pya_sources ) )
2018-10-21 05:46:12 +02:00
config . add_extension ( _pya )
2018-07-15 00:01:37 +02:00
2022-05-12 01:53:16 +02:00
# ------------------------------------------------------------------
# _rba dependency library (dummy)
_rba_path = os . path . join ( " src " , " rbastub " )
_rba_sources = set ( glob . glob ( os . path . join ( _rba_path , " *.cc " ) ) )
_rba = Library ( config . root + ' ._rba ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_RBA_LIBRARY ' , 1 ) ] ,
include_dirs = [ _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) ] ,
language = ' c++ ' ,
libraries = config . libraries ( ' _rba ' ) ,
extra_link_args = config . link_args ( ' _rba ' ) ,
extra_compile_args = config . compile_args ( ' _rba ' ) ,
sources = list ( _rba_sources ) )
config . add_extension ( _rba )
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# _db dependency library
2018-09-02 00:40:35 +02:00
_db_path = os . path . join ( " src " , " db " , " db " )
2018-10-08 09:07:52 +02:00
_db_sources = set ( glob . glob ( os . path . join ( _db_path , " *.cc " ) ) )
2018-07-15 12:12:05 +02:00
2018-10-18 09:41:38 +02:00
_db = Library ( config . root + ' ._db ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_DB_LIBRARY ' , 1 ) ] ,
include_dirs = [ _tl_path , _gsi_path , _db_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) ] ,
language = ' c++ ' ,
2022-05-12 01:53:16 +02:00
libraries = config . libraries ( ' _db ' ) ,
2018-10-18 09:41:38 +02:00
extra_link_args = config . link_args ( ' _db ' ) ,
extra_compile_args = config . compile_args ( ' _db ' ) ,
sources = list ( _db_sources ) )
2018-10-21 05:46:12 +02:00
config . add_extension ( _db )
2018-07-15 12:12:05 +02:00
2019-04-03 01:07:22 +02:00
# ------------------------------------------------------------------
# _lib dependency library
_lib_path = os . path . join ( " src " , " lib " , " lib " )
_lib_sources = set ( glob . glob ( os . path . join ( _lib_path , " *.cc " ) ) )
_lib = Library ( config . root + ' ._lib ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_LIB_LIBRARY ' , 1 ) ] ,
2019-04-03 18:31:05 +02:00
include_dirs = [ _tl_path , _gsi_path , _db_path , _lib_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
2019-04-03 01:07:22 +02:00
language = ' c++ ' ,
2022-05-12 01:53:16 +02:00
libraries = config . libraries ( ' _lib ' ) ,
2019-04-03 01:07:22 +02:00
extra_link_args = config . link_args ( ' _lib ' ) ,
extra_compile_args = config . compile_args ( ' _lib ' ) ,
sources = list ( _lib_sources ) )
config . add_extension ( _lib )
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# _rdb dependency library
2018-10-18 09:41:38 +02:00
_rdb_path = os . path . join ( " src " , " rdb " , " rdb " )
_rdb_sources = set ( glob . glob ( os . path . join ( _rdb_path , " *.cc " ) ) )
2018-07-15 12:12:05 +02:00
2018-10-18 09:41:38 +02:00
_rdb = Library ( config . root + ' ._rdb ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_RDB_LIBRARY ' , 1 ) ] ,
include_dirs = [ _db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
language = ' c++ ' ,
2022-05-12 01:53:16 +02:00
libraries = config . libraries ( ' _rdb ' ) ,
2018-10-18 09:41:38 +02:00
extra_link_args = config . link_args ( ' _rdb ' ) ,
extra_compile_args = config . compile_args ( ' _rdb ' ) ,
sources = list ( _rdb_sources ) )
2018-10-21 05:46:12 +02:00
config . add_extension ( _rdb )
2018-07-15 12:12:05 +02:00
2022-05-12 23:42:21 +02:00
# ------------------------------------------------------------------
2022-05-15 18:45:07 +02:00
# _laybasic dependency library
2022-05-12 23:42:21 +02:00
2022-05-15 18:45:07 +02:00
_laybasic_path = os . path . join ( " src " , " laybasic " , " laybasic " )
_laybasic_sources = set ( glob . glob ( os . path . join ( _laybasic_path , " *.cc " ) ) )
2022-05-12 23:42:21 +02:00
2022-05-15 18:45:07 +02:00
_laybasic = Library ( config . root + ' ._laybasic ' ,
2022-05-12 23:42:21 +02:00
define_macros = config . macros ( ) + [ ( ' MAKE_LAYBASIC_LIBRARY ' , 1 ) ] ,
include_dirs = [ _rdb_path , _db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _rdb ' , _rdb_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
language = ' c++ ' ,
2022-05-15 18:45:07 +02:00
libraries = config . libraries ( ' _laybasic ' ) ,
extra_link_args = config . link_args ( ' _laybasic ' ) ,
extra_compile_args = config . compile_args ( ' _laybasic ' ) ,
sources = list ( _laybasic_sources ) )
config . add_extension ( _laybasic )
# ------------------------------------------------------------------
# _layview dependency library
_layview_path = os . path . join ( " src " , " layview " , " layview " )
_layview_sources = set ( glob . glob ( os . path . join ( _layview_path , " *.cc " ) ) )
_layview = Library ( config . root + ' ._layview ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_LAYVIEW_LIBRARY ' , 1 ) ] ,
include_dirs = [ _laybasic_path , _rdb_path , _db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _laybasic ' , _laybasic_path ) , config . path_of ( ' _rdb ' , _rdb_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
language = ' c++ ' ,
libraries = config . libraries ( ' _layview ' ) ,
extra_link_args = config . link_args ( ' _layview ' ) ,
extra_compile_args = config . compile_args ( ' _layview ' ) ,
sources = list ( _layview_sources ) )
config . add_extension ( _layview )
2022-05-12 23:42:21 +02:00
2022-05-12 01:53:16 +02:00
# ------------------------------------------------------------------
# _lym dependency library
_lym_path = os . path . join ( " src " , " lym " , " lym " )
_lym_sources = set ( glob . glob ( os . path . join ( _lym_path , " *.cc " ) ) )
_lym = Library ( config . root + ' ._lym ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_LYM_LIBRARY ' , 1 ) ] ,
include_dirs = [ _pya_path , _rba_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _rba ' , _rba_path ) , config . path_of ( ' _pya ' , _pya_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) ] ,
language = ' c++ ' ,
libraries = config . libraries ( ' _lym ' ) ,
extra_link_args = config . link_args ( ' _lym ' ) ,
extra_compile_args = config . compile_args ( ' _lym ' ) ,
sources = list ( _lym_sources ) )
config . add_extension ( _lym )
# ------------------------------------------------------------------
# _ant dependency library
_ant_path = os . path . join ( " src " , " ant " , " ant " )
_ant_sources = set ( glob . glob ( os . path . join ( _ant_path , " *.cc " ) ) )
_ant = Library ( config . root + ' ._ant ' ,
define_macros = config . macros ( ) + [ ( ' MAKE_ANT_LIBRARY ' , 1 ) ] ,
2022-05-15 18:45:07 +02:00
include_dirs = [ _laybasic_path , _layview_path , _rdb_path , _db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _laybasic ' , _laybasic_path ) , config . path_of ( ' _layview ' , _layview_path ) , config . path_of ( ' _rdb ' , _rdb_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
2022-05-12 01:53:16 +02:00
language = ' c++ ' ,
libraries = config . libraries ( ' _ant ' ) ,
extra_link_args = config . link_args ( ' _ant ' ) ,
extra_compile_args = config . compile_args ( ' _ant ' ) ,
sources = list ( _ant_sources ) )
config . add_extension ( _ant )
# ------------------------------------------------------------------
# _img dependency library
_img_path = os . path . join ( " src " , " img " , " img " )
_img_sources = set ( glob . glob ( os . path . join ( _img_path , " *.cc " ) ) )
_img = Library ( config . root + ' ._img ' ,
2022-05-16 23:08:02 +02:00
define_macros = config . macros ( ) + [ ( ' MAKE_IMG_LIBRARY ' , 1 ) ] ,
2022-05-15 18:45:07 +02:00
include_dirs = [ _laybasic_path , _layview_path , _rdb_path , _db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _laybasic ' , _laybasic_path ) , config . path_of ( ' _layview ' , _layview_path ) , config . path_of ( ' _rdb ' , _rdb_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
2022-05-12 01:53:16 +02:00
language = ' c++ ' ,
libraries = config . libraries ( ' _img ' ) ,
extra_link_args = config . link_args ( ' _img ' ) ,
extra_compile_args = config . compile_args ( ' _img ' ) ,
sources = list ( _img_sources ) )
config . add_extension ( _img )
# ------------------------------------------------------------------
# _edt dependency library
_edt_path = os . path . join ( " src " , " edt " , " edt " )
_edt_sources = set ( glob . glob ( os . path . join ( _edt_path , " *.cc " ) ) )
_edt = Library ( config . root + ' ._edt ' ,
2022-05-16 23:08:02 +02:00
define_macros = config . macros ( ) + [ ( ' MAKE_EDT_LIBRARY ' , 1 ) ] ,
2022-05-15 18:45:07 +02:00
include_dirs = [ _laybasic_path , _layview_path , _rdb_path , _db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _laybasic ' , _laybasic_path ) , config . path_of ( ' _layview ' , _layview_path ) , config . path_of ( ' _rdb ' , _rdb_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
2022-05-12 01:53:16 +02:00
language = ' c++ ' ,
libraries = config . libraries ( ' _edt ' ) ,
extra_link_args = config . link_args ( ' _edt ' ) ,
extra_compile_args = config . compile_args ( ' _edt ' ) ,
sources = list ( _edt_sources ) )
config . add_extension ( _edt )
2018-07-15 12:52:59 +02:00
# ------------------------------------------------------------------
# dependency libraries from db_plugins
db_plugins = [ ]
2018-10-18 09:41:38 +02:00
dbpi_dirs = glob . glob ( os . path . join ( " src " , " plugins " , " * " , " db_plugin " ) )
dbpi_dirs + = glob . glob ( os . path . join ( " src " , " plugins " , " * " , " * " , " db_plugin " ) )
for pi in dbpi_dirs :
2018-07-15 12:52:59 +02:00
2018-07-16 07:16:36 +02:00
mod_name = " _ " + os . path . split ( os . path . split ( pi ) [ - 2 ] ) [ - 1 ] + " _dbpi "
2018-07-15 12:52:59 +02:00
2018-10-18 09:41:38 +02:00
pi_sources = glob . glob ( os . path . join ( pi , " *.cc " ) )
2018-07-15 12:52:59 +02:00
2018-10-18 09:41:38 +02:00
pi_ext = Library ( config . root + ' .db_plugins. ' + mod_name ,
define_macros = config . macros ( ) + [ ( ' MAKE_DB_PLUGIN_LIBRARY ' , 1 ) ] ,
include_dirs = [ os . path . join ( " src " , " plugins " , " common " ) ,
_db_path , _tl_path , _gsi_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _db ' , _db_path ) ] ,
language = ' c++ ' ,
extra_link_args = config . link_args ( mod_name ) ,
extra_compile_args = config . compile_args ( mod_name ) ,
sources = pi_sources )
2018-07-16 07:12:11 +02:00
2018-07-16 07:16:36 +02:00
db_plugins . append ( pi_ext )
2018-10-21 05:46:12 +02:00
config . add_extension ( pi_ext )
2018-07-16 07:12:11 +02:00
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# tl extension library
2018-10-18 09:41:38 +02:00
tl_path = os . path . join ( " src " , " pymod " , " tl " )
tl_sources = set ( glob . glob ( os . path . join ( tl_path , " *.cc " ) ) )
2018-07-15 00:01:37 +02:00
2018-10-19 23:53:10 +02:00
tl = Extension ( config . root + ' .tlcore ' ,
2018-07-16 07:16:36 +02:00
define_macros = config . macros ( ) ,
2018-10-18 09:41:38 +02:00
include_dirs = [ _tl_path , _gsi_path , _pya_path ] ,
extra_objects = [ config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _pya ' , _pya_path ) ] ,
2018-10-19 23:53:10 +02:00
extra_link_args = config . link_args ( ' tlcore ' ) ,
2022-04-02 16:07:25 +02:00
extra_compile_args = config . compile_args ( ' tlcore ' ) ,
2018-10-18 09:41:38 +02:00
sources = list ( tl_sources ) )
2018-07-15 00:01:37 +02:00
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# db extension library
2018-10-18 09:41:38 +02:00
db_path = os . path . join ( " src " , " pymod " , " db " )
db_sources = set ( glob . glob ( os . path . join ( db_path , " *.cc " ) ) )
2018-07-15 12:12:05 +02:00
2018-10-19 23:53:10 +02:00
db = Extension ( config . root + ' .dbcore ' ,
2018-07-16 07:16:36 +02:00
define_macros = config . macros ( ) ,
2018-10-18 09:41:38 +02:00
include_dirs = [ _db_path , _tl_path , _gsi_path , _pya_path ] ,
extra_objects = [ config . path_of ( ' _db ' , _db_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _pya ' , _pya_path ) ] ,
2018-10-19 23:53:10 +02:00
extra_link_args = config . link_args ( ' dbcore ' ) ,
2022-04-02 16:07:25 +02:00
extra_compile_args = config . compile_args ( ' dbcore ' ) ,
2018-10-18 09:41:38 +02:00
sources = list ( db_sources ) )
2018-07-15 12:12:05 +02:00
2019-04-03 01:07:22 +02:00
# ------------------------------------------------------------------
# lib extension library
lib_path = os . path . join ( " src " , " pymod " , " lib " )
lib_sources = set ( glob . glob ( os . path . join ( lib_path , " *.cc " ) ) )
lib = Extension ( config . root + ' .libcore ' ,
define_macros = config . macros ( ) ,
2019-04-03 18:31:05 +02:00
include_dirs = [ _lib_path , _tl_path , _gsi_path , _pya_path ] ,
extra_objects = [ config . path_of ( ' _lib ' , _lib_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _pya ' , _pya_path ) ] ,
2019-04-03 01:07:22 +02:00
extra_link_args = config . link_args ( ' libcore ' ) ,
2022-04-02 16:07:25 +02:00
extra_compile_args = config . compile_args ( ' libcore ' ) ,
2019-04-03 01:07:22 +02:00
sources = list ( lib_sources ) )
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# rdb extension library
2018-10-18 09:41:38 +02:00
rdb_path = os . path . join ( " src " , " pymod " , " rdb " )
rdb_sources = set ( glob . glob ( os . path . join ( rdb_path , " *.cc " ) ) )
2018-07-15 12:12:05 +02:00
2018-10-19 23:53:10 +02:00
rdb = Extension ( config . root + ' .rdbcore ' ,
2018-07-16 07:16:36 +02:00
define_macros = config . macros ( ) ,
2019-04-03 18:31:05 +02:00
include_dirs = [ _rdb_path , _tl_path , _gsi_path , _pya_path ] ,
2018-10-18 09:41:38 +02:00
extra_objects = [ config . path_of ( ' _rdb ' , _rdb_path ) , config . path_of ( ' _tl ' , _tl_path ) , config . path_of ( ' _gsi ' , _gsi_path ) , config . path_of ( ' _pya ' , _pya_path ) ] ,
2018-10-19 23:53:10 +02:00
extra_link_args = config . link_args ( ' rdbcore ' ) ,
2022-04-02 16:07:25 +02:00
extra_compile_args = config . compile_args ( ' rdbcore ' ) ,
2018-10-18 09:41:38 +02:00
sources = list ( rdb_sources ) )
2018-07-15 12:12:05 +02:00
2022-05-12 01:53:16 +02:00
# ------------------------------------------------------------------
# lay extension library
lay_path = os . path . join ( " src " , " pymod " , " lay " )
lay_sources = set ( glob . glob ( os . path . join ( lay_path , " *.cc " ) ) )
lay = Extension ( config . root + ' .laycore ' ,
define_macros = config . macros ( ) ,
2022-05-15 18:45:07 +02:00
include_dirs = [ _laybasic_path ,
_layview_path ,
_img_path ,
_ant_path ,
_edt_path ,
_lym_path ,
_tl_path ,
_gsi_path ,
_pya_path ] ,
extra_objects = [ config . path_of ( ' _laybasic ' , _laybasic_path ) ,
config . path_of ( ' _layview ' , _layview_path ) ,
config . path_of ( ' _img ' , _img_path ) ,
config . path_of ( ' _ant ' , _ant_path ) ,
config . path_of ( ' _edt ' , _edt_path ) ,
config . path_of ( ' _lym ' , _lym_path ) ,
config . path_of ( ' _tl ' , _tl_path ) ,
config . path_of ( ' _gsi ' , _gsi_path ) ,
config . path_of ( ' _pya ' , _pya_path ) ] ,
2022-05-12 01:53:16 +02:00
extra_link_args = config . link_args ( ' laycore ' ) ,
extra_compile_args = config . compile_args ( ' laycore ' ) ,
sources = list ( lay_sources ) )
2018-07-15 12:12:05 +02:00
# ------------------------------------------------------------------
# Core setup function
2018-07-16 07:12:11 +02:00
if __name__ == ' __main__ ' :
2018-10-07 18:51:37 +02:00
setup ( name = config . root ,
version = config . version ( ) ,
license = ' GNU GPLv3 ' ,
description = ' KLayout standalone Python package ' ,
2022-02-05 10:23:03 +01:00
long_description = ' This package is a standalone distribution of KLayout \' s Python API. \n \n For more details see here: https://www.klayout.org/klayout-pypi ' ,
2018-10-07 18:51:37 +02:00
author = ' Matthias Koefferlein ' ,
author_email = ' matthias@klayout.de ' ,
2019-01-04 21:45:27 +01:00
classifiers = [
# Recommended classifiers
" Programming Language :: Python :: 2 " ,
" Programming Language :: Python :: 3 " ,
" License :: OSI Approved :: GNU General Public License v3 (GPLv3) " ,
" Operating System :: MacOS :: MacOS X " ,
" Operating System :: Microsoft :: Windows " ,
" Operating System :: POSIX :: Linux " ,
# Optional classifiers
" Topic :: Scientific/Engineering :: Electronic Design Automation (EDA) " ,
] ,
2019-11-12 01:10:50 +01:00
url = ' https://github.com/klayout/klayout ' ,
2018-10-20 00:53:37 +02:00
packages = find_packages ( ' src/pymod/distutils_src ' ) ,
package_dir = { ' ' : ' src/pymod/distutils_src ' } , # https://github.com/pypa/setuptools/issues/230
2022-08-27 12:44:37 +02:00
package_data = { config . root : [ " src/pymod/distutils_src/klayout/*.pyi " ] } ,
include_package_data = True ,
2022-05-15 18:45:07 +02:00
ext_modules = [ _tl , _gsi , _pya , _rba , _db , _lib , _rdb , _lym , _laybasic , _layview , _ant , _edt , _img ] + db_plugins + [ tl , db , lib , rdb , lay ] )