diff options
Diffstat (limited to 'src/_cffi_src/utils.py')
| -rw-r--r-- | src/_cffi_src/utils.py | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py index 65f9f120..eecd6ea1 100644 --- a/src/_cffi_src/utils.py +++ b/src/_cffi_src/utils.py @@ -4,61 +4,53 @@ from __future__ import absolute_import, division, print_function +import os import sys +from distutils.ccompiler import new_compiler +from distutils.dist import Distribution from cffi import FFI -def build_ffi_for_binding(module_name, module_prefix, modules, pre_include="", - post_include="", libraries=[], extra_compile_args=[], - extra_link_args=[]): +# Load the cryptography __about__ to get the current package version +base_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +about = {} +with open(os.path.join(base_src, "cryptography", "__about__.py")) as f: + exec(f.read(), about) + + +def build_ffi_for_binding(module_name, module_prefix, modules, libraries=[], + extra_compile_args=[], extra_link_args=[]): """ Modules listed in ``modules`` should have the following attributes: * ``INCLUDES``: A string containing C includes. * ``TYPES``: A string containing C declarations for types. - * ``FUNCTIONS``: A string containing C declarations for functions. - * ``MACROS``: A string containing C declarations for any macros. + * ``FUNCTIONS``: A string containing C declarations for functions & macros. * ``CUSTOMIZATIONS``: A string containing arbitrary top-level C code, this can be used to do things like test for a define and provide an alternate implementation based on that. - * ``CONDITIONAL_NAMES``: A dict mapping strings of condition names from the - library to a list of names which will not be present without the - condition. """ types = [] includes = [] functions = [] - macros = [] customizations = [] for name in modules: __import__(module_prefix + name) module = sys.modules[module_prefix + name] types.append(module.TYPES) - macros.append(module.MACROS) functions.append(module.FUNCTIONS) includes.append(module.INCLUDES) customizations.append(module.CUSTOMIZATIONS) - # We include functions here so that if we got any of their definitions - # wrong, the underlying C compiler will explode. In C you are allowed - # to re-declare a function if it has the same signature. That is: - # int foo(int); - # int foo(int); - # is legal, but the following will fail to compile: - # int foo(int); - # int foo(short); verify_source = "\n".join( - [pre_include] + includes + - [post_include] + - functions + customizations ) ffi = build_ffi( module_name, - cdef_source="\n".join(types + functions + macros), + cdef_source="\n".join(types + functions), verify_source=verify_source, libraries=libraries, extra_compile_args=extra_compile_args, @@ -71,6 +63,11 @@ def build_ffi_for_binding(module_name, module_prefix, modules, pre_include="", def build_ffi(module_name, cdef_source, verify_source, libraries=[], extra_compile_args=[], extra_link_args=[]): ffi = FFI() + # Always add the CRYPTOGRAPHY_PACKAGE_VERSION to the shared object + cdef_source += "\nstatic const char *const CRYPTOGRAPHY_PACKAGE_VERSION;" + verify_source += '\n#define CRYPTOGRAPHY_PACKAGE_VERSION "{}"'.format( + about["__version__"] + ) ffi.cdef(cdef_source) ffi.set_source( module_name, @@ -82,10 +79,23 @@ def build_ffi(module_name, cdef_source, verify_source, libraries=[], return ffi -def extra_link_args(platform): - if platform != "win32": - return [] +def extra_link_args(compiler_type): + if compiler_type == 'msvc': + # Enable NX and ASLR for Windows builds on MSVC. These are enabled by + # default on Python 3.3+ but not on 2.x. + return ['/NXCOMPAT', '/DYNAMICBASE'] else: - # Enable NX and ASLR for Windows builds. These are enabled by default - # on Python 3.3+ but not on 2.x. - return ["/NXCOMPAT", "/DYNAMICBASE"] + return [] + + +def compiler_type(): + """ + Gets the compiler type from distutils. On Windows with MSVC it will be + "msvc". On macOS and linux it is "unix". + """ + dist = Distribution() + dist.parse_config_files() + cmd = dist.get_command_obj('build') + cmd.ensure_finalized() + compiler = new_compiler(compiler=cmd.compiler) + return compiler.compiler_type |
