1import os, sys, subprocess 2import os.path as osp 3import configparser 4from setuptools import setup, Extension 5from distutils.dist import Distribution 6 7setuptools_extra_kwargs = { 8 "install_requires": ["numpy>=1.9","cftime"], 9 "setup_requires": ['setuptools>=18.0', "cython>=0.19"], 10 "entry_points": { 11 'console_scripts': [ 12 'ncinfo = netCDF4.utils:ncinfo', 13 'nc4tonc3 = netCDF4.utils:nc4tonc3', 14 'nc3tonc4 = netCDF4.utils:nc3tonc4', 15 ] 16 }, 17} 18 19open_kwargs = {'encoding': 'utf-8'} 20 21 22def check_hdf5version(hdf5_includedir): 23 try: 24 f = open(os.path.join(hdf5_includedir, 'H5public.h'), **open_kwargs) 25 except IOError: 26 return None 27 hdf5_version = None 28 for line in f: 29 if line.startswith('#define H5_VERS_INFO'): 30 hdf5_version = line.split('"')[1] 31 return hdf5_version 32 33def get_hdf5_version(direc): 34 # check to see if hdf5 headers in direc, return version number or None 35 hdf5_version = None 36 sys.stdout.write('checking %s ...\n' % direc) 37 hdf5_version = check_hdf5version(direc) 38 if hdf5_version is None: 39 sys.stdout.write('hdf5 headers not found in %s\n' % direc) 40 return None 41 else: 42 sys.stdout.write('%s headers found in %s\n' % 43 (hdf5_version,direc)) 44 return hdf5_version 45 46def check_ifnetcdf4(netcdf4_includedir): 47 try: 48 f = open(os.path.join(netcdf4_includedir, 'netcdf.h'), **open_kwargs) 49 except IOError: 50 return False 51 isnetcdf4 = False 52 for line in f: 53 if line.startswith('nc_inq_compound'): 54 isnetcdf4 = True 55 return isnetcdf4 56 57 58def check_api(inc_dirs,netcdf_lib_version): 59 has_rename_grp = False 60 has_nc_inq_path = False 61 has_nc_inq_format_extended = False 62 has_cdf5_format = False 63 has_nc_open_mem = False 64 has_nc_create_mem = False 65 has_parallel_support = False 66 has_parallel4_support = False 67 has_pnetcdf_support = False 68 69 for d in inc_dirs: 70 try: 71 f = open(os.path.join(d, 'netcdf.h'), **open_kwargs) 72 except IOError: 73 continue 74 75 has_nc_open_mem = os.path.exists(os.path.join(d, 'netcdf_mem.h')) 76 77 for line in f: 78 if line.startswith('nc_rename_grp'): 79 has_rename_grp = True 80 if line.startswith('nc_inq_path'): 81 has_nc_inq_path = True 82 if line.startswith('nc_inq_format_extended'): 83 has_nc_inq_format_extended = True 84 if line.startswith('#define NC_FORMAT_64BIT_DATA'): 85 has_cdf5_format = True 86 87 if has_nc_open_mem: 88 try: 89 f = open(os.path.join(d, 'netcdf_mem.h'), **open_kwargs) 90 except IOError: 91 continue 92 for line in f: 93 if line.startswith('EXTERNL int nc_create_mem'): 94 has_nc_create_mem = True 95 96 ncmetapath = os.path.join(d,'netcdf_meta.h') 97 if os.path.exists(ncmetapath): 98 for line in open(ncmetapath): 99 if line.startswith('#define NC_HAS_CDF5'): 100 has_cdf5_format = bool(int(line.split()[2])) 101 if line.startswith('#define NC_HAS_PARALLEL'): 102 has_parallel_support = bool(int(line.split()[2])) 103 if line.startswith('#define NC_HAS_PARALLEL4'): 104 has_parallel4_support = bool(int(line.split()[2])) 105 if line.startswith('#define NC_HAS_PNETCDF'): 106 has_pnetcdf_support = bool(int(line.split()[2])) 107 # NC_HAS_PARALLEL4 missing in 4.6.1 (issue #964) 108 if not has_parallel4_support and has_parallel_support and not has_pnetcdf_support: 109 has_parallel4_support = True 110 # for 4.6.1, if NC_HAS_PARALLEL=NC_HAS_PNETCDF=1, guess that 111 # parallel HDF5 is enabled (must guess since there is no 112 # NC_HAS_PARALLEL4) 113 elif netcdf_lib_version == "4.6.1" and not has_parallel4_support and has_parallel_support: 114 has_parallel4_support = True 115 break 116 117 return has_rename_grp, has_nc_inq_path, has_nc_inq_format_extended, \ 118 has_cdf5_format, has_nc_open_mem, has_nc_create_mem, \ 119 has_parallel4_support, has_pnetcdf_support 120 121 122def getnetcdfvers(libdirs): 123 """ 124 Get the version string for the first netcdf lib found in libdirs. 125 (major.minor.release). If nothing found, return None. 126 """ 127 128 import os, re, sys, ctypes 129 130 if sys.platform.startswith('win'): 131 regexp = re.compile('^netcdf.dll$') 132 elif sys.platform.startswith('cygwin'): 133 bindirs = [] 134 for d in libdirs: 135 bindirs.append(os.path.dirname(d) + '/bin') 136 regexp = re.compile(r'^cygnetcdf-\d.dll') 137 elif sys.platform.startswith('darwin'): 138 regexp = re.compile(r'^libnetcdf.dylib') 139 else: 140 regexp = re.compile(r'^libnetcdf.so') 141 142 if sys.platform.startswith('cygwin'): 143 dirs = bindirs 144 else: 145 dirs = libdirs 146 for d in dirs: 147 try: 148 candidates = [x for x in os.listdir(d) if regexp.match(x)] 149 if len(candidates) != 0: 150 candidates.sort( 151 key=lambda x: len(x)) # Prefer libfoo.so to libfoo.so.X.Y.Z 152 path = os.path.abspath(os.path.join(d, candidates[0])) 153 lib = ctypes.cdll.LoadLibrary(path) 154 inq_libvers = lib.nc_inq_libvers 155 inq_libvers.restype = ctypes.c_char_p 156 vers = lib.nc_inq_libvers() 157 return vers.split()[0] 158 except Exception: 159 pass # We skip invalid entries, because that's what the C compiler does 160 161 return None 162 163def extract_version(CYTHON_FNAME): 164 version = None 165 with open(CYTHON_FNAME) as fi: 166 for line in fi: 167 if (line.startswith('__version__')): 168 _, version = line.split('=') 169 version = version.strip()[1:-1] # Remove quotation characters. 170 break 171 return version 172 173 174HDF5_dir = os.environ.get('HDF5_DIR') 175HDF5_incdir = os.environ.get('HDF5_INCDIR') 176HDF5_libdir = os.environ.get('HDF5_LIBDIR') 177netCDF4_dir = os.environ.get('NETCDF4_DIR') 178netCDF4_incdir = os.environ.get('NETCDF4_INCDIR') 179netCDF4_libdir = os.environ.get('NETCDF4_LIBDIR') 180szip_dir = os.environ.get('SZIP_DIR') 181szip_libdir = os.environ.get('SZIP_LIBDIR') 182szip_incdir = os.environ.get('SZIP_INCDIR') 183hdf4_dir = os.environ.get('HDF4_DIR') 184hdf4_libdir = os.environ.get('HDF4_LIBDIR') 185hdf4_incdir = os.environ.get('HDF4_INCDIR') 186jpeg_dir = os.environ.get('JPEG_DIR') 187jpeg_libdir = os.environ.get('JPEG_LIBDIR') 188jpeg_incdir = os.environ.get('JPEG_INCDIR') 189curl_dir = os.environ.get('CURL_DIR') 190curl_libdir = os.environ.get('CURL_LIBDIR') 191curl_incdir = os.environ.get('CURL_INCDIR') 192mpi_incdir = os.environ.get('MPI_INCDIR') 193 194USE_NCCONFIG = os.environ.get('USE_NCCONFIG') 195if USE_NCCONFIG is not None: 196 USE_NCCONFIG = bool(int(USE_NCCONFIG)) 197USE_SETUPCFG = os.environ.get('USE_SETUPCFG') 198# override use of setup.cfg with env var. 199if USE_SETUPCFG is not None: 200 USE_SETUPCFG = bool(int(USE_SETUPCFG)) 201else: 202 USE_SETUPCFG = True 203 204setup_cfg = 'setup.cfg' 205# contents of setup.cfg will override env vars, unless 206# USE_SETUPCFG evaluates to False. 207ncconfig = None 208use_ncconfig = None 209if USE_SETUPCFG and os.path.exists(setup_cfg): 210 sys.stdout.write('reading from setup.cfg...\n') 211 config = configparser.ConfigParser() 212 config.read(setup_cfg) 213 try: 214 HDF5_dir = config.get("directories", "HDF5_dir") 215 except: 216 pass 217 try: 218 HDF5_libdir = config.get("directories", "HDF5_libdir") 219 except: 220 pass 221 try: 222 HDF5_incdir = config.get("directories", "HDF5_incdir") 223 except: 224 pass 225 try: 226 netCDF4_dir = config.get("directories", "netCDF4_dir") 227 except: 228 pass 229 try: 230 netCDF4_libdir = config.get("directories", "netCDF4_libdir") 231 except: 232 pass 233 try: 234 netCDF4_incdir = config.get("directories", "netCDF4_incdir") 235 except: 236 pass 237 try: 238 szip_dir = config.get("directories", "szip_dir") 239 except: 240 pass 241 try: 242 szip_libdir = config.get("directories", "szip_libdir") 243 except: 244 pass 245 try: 246 szip_incdir = config.get("directories", "szip_incdir") 247 except: 248 pass 249 try: 250 hdf4_dir = config.get("directories", "hdf4_dir") 251 except: 252 pass 253 try: 254 hdf4_libdir = config.get("directories", "hdf4_libdir") 255 except: 256 pass 257 try: 258 hdf4_incdir = config.get("directories", "hdf4_incdir") 259 except: 260 pass 261 try: 262 jpeg_dir = config.get("directories", "jpeg_dir") 263 except: 264 pass 265 try: 266 jpeg_libdir = config.get("directories", "jpeg_libdir") 267 except: 268 pass 269 try: 270 jpeg_incdir = config.get("directories", "jpeg_incdir") 271 except: 272 pass 273 try: 274 curl_dir = config.get("directories", "curl_dir") 275 except: 276 pass 277 try: 278 curl_libdir = config.get("directories", "curl_libdir") 279 except: 280 pass 281 try: 282 curl_incdir = config.get("directories", "curl_incdir") 283 except: 284 pass 285 try: 286 mpi_incdir = config.get("directories","mpi_incdir") 287 except: 288 pass 289 try: 290 use_ncconfig = config.getboolean("options", "use_ncconfig") 291 except: 292 pass 293 try: 294 ncconfig = config.get("options", "ncconfig") 295 except: 296 pass 297 298try: 299 if ncconfig is None: 300 if netCDF4_dir is not None: 301 ncconfig = os.path.join(netCDF4_dir, 'bin/nc-config') 302 else: # otherwise, just hope it's in the users PATH. 303 ncconfig = 'nc-config' 304 HAS_NCCONFIG = subprocess.call([ncconfig, '--libs'], 305 stdout=subprocess.PIPE) == 0 306except OSError: 307 HAS_NCCONFIG = False 308 309# make sure USE_NCCONFIG from environment takes 310# precendence over use_ncconfig from setup.cfg (issue #341). 311if USE_NCCONFIG is None and use_ncconfig is not None: 312 USE_NCCONFIG = use_ncconfig 313elif USE_NCCONFIG is None: 314 # if nc-config exists, and USE_NCCONFIG not set, try to use it. 315 if HAS_NCCONFIG: USE_NCCONFIG=True 316#elif USE_NCCONFIG is None: 317# USE_NCCONFIG = False # don't try to use nc-config if USE_NCCONFIG not set 318 319try: 320 HAS_PKG_CONFIG = subprocess.call(['pkg-config', '--libs', 'hdf5'], 321 stdout=subprocess.PIPE) == 0 322except OSError: 323 HAS_PKG_CONFIG = False 324 325def _populate_hdf5_info(dirstosearch, inc_dirs, libs, lib_dirs): 326 global HDF5_incdir, HDF5_dir, HDF5_libdir 327 328 nohdf5dirs = HDF5_incdir is None and HDF5_libdir is None and HDF5_dir is None 329 if HAS_PKG_CONFIG and nohdf5dirs: 330 # if HDF5 dirs not specified, and pkg-config available, use it 331 dep = subprocess.Popen(['pkg-config', '--cflags', 'hdf5'], 332 stdout=subprocess.PIPE).communicate()[0] 333 inc_dirs.extend([str(i[2:].decode()) for i in dep.split() if 334 i[0:2].decode() == '-I']) 335 dep = subprocess.Popen(['pkg-config', '--libs', 'hdf5'], 336 stdout=subprocess.PIPE).communicate()[0] 337 libs.extend( 338 [str(l[2:].decode()) for l in dep.split() if l[0:2].decode() == '-l']) 339 lib_dirs.extend( 340 [str(l[2:].decode()) for l in dep.split() if l[0:2].decode() == '-L']) 341 dep = subprocess.Popen(['pkg-config', '--cflags', 'hdf5'], 342 stdout=subprocess.PIPE).communicate()[0] 343 inc_dirs.extend( 344 [str(i[2:].decode()) for i in dep.split() if i[0:2].decode() == '-I']) 345 else: 346 if HDF5_incdir is None and HDF5_dir is None: 347 sys.stdout.write(""" 348 HDF5_DIR environment variable not set, checking some standard locations ..\n""") 349 for direc in dirstosearch: 350 hdf5_version = get_hdf5_version(os.path.join(direc, 'include')) 351 if hdf5_version is None: 352 continue 353 else: 354 HDF5_dir = direc 355 HDF5_incdir = os.path.join(direc, 'include') 356 sys.stdout.write('%s found in %s\n' % 357 (hdf5_version,HDF5_dir)) 358 break 359 if HDF5_dir is None: 360 raise ValueError('did not find HDF5 headers') 361 else: 362 if HDF5_incdir is None: 363 HDF5_incdir = os.path.join(HDF5_dir, 'include') 364 hdf5_version = get_hdf5_version(HDF5_incdir) 365 if hdf5_version is None: 366 raise ValueError('did not find HDF5 headers in %s' % HDF5_incdir) 367 else: 368 sys.stdout.write('%s found in %s\n' % 369 (hdf5_version,HDF5_dir)) 370 371 if HDF5_libdir is None and HDF5_dir is not None: 372 HDF5_libdir = os.path.join(HDF5_dir, 'lib') 373 374 if HDF5_libdir is not None: lib_dirs.append(HDF5_libdir) 375 if HDF5_incdir is not None: inc_dirs.append(HDF5_incdir) 376 377 libs.extend(['hdf5_hl', 'hdf5']) 378 379 380dirstosearch = [] 381if os.environ.get("CONDA_PREFIX"): 382 dirstosearch.append(os.environ["CONDA_PREFIX"]) # linux,macosx 383 dirstosearch.append(os.path.join(os.environ["CONDA_PREFIX"],'Library')) # windows 384dirstosearch += [os.path.expanduser('~'), '/usr/local', '/sw', '/opt', 385 '/opt/local', '/usr'] 386 387# try nc-config first 388if USE_NCCONFIG and HAS_NCCONFIG: # Try nc-config. 389 sys.stdout.write('using %s...\n' % ncconfig) 390 dep = subprocess.Popen([ncconfig, '--libs'], 391 stdout=subprocess.PIPE).communicate()[0] 392 libs = [str(l[2:].decode()) for l in dep.split() if l[0:2].decode() == '-l'] 393 lib_dirs = [str(l[2:].decode()) for l in dep.split() if 394 l[0:2].decode() == '-L'] 395 dep = subprocess.Popen([ncconfig, '--cflags'], 396 stdout=subprocess.PIPE).communicate()[0] 397 inc_dirs = [str(i[2:].decode()) for i in dep.split() if 398 i[0:2].decode() == '-I'] 399 400 # check to see if hdf5 found in directories returned by nc-config 401 hdf5_version = None 402 for direc in inc_dirs: 403 hdf5_version = get_hdf5_version(direc) 404 if hdf5_version is not None: 405 break 406 # if hdf5 not found, search other standard locations (including those specified in env vars). 407 if hdf5_version is None: 408 sys.stdout.write('nc-config did provide path to HDF5 headers, search standard locations...') 409 _populate_hdf5_info(dirstosearch, inc_dirs, libs, lib_dirs) 410 411# If nc-config doesn't work, fall back on brute force method. 412else: 413 lib_dirs = [] 414 inc_dirs = [] 415 libs = [] 416 417 # _populate_hdf5_info will use HDF5_dir, HDF5_libdir and HDF5_incdir if they are set. 418 # otherwise pkg-config will be tried, and if that fails, dirstosearch will be searched. 419 _populate_hdf5_info(dirstosearch, inc_dirs, libs, lib_dirs) 420 421 if netCDF4_incdir is None and netCDF4_dir is None: 422 sys.stdout.write(""" 423NETCDF4_DIR environment variable not set, checking standard locations.. \n""") 424 for direc in dirstosearch: 425 sys.stdout.write('checking %s ...\n' % direc) 426 isnetcdf4 = check_ifnetcdf4(os.path.join(direc, 'include')) 427 if not isnetcdf4: 428 continue 429 else: 430 netCDF4_dir = direc 431 netCDF4_incdir = os.path.join(direc, 'include') 432 sys.stdout.write('netCDF4 found in %s\n' % netCDF4_dir) 433 break 434 if netCDF4_dir is None: 435 raise ValueError('did not find netCDF version 4 headers') 436 else: 437 if netCDF4_incdir is None: 438 netCDF4_incdir = os.path.join(netCDF4_dir, 'include') 439 isnetcdf4 = check_ifnetcdf4(netCDF4_incdir) 440 if not isnetcdf4: 441 raise ValueError( 442 'did not find netCDF version 4 headers %s' % netCDF4_incdir) 443 444 if netCDF4_libdir is None and netCDF4_dir is not None: 445 netCDF4_libdir = os.path.join(netCDF4_dir, 'lib') 446 447 if sys.platform == 'win32': 448 libs.extend(['netcdf', 'zlib']) 449 else: 450 libs.extend(['netcdf', 'z']) 451 452 if netCDF4_libdir is not None: lib_dirs.append(netCDF4_libdir) 453 if netCDF4_incdir is not None: inc_dirs.append(netCDF4_incdir) 454 455 # add szip to link if desired. 456 if szip_libdir is None and szip_dir is not None: 457 szip_libdir = os.path.join(szip_dir, 'lib') 458 if szip_incdir is None and szip_dir is not None: 459 szip_incdir = os.path.join(szip_dir, 'include') 460 if szip_incdir is not None and szip_libdir is not None: 461 libs.append('sz') 462 lib_dirs.append(szip_libdir) 463 inc_dirs.append(szip_incdir) 464 # add hdf4 to link if desired. 465 if hdf4_libdir is None and hdf4_dir is not None: 466 hdf4_libdir = os.path.join(hdf4_dir, 'lib') 467 if hdf4_incdir is None and hdf4_dir is not None: 468 hdf4_incdir = os.path.join(hdf4_dir, 'include') 469 if hdf4_incdir is not None and hdf4_libdir is not None: 470 libs.append('mfhdf') 471 libs.append('df') 472 lib_dirs.append(hdf4_libdir) 473 inc_dirs.append(hdf4_incdir) 474 # add jpeg to link if desired. 475 if jpeg_libdir is None and jpeg_dir is not None: 476 jpeg_libdir = os.path.join(jpeg_dir, 'lib') 477 if jpeg_incdir is None and jpeg_dir is not None: 478 jpeg_incdir = os.path.join(jpeg_dir, 'include') 479 if jpeg_incdir is not None and jpeg_libdir is not None: 480 libs.append('jpeg') 481 lib_dirs.append(jpeg_libdir) 482 inc_dirs.append(jpeg_incdir) 483 # add curl to link if desired. 484 if curl_libdir is None and curl_dir is not None: 485 curl_libdir = os.path.join(curl_dir, 'lib') 486 if curl_incdir is None and curl_dir is not None: 487 curl_incdir = os.path.join(curl_dir, 'include') 488 if curl_incdir is not None and curl_libdir is not None: 489 libs.append('curl') 490 lib_dirs.append(curl_libdir) 491 inc_dirs.append(curl_incdir) 492 493if sys.platform == 'win32': 494 runtime_lib_dirs = [] 495else: 496 runtime_lib_dirs = lib_dirs 497 498# Do not require numpy for just querying the package 499# Taken from the h5py setup file. 500if any('--' + opt in sys.argv for opt in Distribution.display_option_names + 501 ['help-commands', 'help']) or sys.argv[1] == 'egg_info': 502 pass 503else: 504 # append numpy include dir. 505 import numpy 506 inc_dirs.append(numpy.get_include()) 507 508# get netcdf library version. 509netcdf_lib_version = getnetcdfvers(lib_dirs) 510if netcdf_lib_version is None: 511 sys.stdout.write('unable to detect netcdf library version\n') 512else: 513 netcdf_lib_version = str(netcdf_lib_version) 514 sys.stdout.write('using netcdf library version %s\n' % netcdf_lib_version) 515 516cmdclass = {} 517DEFINE_MACROS = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")] 518netcdf4_src_root = osp.join(osp.join('src','netCDF4'), '_netCDF4') 519netcdf4_src_c = netcdf4_src_root + '.c' 520netcdf4_src_pyx = netcdf4_src_root + '.pyx' 521if 'sdist' not in sys.argv[1:] and 'clean' not in sys.argv[1:] and '--version' not in sys.argv[1:]: 522 sys.stdout.write('using Cython to compile netCDF4.pyx...\n') 523 # remove _netCDF4.c file if it exists, so cython will recompile _netCDF4.pyx. 524 # run for build *and* install (issue #263). Otherwise 'pip install' will 525 # not regenerate _netCDF4.c, even if the C lib supports the new features. 526 if len(sys.argv) >= 2: 527 if os.path.exists(netcdf4_src_c): 528 os.remove(netcdf4_src_c) 529 # this determines whether renameGroup and filepath methods will work. 530 has_rename_grp, has_nc_inq_path, has_nc_inq_format_extended, \ 531 has_cdf5_format, has_nc_open_mem, has_nc_create_mem, \ 532 has_parallel4_support, has_pnetcdf_support = \ 533 check_api(inc_dirs,netcdf_lib_version) 534 # for netcdf 4.4.x CDF5 format is always enabled. 535 if netcdf_lib_version is not None and\ 536 (netcdf_lib_version > "4.4" and netcdf_lib_version < "4.5"): 537 has_cdf5_format = True 538 539 # disable parallel support if mpi4py not available. 540 try: 541 import mpi4py 542 except ImportError: 543 has_parallel4_support = False 544 has_pnetcdf_support = False 545 546 f = open(osp.join('include', 'constants.pyx'), 'w') 547 if has_rename_grp: 548 sys.stdout.write('netcdf lib has group rename capability\n') 549 f.write('DEF HAS_RENAME_GRP = 1\n') 550 else: 551 sys.stdout.write('netcdf lib does not have group rename capability\n') 552 f.write('DEF HAS_RENAME_GRP = 0\n') 553 554 if has_nc_inq_path: 555 sys.stdout.write('netcdf lib has nc_inq_path function\n') 556 f.write('DEF HAS_NC_INQ_PATH = 1\n') 557 else: 558 sys.stdout.write('netcdf lib does not have nc_inq_path function\n') 559 f.write('DEF HAS_NC_INQ_PATH = 0\n') 560 561 if has_nc_inq_format_extended: 562 sys.stdout.write('netcdf lib has nc_inq_format_extended function\n') 563 f.write('DEF HAS_NC_INQ_FORMAT_EXTENDED = 1\n') 564 else: 565 sys.stdout.write( 566 'netcdf lib does not have nc_inq_format_extended function\n') 567 f.write('DEF HAS_NC_INQ_FORMAT_EXTENDED = 0\n') 568 569 if has_nc_open_mem: 570 sys.stdout.write('netcdf lib has nc_open_mem function\n') 571 f.write('DEF HAS_NC_OPEN_MEM = 1\n') 572 else: 573 sys.stdout.write('netcdf lib does not have nc_open_mem function\n') 574 f.write('DEF HAS_NC_OPEN_MEM = 0\n') 575 576 if has_nc_create_mem: 577 sys.stdout.write('netcdf lib has nc_create_mem function\n') 578 f.write('DEF HAS_NC_CREATE_MEM = 1\n') 579 else: 580 sys.stdout.write('netcdf lib does not have nc_create_mem function\n') 581 f.write('DEF HAS_NC_CREATE_MEM = 0\n') 582 583 if has_cdf5_format: 584 sys.stdout.write('netcdf lib has cdf-5 format capability\n') 585 f.write('DEF HAS_CDF5_FORMAT = 1\n') 586 else: 587 sys.stdout.write('netcdf lib does not have cdf-5 format capability\n') 588 f.write('DEF HAS_CDF5_FORMAT = 0\n') 589 590 if has_parallel4_support: 591 sys.stdout.write('netcdf lib has netcdf4 parallel functions\n') 592 f.write('DEF HAS_PARALLEL4_SUPPORT = 1\n') 593 else: 594 sys.stdout.write('netcdf lib does not have netcdf4 parallel functions\n') 595 f.write('DEF HAS_PARALLEL4_SUPPORT = 0\n') 596 597 if has_pnetcdf_support: 598 sys.stdout.write('netcdf lib has pnetcdf parallel functions\n') 599 f.write('DEF HAS_PNETCDF_SUPPORT = 1\n') 600 else: 601 sys.stdout.write('netcdf lib does not have pnetcdf parallel functions\n') 602 f.write('DEF HAS_PNETCDF_SUPPORT = 0\n') 603 604 f.close() 605 606 if has_parallel4_support or has_pnetcdf_support: 607 inc_dirs.append(mpi4py.get_include()) 608 # mpi_incdir should not be needed if using nc-config 609 # (should be included in nc-config --cflags) 610 if mpi_incdir is not None: inc_dirs.append(mpi_incdir) 611 612 ext_modules = [Extension("netCDF4._netCDF4", 613 [netcdf4_src_pyx], 614 define_macros=DEFINE_MACROS, 615 libraries=libs, 616 library_dirs=lib_dirs, 617 include_dirs=inc_dirs + ['include'], 618 runtime_library_dirs=runtime_lib_dirs)] 619else: 620 ext_modules = None 621 622setup(name="netCDF4", 623 cmdclass=cmdclass, 624 version=extract_version(netcdf4_src_pyx), 625 long_description="netCDF version 4 has many features not found in earlier versions of the library, such as hierarchical groups, zlib compression, multiple unlimited dimensions, and new data types. It is implemented on top of HDF5. This module implements most of the new features, and can read and write netCDF files compatible with older versions of the library. The API is modelled after Scientific.IO.NetCDF, and should be familiar to users of that module.\n\nThis project is hosted on a `GitHub repository <https://github.com/Unidata/netcdf4-python>`_ where you may access the most up-to-date source.", 626 author="Jeff Whitaker", 627 author_email="jeffrey.s.whitaker@noaa.gov", 628 url="http://github.com/Unidata/netcdf4-python", 629 download_url="http://python.org/pypi/netCDF4", 630 platforms=["any"], 631 license='License :: OSI Approved :: MIT License', 632 description="Provides an object-oriented python interface to the netCDF version 4 library.", 633 keywords=['numpy', 'netcdf', 'data', 'science', 'network', 'oceanography', 634 'meteorology', 'climate'], 635 classifiers=["Development Status :: 3 - Alpha", 636 "Programming Language :: Python :: 3", 637 "Programming Language :: Python :: 3.6", 638 "Programming Language :: Python :: 3.7", 639 "Programming Language :: Python :: 3.8", 640 "Intended Audience :: Science/Research", 641 "License :: OSI Approved :: MIT License", 642 "Topic :: Software Development :: Libraries :: Python Modules", 643 "Topic :: System :: Archiving :: Compression", 644 "Operating System :: OS Independent"], 645 packages=['netCDF4'], 646 package_dir={'':'src'}, 647 ext_modules=ext_modules, 648 **setuptools_extra_kwargs) 649