29
29
from distutils .command .install_lib import install_lib
30
30
from distutils .errors import DistutilsExecError
31
31
from distutils .util import get_platform
32
+ from distutils .dir_util import copy_tree
32
33
from distutils import log
33
34
from glob import glob
34
35
import os
41
42
42
43
CEXT_OPTIONS = [
43
44
('with-mysql-capi=' , None ,
44
- "Location of MySQL C API installation or path to mysql_config" )
45
+ "Location of MySQL C API installation or path to mysql_config" ),
46
+ ]
47
+
48
+ CEXT_STATIC_OPTIONS = [
49
+ ('static' , None ,
50
+ "Link C libraries statically with the C Extension" ),
45
51
]
46
52
47
53
INSTALL_OPTIONS = [
48
54
('byte-code-only=' , None ,
49
- "Remove Python .py files; leave byte code .pyc only" )
55
+ "Remove Python .py files; leave byte code .pyc only" ),
50
56
]
51
57
52
58
@@ -199,7 +205,7 @@ def remove_cext(distribution):
199
205
distribution .ext_modules .remove (ext_mod )
200
206
201
207
202
- class BuildMySQLExt (build_ext ):
208
+ class BuildExtDynamic (build_ext ):
203
209
204
210
"""Build Connector/Python C Extension"""
205
211
@@ -220,13 +226,13 @@ def _finalize_connector_c(self, connc_loc):
220
226
"""
221
227
platform = get_platform ()
222
228
self ._mysql_config_info = None
223
- min_version = BuildMySQLExt .min_connector_c_version
229
+ min_version = BuildExtDynamic .min_connector_c_version
224
230
225
231
err_invalid_loc = "MySQL C API location is invalid; was %s"
226
232
227
233
mysql_config = None
228
234
err_version = "MySQL C API {0}.{1}.{2} or later required" .format (
229
- * BuildMySQLExt .min_connector_c_version )
235
+ * BuildExtDynamic .min_connector_c_version )
230
236
231
237
if not os .path .exists (connc_loc ):
232
238
log .error (err_invalid_loc , connc_loc )
@@ -397,6 +403,62 @@ def run(self):
397
403
self .real_build_extensions ()
398
404
399
405
406
+ class BuildExtStatic (BuildExtDynamic ):
407
+
408
+ """Build and Link libraries statically with the C Extensions"""
409
+
410
+ user_options = build_ext .user_options + CEXT_OPTIONS
411
+
412
+ def finalize_options (self ):
413
+ self .set_undefined_options ('install' ,
414
+ ('with_mysql_capi' , 'with_mysql_capi' ))
415
+
416
+ build_ext .finalize_options (self )
417
+ self .connc_lib = os .path .join (self .build_temp , 'connc' , 'lib' )
418
+ self .connc_include = os .path .join (self .build_temp , 'connc' , 'include' )
419
+
420
+ if self .with_mysql_capi :
421
+ self ._finalize_connector_c (self .with_mysql_capi )
422
+
423
+ def _finalize_connector_c (self , connc_loc ):
424
+ if not os .path .isdir (connc_loc ):
425
+ log .error ("MySQL C API should be a directory" )
426
+ sys .exit (1 )
427
+
428
+ copy_tree (os .path .join (connc_loc , 'lib' ), self .connc_lib )
429
+ copy_tree (os .path .join (connc_loc , 'include' ), self .connc_include )
430
+
431
+ for lib_file in os .listdir (self .connc_lib ):
432
+ if os .name == 'posix' and not lib_file .endswith ('.a' ):
433
+ os .unlink (os .path .join (self .connc_lib , lib_file ))
434
+
435
+ def fix_compiler (self ):
436
+ BuildExtDynamic .fix_compiler (self )
437
+
438
+ extra_compile_args = []
439
+ extra_link_args = []
440
+
441
+ if os .name == 'posix' :
442
+ extra_compile_args = [
443
+ '-I%s' % self .connc_include
444
+ ]
445
+ extra_link_args = [
446
+ #'-lstdc++',
447
+ '-L%s' % self .connc_lib ,
448
+ '-lmysqlclient' ,
449
+ ]
450
+
451
+ if not extra_compile_args and not extra_link_args :
452
+ return
453
+
454
+ for ext in self .extensions :
455
+ if extra_compile_args :
456
+ ext .extra_compile_args .extend (extra_compile_args )
457
+ if extra_link_args :
458
+ ext .extra_link_args .extend (extra_link_args )
459
+
460
+
461
+
400
462
class InstallLib (install_lib ):
401
463
402
464
user_options = install_lib .user_options + CEXT_OPTIONS + INSTALL_OPTIONS
@@ -435,19 +497,24 @@ class Install(install):
435
497
436
498
description = "install MySQL Connector/Python"
437
499
438
- user_options = install .user_options + CEXT_OPTIONS + INSTALL_OPTIONS
500
+ user_options = install .user_options + CEXT_OPTIONS + INSTALL_OPTIONS + \
501
+ CEXT_STATIC_OPTIONS
439
502
440
- boolean_options = ['byte-code-only' ]
503
+ boolean_options = ['byte-code-only' , 'static' ]
441
504
need_ext = False
442
505
443
506
def initialize_options (self ):
444
507
install .initialize_options (self )
445
508
self .with_mysql_capi = None
446
509
self .byte_code_only = None
510
+ self .static = None
447
511
448
512
def finalize_options (self ):
449
513
install .finalize_options (self )
450
514
515
+ if self .static :
516
+ self .distribution .cmdclass ['build_ext' ] = BuildExtStatic
517
+
451
518
if self .byte_code_only is None :
452
519
self .byte_code_only = False
453
520
0 commit comments