35
35
import os
36
36
import shlex
37
37
import struct
38
- from subprocess import Popen , PIPE , STDOUT
38
+ from subprocess import Popen , PIPE , STDOUT , check_call
39
39
import sys
40
40
import platform
41
+ import shutil
42
+
41
43
42
44
ARCH_64BIT = sys .maxsize > 2 ** 32 # Works with Python 2.6 and greater
43
45
py_arch = '64-bit' if ARCH_64BIT else '32-bit'
44
46
45
47
CEXT_OPTIONS = [
46
48
('with-mysql-capi=' , None ,
47
49
"Location of MySQL C API installation or path to mysql_config" ),
50
+ ('extra-compile-args=' , None ,
51
+ "Extra compile args" ),
52
+ ('extra-link-args=' , None ,
53
+ "Extra link args" )
48
54
]
49
55
50
56
CEXT_STATIC_OPTIONS = [
@@ -125,7 +131,11 @@ def unix_lib_is64bit(lib_file):
125
131
lib_file = mysqlclient_libs [- 1 ]
126
132
127
133
log .debug ("# Using file command to test lib_file {0}" .format (lib_file ))
128
- prc = Popen (['file' , '-L' , lib_file ], stdin = PIPE , stderr = STDOUT ,
134
+ if platform .uname () == 'SunOS' :
135
+ cmd_list = ['file' , '-L' , lib_file ]
136
+ else :
137
+ cmd_list = ['file' , '-L' , lib_file ]
138
+ prc = Popen (cmd_list , stdin = PIPE , stderr = STDOUT ,
129
139
stdout = PIPE )
130
140
stdout = prc .communicate ()[0 ]
131
141
stdout = stdout .split (':' )[1 ]
@@ -152,6 +162,9 @@ def parse_mysql_config_info(options, stdout):
152
162
libs = shlex .split (info ['libs' ])
153
163
info ['lib_dir' ] = libs [0 ].replace ('-L' , '' )
154
164
info ['libs' ] = [ lib .replace ('-l' , '' ) for lib in libs [1 :] ]
165
+ if platform .uname ()[0 ] == 'SunOS' :
166
+ info ['lib_dir' ] = info ['lib_dir' ].replace ('-R' , '' )
167
+ info ['libs' ] = [lib .replace ('-R' , '' ) for lib in info ['libs' ]]
155
168
log .debug ("# info['libs']: " )
156
169
for lib in info ['libs' ]:
157
170
log .debug ("# {0}" .format (lib ))
@@ -185,7 +198,17 @@ def get_mysql_config_info(mysql_config):
185
198
# Try to figure out the architecture
186
199
info ['arch' ] = None
187
200
if os .name == 'posix' :
188
- pathname = os .path .join (info ['lib_dir' ], 'lib' + info ['libs' ][0 ]) + '*'
201
+ if platform .uname ()[0 ] == 'SunOS' :
202
+ print ("info['lib_dir']: {0}" .format (info ['lib_dir' ]))
203
+ print ("info['libs'][0]: {0}" .format (info ['libs' ][0 ]))
204
+ pathname = os .path .abspath (os .path .join (info ['lib_dir' ],
205
+ 'lib' ,
206
+ info ['libs' ][0 ])) + '/*'
207
+ else :
208
+ pathname = os .path .join (info ['lib_dir' ],
209
+ 'lib' + info ['libs' ][0 ]) + '*'
210
+ print ("# Looking mysqlclient_lib at path: {0}" .format (pathname ))
211
+ log .debug ("# searching mysqlclient_lib at: %s" , pathname )
189
212
libs = glob (pathname )
190
213
mysqlclient_libs = []
191
214
for filepath in libs :
@@ -205,7 +228,12 @@ def get_mysql_config_info(mysql_config):
205
228
log .debug ("#+ {0}" .format (mysqlclient_lib ))
206
229
log .debug ("# tested mysqlclient_lib[-1]: "
207
230
"{0}" .format (mysqlclient_libs [- 1 ]))
208
- proc = Popen (['file' , '-L' , mysqlclient_libs [- 1 ]], stdout = PIPE ,
231
+ if platform .uname ()[0 ] == 'SunOS' :
232
+ print ("mysqlclient_lib: {0}" .format (mysqlclient_libs [- 1 ]))
233
+ cmd_list = ['file' , mysqlclient_libs [- 1 ]]
234
+ else :
235
+ cmd_list = ['file' , '-L' , mysqlclient_libs [- 1 ]]
236
+ proc = Popen (cmd_list , stdout = PIPE ,
209
237
universal_newlines = True )
210
238
stdout , _ = proc .communicate ()
211
239
stdout = stdout .split (':' )[1 ]
@@ -258,6 +286,8 @@ class BuildExtDynamic(build_ext):
258
286
259
287
def initialize_options (self ):
260
288
build_ext .initialize_options (self )
289
+ self .extra_compile_args = None
290
+ self .extra_link_args = None
261
291
self .with_mysql_capi = None
262
292
263
293
def _finalize_connector_c (self , connc_loc ):
@@ -367,10 +397,7 @@ def _finalize_connector_c(self, connc_loc):
367
397
368
398
# We try to offer a nice message when the architecture of Python
369
399
# is not the same as MySQL Connector/C binaries.
370
- py_arch = '64-bit' if ARCH_64BIT else '32-bit'
371
- log .debug ("# Python architecture: {0}" .format (py_arch ))
372
- log .debug ("# Python ARCH_64BIT: {0}" .format (ARCH_64BIT ))
373
- log .debug ("# self.arch: {0}" .format (self .arch ))
400
+ print ("# self.arch: {0}" .format (self .arch ))
374
401
if ARCH_64BIT != connc_64bit :
375
402
log .error ("Python is {0}, but does not "
376
403
"match MySQL C API {1} architecture, "
@@ -381,11 +408,17 @@ def _finalize_connector_c(self, connc_loc):
381
408
sys .exit (1 )
382
409
383
410
def finalize_options (self ):
384
- self .set_undefined_options ('install' ,
385
- ('with_mysql_capi' , 'with_mysql_capi' ))
411
+ self .set_undefined_options (
412
+ 'install' ,
413
+ ('extra_compile_args' , 'extra_compile_args' ),
414
+ ('extra_link_args' , 'extra_link_args' ),
415
+ ('with_mysql_capi' , 'with_mysql_capi' ))
386
416
387
417
build_ext .finalize_options (self )
388
418
419
+ print ("# Python architecture: {0}" .format (py_arch ))
420
+ print ("# Python ARCH_64BIT: {0}" .format (ARCH_64BIT ))
421
+
389
422
if self .with_mysql_capi :
390
423
self ._finalize_connector_c (self .with_mysql_capi )
391
424
@@ -430,6 +463,13 @@ def fix_compiler(self):
430
463
# Add system headers to Extensions extra_compile_args
431
464
sysheaders = [ '-isystem' + dir for dir in cc .include_dirs ]
432
465
for ext in self .extensions :
466
+ # Add extra compile args
467
+ if self .extra_compile_args :
468
+ ext .extra_compile_args .extend (self .extra_compile_args .split ())
469
+ # Add extra link args
470
+ if self .extra_link_args :
471
+ ext .extra_link_args .extend (self .extra_link_args .split ())
472
+ # Add system headers
433
473
for sysheader in sysheaders :
434
474
if sysheader not in ext .extra_compile_args :
435
475
ext .extra_compile_args .append (sysheader )
@@ -440,10 +480,16 @@ def fix_compiler(self):
440
480
441
481
def run (self ):
442
482
"""Run the command"""
443
- if not self .with_mysql_capi :
444
- return
445
-
446
483
if os .name == 'nt' :
484
+ for ext in self .extensions :
485
+ # Use the multithread, static version of the run-time library
486
+ ext .extra_compile_args .append ("/MT" )
487
+ # Add extra compile args
488
+ if self .extra_compile_args :
489
+ ext .extra_compile_args .extend (self .extra_compile_args .split ())
490
+ # Add extra link args
491
+ if self .extra_link_args :
492
+ ext .extra_link_args .extend (self .extra_link_args .split ())
447
493
build_ext .run (self )
448
494
else :
449
495
self .real_build_extensions = self .build_extensions
@@ -460,11 +506,27 @@ class BuildExtStatic(BuildExtDynamic):
460
506
user_options = build_ext .user_options + CEXT_OPTIONS
461
507
462
508
def finalize_options (self ):
509
+ install_obj = self .distribution .get_command_obj ('install' )
510
+ install_obj .with_mysql_capi = self .with_mysql_capi
511
+ install_obj .extra_compile_args = self .extra_compile_args
512
+ install_obj .extra_link_args = self .extra_link_args
513
+ install_obj .static = True
514
+
515
+ options_pairs = []
516
+ if not self .extra_compile_args :
517
+ options_pairs .append (('extra_compile_args' , 'extra_compile_args' ))
518
+ if not self .extra_link_args :
519
+ options_pairs .append (('extra_link_args' , 'extra_link_args' ))
463
520
if not self .with_mysql_capi :
464
- self .set_undefined_options ('install' ,
465
- ('with_mysql_capi' , 'with_mysql_capi' ))
521
+ options_pairs .append (('with_mysql_capi' , 'with_mysql_capi' ))
522
+ if options_pairs :
523
+ self .set_undefined_options ('install' , * options_pairs )
466
524
467
525
build_ext .finalize_options (self )
526
+
527
+ print ("# Python architecture: {0}" .format (py_arch ))
528
+ print ("# Python ARCH_64BIT: {0}" .format (ARCH_64BIT ))
529
+
468
530
self .connc_lib = os .path .join (self .build_temp , 'connc' , 'lib' )
469
531
self .connc_include = os .path .join (self .build_temp , 'connc' , 'include' )
470
532
@@ -500,7 +562,8 @@ def fix_compiler(self):
500
562
if os .name == 'posix' :
501
563
include_dirs .append (self .connc_include )
502
564
library_dirs .append (self .connc_lib )
503
- libraries .append ("mysqlclient" )
565
+ if self .with_mysql_capi :
566
+ libraries .append ("mysqlclient" )
504
567
505
568
# As we statically link and the "libmysqlclient.a" library
506
569
# carry no information what it depends on, we need to
@@ -512,6 +575,12 @@ def fix_compiler(self):
512
575
ext .include_dirs .extend (include_dirs )
513
576
ext .library_dirs .extend (library_dirs )
514
577
ext .libraries .extend (libraries )
578
+ # Add extra compile args
579
+ if self .extra_compile_args :
580
+ ext .extra_compile_args .extend (self .extra_compile_args .split ())
581
+ # Add extra link args
582
+ if self .extra_link_args :
583
+ ext .extra_link_args .extend (self .extra_link_args .split ())
515
584
516
585
517
586
class InstallLib (install_lib ):
@@ -560,23 +629,27 @@ class Install(install):
560
629
561
630
def initialize_options (self ):
562
631
install .initialize_options (self )
632
+ self .extra_compile_args = None
633
+ self .extra_link_args = None
563
634
self .with_mysql_capi = None
564
635
self .byte_code_only = None
565
636
self .static = None
566
637
567
638
def finalize_options (self ):
568
639
if self .static :
569
- log .info ("Linking CExtension statically with MySQL libraries" )
640
+ log .info ("Linking C Extension statically with libraries" )
570
641
self .distribution .cmdclass ['build_ext' ] = BuildExtStatic
571
642
572
643
if self .byte_code_only is None :
573
644
self .byte_code_only = False
574
645
646
+ build_ext_obj = self .distribution .get_command_obj ('build_ext' )
647
+ build_ext_obj .with_mysql_capi = self .with_mysql_capi
648
+ build_ext_obj .extra_compile_args = self .extra_compile_args
649
+ build_ext_obj .extra_link_args = self .extra_link_args
650
+ build_ext_obj .static = self .static
651
+
575
652
if self .with_mysql_capi :
576
- build_ext = self .distribution .get_command_obj ('build_ext' )
577
- build_ext .with_mysql_capi = self .with_mysql_capi
578
- build = self .distribution .get_command_obj ('build_ext' )
579
- build .with_mysql_capi = self .with_mysql_capi
580
653
self .need_ext = True
581
654
582
655
if not self .need_ext :
@@ -586,7 +659,7 @@ def finalize_options(self):
586
659
587
660
def run (self ):
588
661
if not self .need_ext :
589
- log .info ("Not Installing C Extension" )
662
+ log .info ("Not Installing MySQL C Extension" )
590
663
else :
591
- log .info ("Installing C Extension" )
664
+ log .info ("Installing MySQL C Extension" )
592
665
install .run (self )
0 commit comments