@@ -364,6 +364,57 @@ def find_module_file(module, dirlist):
364364 return os .path .join (dirs [0 ], module )
365365
366366
367+ def parse_cflags (flags ):
368+ """Parse a string with compiler flags (-I, -D, -U, extra)
369+
370+ Distutils appends extra args to the compiler arguments. Some flags like
371+ -I must appear earlier. Otherwise the pre-processor picks up files
372+ from system inclue directories.
373+ """
374+ include_dirs = []
375+ define_macros = []
376+ undef_macros = []
377+ extra_compile_args = []
378+ if flags is not None :
379+ # shlex.split(None) reads from stdin
380+ for token in shlex .split (flags ):
381+ switch = token [0 :2 ]
382+ value = token [2 :]
383+ if switch == '-I' :
384+ include_dirs .append (value )
385+ elif switch == '-D' :
386+ key , _ , val = value .partition ("=" )
387+ if not val :
388+ val = None
389+ define_macros .append ((key , val ))
390+ elif switch == '-U' :
391+ undef_macros .append (value )
392+ else :
393+ extra_compile_args .append (token )
394+
395+ return include_dirs , define_macros , undef_macros , extra_compile_args
396+
397+
398+ def parse_ldflags (flags ):
399+ """Parse a string with linker flags (-L, -l, extra)"""
400+ library_dirs = []
401+ libraries = []
402+ extra_link_args = []
403+ if flags is not None :
404+ # shlex.split(None) reads from stdin
405+ for token in shlex .split (flags ):
406+ switch = token [0 :2 ]
407+ value = token [2 :]
408+ if switch == '-L' :
409+ library_dirs .append (value )
410+ elif switch == '-l' :
411+ libraries .append (value )
412+ else :
413+ extra_link_args .append (token )
414+
415+ return library_dirs , libraries , extra_link_args
416+
417+
367418class PyBuildExt (build_ext ):
368419
369420 def __init__ (self , dist ):
@@ -1469,59 +1520,39 @@ def detect_expat_elementtree(self):
14691520 #
14701521 # More information on Expat can be found at www.libexpat.org.
14711522 #
1472- if '--with-system-expat' in sysconfig .get_config_var ("CONFIG_ARGS" ):
1473- expat_inc = []
1474- extra_compile_args = []
1475- expat_lib = ['expat' ]
1476- expat_sources = []
1477- expat_depends = []
1478- else :
1479- expat_inc = [os .path .join (self .srcdir , 'Modules' , 'expat' )]
1480- extra_compile_args = []
1481- # bpo-44394: libexpat uses isnan() of math.h and needs linkage
1482- # against the libm
1483- expat_lib = ['m' ]
1484- expat_sources = ['expat/xmlparse.c' ,
1485- 'expat/xmlrole.c' ,
1486- 'expat/xmltok.c' ]
1487- expat_depends = ['expat/ascii.h' ,
1488- 'expat/asciitab.h' ,
1489- 'expat/expat.h' ,
1490- 'expat/expat_config.h' ,
1491- 'expat/expat_external.h' ,
1492- 'expat/internal.h' ,
1493- 'expat/latin1tab.h' ,
1494- 'expat/utf8tab.h' ,
1495- 'expat/xmlrole.h' ,
1496- 'expat/xmltok.h' ,
1497- 'expat/xmltok_impl.h'
1498- ]
1499-
1500- cc = sysconfig .get_config_var ('CC' ).split ()[0 ]
1501- ret = run_command (
1502- '"%s" -Werror -Wno-unreachable-code -E -xc /dev/null >/dev/null 2>&1' % cc )
1503- if ret == 0 :
1504- extra_compile_args .append ('-Wno-unreachable-code' )
1523+ cflags = parse_cflags (sysconfig .get_config_var ("EXPAT_CFLAGS" ))
1524+ include_dirs , define_macros , undef_macros , extra_compile_args = cflags
1525+ # ldflags includes either system libexpat or full path to
1526+ # our static libexpat.a.
1527+ ldflags = parse_ldflags (sysconfig .get_config_var ("EXPAT_LDFLAGS" ))
1528+ library_dirs , libraries , extra_link_args = ldflags
1529+
1530+ expat_depends = []
1531+ libexpat_a = sysconfig .get_config_var ("LIBEXPAT_A" )
1532+ if libexpat_a :
1533+ expat_depends .append (libexpat_a )
15051534
15061535 self .add (Extension ('pyexpat' ,
1536+ include_dirs = include_dirs ,
1537+ define_macros = define_macros ,
1538+ undef_macros = undef_macros ,
15071539 extra_compile_args = extra_compile_args ,
1508- include_dirs = expat_inc ,
1509- libraries = expat_lib ,
1510- sources = ['pyexpat.c' ] + expat_sources ,
1540+ library_dirs = library_dirs ,
1541+ libraries = libraries ,
1542+ extra_link_args = extra_link_args ,
1543+ sources = ['pyexpat.c' ],
15111544 depends = expat_depends ))
15121545
15131546 # Fredrik Lundh's cElementTree module. Note that this also
15141547 # uses expat (via the CAPI hook in pyexpat).
1515-
1516- if os .path .isfile (os .path .join (self .srcdir , 'Modules' , '_elementtree.c' )):
1517- self .add (Extension ('_elementtree' ,
1518- include_dirs = expat_inc ,
1519- libraries = expat_lib ,
1520- sources = ['_elementtree.c' ],
1521- depends = ['pyexpat.c' , * expat_sources ,
1522- * expat_depends ]))
1523- else :
1524- self .missing .append ('_elementtree' )
1548+ self .add (Extension ('_elementtree' ,
1549+ include_dirs = include_dirs ,
1550+ define_macros = define_macros ,
1551+ undef_macros = undef_macros ,
1552+ extra_compile_args = extra_compile_args ,
1553+ # no EXPAT_LDFLAGS
1554+ sources = ['_elementtree.c' ],
1555+ depends = ['pyexpat.c' , * expat_depends ]))
15251556
15261557 def detect_multibytecodecs (self ):
15271558 # Hye-Shik Chang's CJKCodecs modules.
@@ -2019,24 +2050,27 @@ def detect_decimal(self):
20192050 # Stefan Krah's _decimal module
20202051 sources = ['_decimal/_decimal.c' ]
20212052 depends = ['_decimal/docstrings.h' ]
2022- define_macros = []
2023-
2024- cflags = sysconfig .get_config_var ("DECIMAL_CFLAGS" )
2025- extra_compile_args = shlex .split (cflags ) if cflags else None
2053+
2054+ cflags = parse_cflags (sysconfig .get_config_var ("DECIMAL_CFLAGS" ))
2055+ include_dirs , define_macros , undef_macros , extra_compile_args = cflags
20262056 # ldflags includes either system libmpdec or full path to
20272057 # our static libmpdec.a.
2028- ldflags = sysconfig .get_config_var ("DECIMAL_LDFLAGS" )
2029- extra_link_args = shlex . split ( ldflags ) if ldflags else None
2030-
2058+ ldflags = parse_ldflags ( sysconfig .get_config_var ("DECIMAL_LDFLAGS" ) )
2059+ library_dirs , libraries , extra_link_args = ldflags
2060+
20312061 libmpdec_a = sysconfig .get_config_var ("LIBMPDEC_A" )
20322062 if libmpdec_a :
20332063 depends .append (libmpdec_a )
20342064
20352065 # Uncomment for extra functionality:
20362066 #define_macros.append(('EXTRA_FUNCTIONALITY', 1))
20372067 self .add (Extension ('_decimal' ,
2068+ include_dirs = include_dirs ,
20382069 define_macros = define_macros ,
2070+ undef_macros = undef_macros ,
20392071 extra_compile_args = extra_compile_args ,
2072+ library_dirs = library_dirs ,
2073+ libraries = libraries ,
20402074 extra_link_args = extra_link_args ,
20412075 sources = sources ,
20422076 depends = depends ))
0 commit comments