GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — p4python/setup.py at master · perforce/p4python Expand file tree/ Copy pathsetup.pyMore file actions 521 lines (423 loc) · 20 KB / Copy pathsetup.pyFile metadata and controls521 lines (423 loc) · 20 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 """P4Python - Python interface to Perforce API Perforce is the fast SCM system at www.perforce.com. This package provides a simple interface from Python wrapping the Perforce C++ API to gain performance and ease of coding. Similar to interfaces available for Ruby and Perl. """ from __future__ import print_function classifiers = """\ Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: Freely Distributable Programming Language :: Python Topic :: Software Development :: Libraries :: Python Modules Topic :: Software Development :: Version Control Topic :: Software Development Topic :: Utilities Operating System :: Microsoft :: Windows Operating System :: Unix Operating System :: MacOS :: MacOS X """ # Customisations needed to use to build: # 1. Set directory for p4api in setup.cfg # See notes in P4API documentation for building with API on different # platforms: # http://www.perforce.com/perforce/doc.current/manuals/p4api/02_clientprog.html MIN_SSL_VERSION = 100 # MIN_SSL_RELEASE='e' # currently not restricting builds for any OpenSSL > 1.0.0 try: from setuptools import setup, Extension except ImportError: from distutils.core import setup, Extension from distutils.command.build import build as build_module from distutils.command.build_ext import build_ext as build_ext_module from distutils.command.sdist import sdist as sdist_module import os, os.path, sys, re, shutil, stat, subprocess from tools.PlatformInfo import PlatformInfo from tools.VersionInfo import VersionInfo from tools.P4APIHttps import P4APIHttps if sys.version_info < (3, 0): from ConfigParser import ConfigParser else: from configparser import ConfigParser global_dist_directory = "p4python-" doclines = __doc__.split("\n") NAME = "p4python" VERSION = "2023.1" PY_MODULES = ["P4"] P4_API_DIR = "p4api" DESCRIPTION = doclines[0] AUTHOR = "Perforce Software Inc" MAINTAINER = "Perforce Software Inc" LICENSE = "LICENSE.txt" URL = "http://www.perforce.com" KEYWORDS = "Perforce perforce P4Python" P4_CONFIG_FILE = "setup.cfg" P4_CONFIG_SECTION = "p4python_config" P4_CONFIG_P4APIDIR = "p4_apidir" P4_CONFIG_SSLDIR = "p4_ssl" P4_DOC_RELNOTES = "../p4-doc/user/p4pythonnotes.txt" P4_RELNOTES = "RELNOTES.txt" # you gotta love python for monkey patching def monkey_nt_quote_args(args): rlist = [] for arg in args: # if there is a space in the arg, wrap it in double quotes if " " in arg: arg = '"\"{}\""'.format(arg) rlist.append(arg) return rlist ###################################################### # Command Classes class p4build(build_module): """Subclass of build subcommand for passing paths to build_ext compiler and linker""" user_options = build_module.user_options + [ ('ssl=', None, 'specify ssl library directory'), ('apidir=', None, 'specify root of p4api directory'), ] def initialize_options(self, *args, **kwargs): self.apidir = os.getenv("apidir", None) self.ssl = os.getenv("ssl", None) build_module.initialize_options(self, *args, **kwargs) def finalize_options(self): global p4_api_dir, p4_ssl_dir if self.apidir: p4_api_dir = self.apidir if self.ssl: p4_ssl_dir = self.ssl build_module.finalize_options(self) class p4build_ext(build_ext_module): """Subclass of build subcommand for passing paths to compiler and linker""" user_options = build_ext_module.user_options + [ ('ssl=', None, 'specify ssl library directory'), ('apidir=', None, 'specify root of p4api directory'), ] def initialize_options(self, *args, **kwargs): self.apidir = os.getenv("apidir", None) self.ssl = os.getenv("ssl", None) build_ext_module.initialize_options(self, *args, **kwargs) def get_config(self, option): config = ConfigParser() config.read(P4_CONFIG_FILE) dir = "" if config.has_section(P4_CONFIG_SECTION): if config.has_option(P4_CONFIG_SECTION, option): dir = config.get(P4_CONFIG_SECTION, option) return dir def finalize_options(self): global p4_api_dir, p4_ssl_dir # options passed to "build" are copied into globals for use in "build_ext" if p4_api_dir: self.apidir = p4_api_dir if p4_ssl_dir: self.ssl = p4_ssl_dir # if we didn't get values from the command line, check the config file if not self.apidir: self.apidir = self.get_config(P4_CONFIG_P4APIDIR) if not self.ssl: self.ssl = self.get_config(P4_CONFIG_SSLDIR) build_ext_module.finalize_options(self) def is_super(self): rv = subprocess.check_output("id -u", shell=True) if int(rv) != 0: return False return True def download_p4api(self, api_ver, ssl_ver): global loaded_lib_from_ftp print("Looking for P4 API {0} for SSL {1} on https://ftp.perforce.com".format(api_ver, ssl_ver)) g_major, g_minor = P4APIHttps.get_glib_ver(self) p4https = P4APIHttps() url = p4https.get_url(g_minor, ssl_ver, api_ver) api_dir, api_tarball= p4https.get_file(url) print("Extracted {0} into {1}".format(api_tarball, api_dir)) loaded_lib_from_ftp = True return api_dir # run strings on p4api librpc.a to get the version of OpenSSL needed def get_ssl_version_from_p4api(self): libpath = os.path.join(self.apidir, "lib", "librpc.a") p1 = subprocess.Popen(["strings", libpath], stdout=subprocess.PIPE) p2 = subprocess.Popen(["grep", "^OpenSSL"], stdin=p1.stdout, stdout=subprocess.PIPE) p1.stdout.close() out, err = p2.communicate() sslstr = out.split() return sslstr[1].decode(encoding='UTF-8') @staticmethod def build_ssl_lib(ssl_ver): # not for windows # get the openssl version needed # Now that p4api needs to know the ssl version, this call gets recursive. # ssl_ver = self.get_ssl_version_from_p4api(self) # Default OpenSSL version if none is provided if not ssl_ver: ssl_ver = "3.0.2" # Default to the latest supported SSL version # Check environment variable for build_ssl # If set to "no", skip the build process # If set to "yes", proceed with the build process # If not set, default to "no" build_ssl = os.getenv("P4PYTHON_BUILD_SSL", "no").lower() if build_ssl != "yes": print("Skipping OpenSSL build as per environment variable.") return "", "", "", False # Proceed to download and build OpenSSL print(f"Downloading OpenSSL {ssl_ver} source from https://www.openssl.org/source/") ssl_src_dir, tarball = P4APIHttps().get_ssl_src(ssl_ver) if not ssl_src_dir: print("Failed to download or extract OpenSSL source.") return "", "", "", False print(f"Building OpenSSL source in {ssl_src_dir}") ssl_lib_dir = P4APIHttps().build_ssl(ssl_src_dir) return ssl_lib_dir, ssl_src_dir, tarball, True @staticmethod def check_installed_ssl(): # not for windows try: (version_string, err) = subprocess.Popen(["openssl", "version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() except IOError: print("****************************************************", file=sys.stderr) print("No openssl in path and no ssl library path specified", file=sys.stderr) print("****************************************************", file=sys.stderr) return "", "" if err: print("****************************************************", file=sys.stderr) print("Cannot determine the version of openssl", file=sys.stderr) print("****************************************************", file=sys.stderr) return "", "" if type(version_string) == bytes: version_string = version_string.decode('utf8') print("Found installed SSL version " + version_string) pattern = re.compile(r"OpenSSL (\d)\.(\d)\.(\d)(\S+\s?\S*)?\s+\d+ \S+ \d+") match = pattern.match(version_string) if match: version = int(match.group(1)) * 100 + int(match.group(2)) * 10 + int(match.group(3)) * 1 if match.group(4) is None: ver_only = str(match.group(1)) + "." + str(match.group(2)) + "." + str(match.group(3)) else: ver_only = str(match.group(1)) + "." + str(match.group(2)) + "." + str(match.group(3)) + str(match.group(4)) if version >= MIN_SSL_VERSION: release = match.group(4) for p in os.environ["PATH"].split(os.pathsep): pathToFile = os.path.join(p, "openssl") if os.path.exists(pathToFile) and os.access(pathToFile, os.X_OK): try: output = subprocess.check_output(["ldd", pathToFile], text=True) for line in output.splitlines(): if "libssl" in line: parts = line.split() if len(parts) >= 3: libpath = os.path.dirname(parts[2]) break else: raise Exception(f"libssl not found in ldd output for {pathToFile}") if os.path.exists(libpath) and os.path.isdir(libpath): print("Found installed SSL libraries " + libpath) return libpath, ver_only else: print("****************************************************", file=sys.stderr) print(f"Calculated path {libpath} for SSL does not exist", file=sys.stderr) print("****************************************************", file=sys.stderr) return "", "" except subprocess.CalledProcessError as e: print("****************************************************", file=sys.stderr) print(f"Error running ldd on {pathToFile}: {e}", file=sys.stderr) print("****************************************************", file=sys.stderr) return "", "" except Exception as e: print("****************************************************", file=sys.stderr) print(f"Error processing ldd output: {e}", file=sys.stderr) print("****************************************************", file=sys.stderr) return "", "" else: print("***************************************", file=sys.stderr) print("Minimum SSL release required is 1.0.0", file=sys.stderr) print("***************************************", file=sys.stderr) else: print("****************************************************", file=sys.stderr) print("Cannot match OpenSSL Version string '{0}'".format(version_string), file=sys.stderr) print("****************************************************", file=sys.stderr) return "", "" # run from setup.py after the options are processed def run(self, *args, **kwargs): global p4_api_dir, p4_ssl_dir, p4_ssl_ver, ssl_src, ssl_tarball, loaded_ssl_from_ftp, loaded_api_from_ftp global global_dist_directory global releaseVersion global p4_extension ssl_ver = "" if not p4_ssl_dir: if (not self.ssl) and (sys.platform == "linux" or sys.platform == "linux2"): # check for a version of SSL already installed via 'openssl version' self.ssl, ssl_ver = self.check_installed_ssl() # return libpath or None # we only support 1.1.1 or 3 using 2019.1 p4api if not(("1.1.1" in ssl_ver) or (ssl_ver.startswith("3"))): self.ssl = "" if not self.ssl: # try downloading and building ssl if self.is_super(): (self.ssl, ssl_src, ssl_tarball, loaded_ssl_from_ftp) = self.build_ssl_lib(ssl_ver) if not self.ssl: print("OpenSSL build was skipped or failed.") raise Exception("Cannot build P4Python without SSL support.") p4_ssl_dir = self.ssl p4_ssl_ver = ssl_ver else: print("must be root to build and install SSL") if not self.ssl: print("***********************************************", file=sys.stderr) print("** Cannot build P4Python without SSL support **", file=sys.stderr) print("***********************************************", file=sys.stderr) raise Exception("Parameter --ssl is needed") p4_ssl_dir = self.ssl if not p4_api_dir: if (not self.apidir) and (sys.platform == "linux" or sys.platform == "linux2"): # Attempt to download P4 API which matches our versions self.apidir = self.download_p4api(VersionInfo(".").getVersion(), ssl_ver) p4_api_dir = self.apidir if not self.apidir: print("***********************************************", file=sys.stderr) print("** Cannot build P4Python without P4API **", file=sys.stderr) print("***********************************************", file=sys.stderr) raise Exception("Parameter --apidir is needed") p4_api_dir = self.apidir try: apiVersion = VersionInfo(p4_api_dir) releaseVersion = VersionInfo(".") except IOError: print("Cannot find Version file in API dir {0}.".format(p4_api_dir)) exit(1) ryear = int(apiVersion.release_year) rversion = int(apiVersion.release_version) global_dist_directory += releaseVersion.getDistVersion() if ryear < 2021: print("API Release %s.%s not supported by p4python, Minimum API requirement is 2022.1" % (ryear, rversion)) print("Please download a more recent API release from the Perforce ftp site.") exit(1) else: print("Using API Release %s.%s" % (ryear, rversion)) # monkey patch nt_quote_args (Only works in the debugger!) #spawn._nt_quote_args = monkey_nt_quote_args # add the paths for p4 headers and library inc_path = [str(os.path.join(p4_api_dir, "include", "p4"))] lib_path = [str(os.path.join(p4_api_dir, "lib")), str(p4_ssl_dir)] # check if the interpreter is mayapy.exe namedir = os.path.dirname(os.path.dirname(sys.executable)) if "maya" in namedir.lower(): inc_path.append(str(os.path.join(namedir, "include"))) inc_path.append(str(os.path.join(namedir, "include", "python2.7"))) lib_path.append(str(os.path.join(namedir, "lib"))) info = PlatformInfo(apiVersion, releaseVersion, str(p4_ssl_dir), p4_ssl_ver) # Extend the extension specification with the new configuration p4_extension.include_dirs += inc_path p4_extension.library_dirs += lib_path p4_extension.libraries += info.libraries p4_extension.extra_compile_args += info.extra_compile_args p4_extension.define_macros += info.define_macros p4_extension.extra_link_args += info.extra_link_args build_ext_module.run(self, *args, **kwargs) class p4build_sdist(sdist_module): user_options = sdist_module.user_options + [ ('ssl=', None, 'ignored by sdist'), ('apidir=', None, 'ignored by sdist'), ] @staticmethod def force_remove_file(function, path, excinfo): os.chmod(path, stat.S_IWRITE) os.unlink(path) def copyReleaseNotes(self): """Copies the relnotes from the doc directory to the local directory if they exist Returns True if the release notes were copied, otherwise False """ if os.path.exists(P4_DOC_RELNOTES): try: shutil.copy(P4_DOC_RELNOTES, P4_RELNOTES) return True except Exception as e: print(e) return False else: return False def deleteReleaseNotes(self): """Removes RELNOTES.txt from the current directory again""" os.chmod(P4_RELNOTES, stat.S_IWRITE) os.remove(P4_RELNOTES) def initialize_options(self): global global_dist_directory # Don't use hard links when building source distribution. # It's great, apart from under VirtualBox where it falls # apart due to a bug try: del os.link except: pass if os.path.exists(P4_RELNOTES): self.deleteReleaseNotes() self.copyReleaseNotes() version = VersionInfo(".") distdir = global_dist_directory + version.getDistVersion() if os.path.exists(distdir): shutil.rmtree(distdir, False, self.force_remove_file) sdist_module.initialize_options(self) def do_setup(): global global_dist_directory global p4_extension p4_extension = Extension("P4API", ["P4API.cpp", "PythonClientAPI.cpp", "PythonClientUser.cpp", "SpecMgr.cpp", "P4Result.cpp", "PythonMergeData.cpp", "P4MapMaker.cpp", "PythonSpecData.cpp", "PythonMessage.cpp", "PythonActionMergeData.cpp", "PythonClientProgress.cpp", "P4PythonDebug.cpp", "PythonKeepAlive.cpp"], include_dirs=[], library_dirs=[], libraries=[], extra_compile_args=[], define_macros=[], extra_link_args=[] ) setup(name=NAME, version=VersionInfo(".").getDistVersion(), description=DESCRIPTION, author=AUTHOR, author_email=AUTHOR_EMAIL, maintainer=MAINTAINER, maintainer_email=MAINTAINER_EMAIL, license=LICENSE, url=URL, keywords=KEYWORDS, classifiers=[x for x in classifiers.split("\n") if x], long_description="\n".join(doclines[2:]), py_modules=PY_MODULES, ext_modules=[p4_extension], cmdclass={ 'build': p4build, 'build_ext': p4build_ext, 'sdist': p4build_sdist, } ) # def rreplace(s, old, new, occurrence=1): # li = s.rsplit(old, occurrence) # return new.join(li) def cleanup_api(api_dir, tarball): base = os.path.dirname(api_dir) # =========================================================================== # Delete p4api.tgz and p4_api_dir or ssl.tar.gz and ssl_src_dir # =========================================================================== print("Deleting temporary files from '{}'".format(base)) tarfile = os.path.join(base, tarball) os.unlink(tarfile) shutil.rmtree(api_dir) # declare some evil globals p4_api_dir = "" p4_ssl_dir = "" p4_ssl_ver = "" ssl_tarball = "" ssl_src = "" loaded_api_from_ftp = False loaded_ssl_from_ftp = False if __name__ == "__main__": do_setup() if loaded_api_from_ftp: cleanup_api(p4_api_dir, "p4api.tgz") if loaded_ssl_from_ftp: cleanup_api(ssl_src, ssl_tarball) |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |