Beispiel #1
0
def sage_create_extension(template, kwds):
    """
    Create a distutils Extension given data from Cython

    This adjust the ``kwds`` in the following ways:

    - Make everything depend on *this* setup.py file

    - Add dependencies on header files for certain libraries

    - Ensure that C++ extensions link with -lstdc++

    - Sort the libraries according to the library order

    - Add some default compile/link args and directories

    - Drop -std=c99 and similar from C++ extensions

    - Ensure that each flag, library, ... is listed at most once
    """
    lang = kwds.get('language', 'c')

    # Libraries: add stdc++ if needed and sort them
    libs = kwds.get('libraries', [])
    if lang == 'c++':
        libs = libs + ['stdc++']
    kwds['libraries'] = sorted(set(libs),
            key=lambda lib: library_order.get(lib, 0))

    # Dependencies: add setup.py and lib_headers
    depends = kwds.get('depends', []) + [__file__]
    for lib, headers in lib_headers.items():
        if lib in libs:
            depends += headers
    kwds['depends'] = depends  # These are sorted and uniq'ed by Cython

    # Process extra_compile_args
    cflags = []
    for flag in kwds.get('extra_compile_args', []):
        if lang == "c++":
            if flag.startswith("-std=") and "++" not in flag:
                continue  # Skip -std=c99 and similar for C++
        cflags.append(flag)
    cflags = extra_compile_args + cflags
    kwds['extra_compile_args'] = stable_uniq(cflags)

    # Process extra_link_args
    ldflags = kwds.get('extra_link_args', []) + extra_link_args
    kwds['extra_link_args'] = stable_uniq(ldflags)

    # Process library_dirs
    lib_dirs = kwds.get('library_dirs', []) + library_dirs
    kwds['library_dirs'] = stable_uniq(lib_dirs)

    # Process include_dirs
    inc_dirs = kwds.get('include_dirs', []) + include_dirs
    kwds['include_dirs'] = stable_uniq(inc_dirs)

    return default_create_extension(template, kwds)
Beispiel #2
0
def sage_create_extension(template, kwds):
    """
    Create a distutils Extension given data from Cython

    This adjust the ``kwds`` in the following ways:

    - Make everything depend on *this* setup.py file

    - Add dependencies on header files for certain libraries

    - Ensure that C++ extensions link with -lstdc++

    - Sort the libraries according to the library order

    - Add some default compile/link args and directories

    - Drop -std=c99 and similar from C++ extensions

    - Ensure that each flag, library, ... is listed at most once
    """
    lang = kwds.get('language', 'c')

    # Libraries: add stdc++ if needed and sort them
    libs = kwds.get('libraries', [])
    if lang == 'c++':
        libs = libs + ['stdc++']
    kwds['libraries'] = sorted(set(libs),
                               key=lambda lib: library_order.get(lib, 0))

    # Dependencies: add setup.py and lib_headers
    depends = kwds.get('depends', []) + [__file__]
    for lib, headers in lib_headers.items():
        if lib in libs:
            depends += headers
    kwds['depends'] = depends  # These are sorted and uniq'ed by Cython

    # Process extra_compile_args
    cflags = []
    for flag in kwds.get('extra_compile_args', []):
        if lang == "c++":
            if flag.startswith("-std=") and "++" not in flag:
                continue  # Skip -std=c99 and similar for C++
        cflags.append(flag)
    cflags = extra_compile_args + cflags
    kwds['extra_compile_args'] = stable_uniq(cflags)

    # Process extra_link_args
    ldflags = kwds.get('extra_link_args', []) + extra_link_args
    kwds['extra_link_args'] = stable_uniq(ldflags)

    # Process library_dirs
    lib_dirs = kwds.get('library_dirs', []) + library_dirs
    kwds['library_dirs'] = stable_uniq(lib_dirs)

    # Process include_dirs
    inc_dirs = kwds.get('include_dirs', []) + include_dirs
    kwds['include_dirs'] = stable_uniq(inc_dirs)

    return default_create_extension(template, kwds)
Beispiel #3
0
    def prepare_extension(self, ext):
        sources = ext.sources
        if sources is None or not isinstance(sources, (list, tuple)):
            raise DistutilsSetupError(
                ("in 'ext_modules' option (extension '%s'), " +
                 "'sources' must be present and must be " +
                 "a list of source filenames") % ext.name)
        sources = list(sources)

        fullname = self.get_ext_fullname(ext.name)
        if self.inplace:
            # ignore build-lib -- put the compiled extension into
            # the source tree along with pure Python modules

            modpath = string.split(fullname, '.')
            package = string.join(modpath[0:-1], '.')
            base = modpath[-1]

            build_py = self.get_finalized_command('build_py')
            package_dir = build_py.get_package_dir(package)
            ext_filename = os.path.join(package_dir,
                                        self.get_ext_filename(base))
            relative_ext_filename = self.get_ext_filename(base)
        else:
            ext_filename = os.path.join(self.build_lib,
                                        self.get_ext_filename(fullname))
            relative_ext_filename = self.get_ext_filename(fullname)

        # while dispatching the calls to gcc in parallel, we sometimes
        # hit a race condition where two separate build_ext objects
        # try to create a given directory at the same time; whoever
        # loses the race then seems to throw an error, saying that
        # the directory already exists. so, instead of fighting to
        # fix the race condition, we simply make sure the entire
        # directory tree exists now, while we're processing the
        # extensions in serial.
        relative_ext_dir = os.path.split(relative_ext_filename)[0]
        prefixes = ['', self.build_lib, self.build_temp]
        for prefix in prefixes:
            path = os.path.join(prefix, relative_ext_dir)
            try:
                os.makedirs(path)
            except OSError as e:
                assert e.errno == errno.EEXIST, 'Cannot create %s.' % path
        depends = sources + ext.depends
        if not (self.force or newer_group(depends, ext_filename, 'newer')):
            log.debug("skipping '%s' extension (up-to-date)", ext.name)
            need_to_compile = False
        elif getattr(ext, "skip_build", False):
            log.debug("skipping '%s' extension (optional)", ext.name)
            need_to_compile = False
        else:
            log.info("building '%s' extension", ext.name)
            need_to_compile = True

        # If we need to compile, adjust the given extension
        if need_to_compile:
            libs = ext.libraries
            if ext.language == 'c++' and 'stdc++' not in libs:
                libs = libs + ['stdc++']

            # Sort libraries according to library_order
            ext.libraries = sorted(libs, key=lambda x: library_order.get(x, 0))

        return need_to_compile, (sources, ext, ext_filename)
Beispiel #4
0
    def create_extension(self, template, kwds):
        """
        Create a distutils Extension given data from Cython.

        This adjust the ``kwds`` in the following ways:

        - Make everything depend on *this* setup.py file

        - Add dependencies on header files for certain libraries

        - Ensure that C++ extensions link with -lstdc++

        - Sort the libraries according to the library order

        - Add some default compile/link args and directories

        - Choose C99 standard for C code and C++11 for C++ code

        - Drop -std=c99 and similar from C++ extensions

        - Ensure that each flag, library, ... is listed at most once
        """
        lang = kwds.get('language', 'c')
        cplusplus = (lang == "c++")

        # Libraries: add stdc++ if needed and sort them
        libs = kwds.get('libraries', [])
        if cplusplus:
            libs = libs + ['stdc++']
        kwds['libraries'] = sorted(set(libs),
                                   key=lambda lib: library_order.get(lib, 0))

        # Dependencies: add setup.py and lib_headers
        depends = kwds.get('depends', []) + [__file__]
        for lib, headers in lib_headers.items():
            if lib in libs:
                depends += headers
        kwds['depends'] = depends  # These are sorted and uniq'ed by Cython

        # Process extra_compile_args
        cflags = []
        have_std_flag = False
        for flag in kwds.get('extra_compile_args', []):
            if flag.startswith("-std="):
                if cplusplus and "++" not in flag:
                    continue  # Skip -std=c99 and similar for C++
                have_std_flag = True
            cflags.append(flag)
        if not have_std_flag:  # See Trac #23919
            if sys.platform == 'cygwin':
                # Cygwin (particularly newlib, Cygwin's libc) has some bugs
                # with strict ANSI C/C++ in some headers; using the GNU
                # extensions typically fares better:
                # https://trac.sagemath.org/ticket/24192
                if cplusplus:
                    cflags.append("-std=gnu++11")
                else:
                    cflags.append("-std=gnu99")
            else:
                if cplusplus:
                    cflags.append("-std=c++11")
                else:
                    cflags.append("-std=c99")
        cflags = extra_compile_args + cflags
        kwds['extra_compile_args'] = stable_uniq(cflags)

        # Process extra_link_args
        ldflags = kwds.get('extra_link_args', []) + extra_link_args
        kwds['extra_link_args'] = stable_uniq(ldflags)

        # Process library_dirs
        lib_dirs = kwds.get('library_dirs', []) + library_dirs
        kwds['library_dirs'] = stable_uniq(lib_dirs)

        # Process include_dirs
        inc_dirs = kwds.get('include_dirs',
                            []) + include_dirs + [self.build_dir]
        kwds['include_dirs'] = stable_uniq(inc_dirs)

        return default_create_extension(template, kwds)
Beispiel #5
0
    def prepare_extension(self, ext):
        sources = ext.sources
        if sources is None or not isinstance(sources, (list, tuple)):
            raise DistutilsSetupError(("in 'ext_modules' option (extension '%s'), " +
                   "'sources' must be present and must be " +
                   "a list of source filenames") % ext.name)
        sources = list(sources)

        fullname = self.get_ext_fullname(ext.name)
        if self.inplace:
            # ignore build-lib -- put the compiled extension into
            # the source tree along with pure Python modules

            modpath = string.split(fullname, '.')
            package = string.join(modpath[0:-1], '.')
            base = modpath[-1]

            build_py = self.get_finalized_command('build_py')
            package_dir = build_py.get_package_dir(package)
            ext_filename = os.path.join(package_dir,
                                        self.get_ext_filename(base))
            relative_ext_filename = self.get_ext_filename(base)
        else:
            ext_filename = os.path.join(self.build_lib,
                                        self.get_ext_filename(fullname))
            relative_ext_filename = self.get_ext_filename(fullname)

        # while dispatching the calls to gcc in parallel, we sometimes
        # hit a race condition where two separate build_ext objects
        # try to create a given directory at the same time; whoever
        # loses the race then seems to throw an error, saying that
        # the directory already exists. so, instead of fighting to
        # fix the race condition, we simply make sure the entire
        # directory tree exists now, while we're processing the
        # extensions in serial.
        relative_ext_dir = os.path.split(relative_ext_filename)[0]
        prefixes = ['', self.build_lib, self.build_temp]
        for prefix in prefixes:
            path = os.path.join(prefix, relative_ext_dir)
            try:
                os.makedirs(path)
            except OSError as e:
                assert e.errno==errno.EEXIST, 'Cannot create %s.' % path
        depends = sources + ext.depends
        if not (self.force or newer_group(depends, ext_filename, 'newer')):
            log.debug("skipping '%s' extension (up-to-date)", ext.name)
            need_to_compile = False
        elif getattr(ext, "skip_build", False):
            log.debug("skipping '%s' extension (optional)", ext.name)
            need_to_compile = False
        else:
            log.info("building '%s' extension", ext.name)
            need_to_compile = True

        # If we need to compile, adjust the given extension
        if need_to_compile:
            libs = ext.libraries
            if ext.language == 'c++' and 'stdc++' not in libs:
                libs = libs + ['stdc++']

            # Sort libraries according to library_order
            ext.libraries = sorted(libs, key=lambda x: library_order.get(x, 0))

        return need_to_compile, (sources, ext, ext_filename)
Beispiel #6
0
    def create_extension(self, template, kwds):
        """
        Create a distutils Extension given data from Cython.

        This adjust the ``kwds`` in the following ways:

        - Make everything depend on *this* setup.py file

        - Add dependencies on header files for certain libraries

        - Ensure that C++ extensions link with -lstdc++

        - Sort the libraries according to the library order

        - Add some default compile/link args and directories

        - Choose C99 standard for C code and C++11 for C++ code

        - Drop -std=c99 and similar from C++ extensions

        - Ensure that each flag, library, ... is listed at most once
        """
        lang = kwds.get('language', 'c')
        cplusplus = (lang == "c++")

        # Libraries: add stdc++ if needed and sort them
        libs = kwds.get('libraries', [])
        if cplusplus:
            libs = libs + ['stdc++']
        kwds['libraries'] = sorted(set(libs),
                key=lambda lib: library_order.get(lib, 0))

        # Dependencies: add setup.py and lib_headers
        depends = kwds.get('depends', []) + [__file__]
        for lib, headers in lib_headers.items():
            if lib in libs:
                depends += headers
        kwds['depends'] = depends  # These are sorted and uniq'ed by Cython

        # Process extra_compile_args
        cflags = []
        have_std_flag = False
        for flag in kwds.get('extra_compile_args', []):
            if flag.startswith("-std="):
                if cplusplus and "++" not in flag:
                    continue  # Skip -std=c99 and similar for C++
                have_std_flag = True
            cflags.append(flag)
        if not have_std_flag:  # See Trac #23919
            if sys.platform == 'cygwin':
                # Cygwin (particularly newlib, Cygwin's libc) has some bugs
                # with strict ANSI C/C++ in some headers; using the GNU
                # extensions typically fares better:
                # https://trac.sagemath.org/ticket/24192
                if cplusplus:
                    cflags.append("-std=gnu++11")
                else:
                    cflags.append("-std=gnu99")
            else:
                if cplusplus:
                    cflags.append("-std=c++11")
                else:
                    cflags.append("-std=c99")
        cflags = extra_compile_args + cflags
        kwds['extra_compile_args'] = stable_uniq(cflags)

        # Process extra_link_args
        ldflags = kwds.get('extra_link_args', []) + extra_link_args
        kwds['extra_link_args'] = stable_uniq(ldflags)

        # Process library_dirs
        lib_dirs = kwds.get('library_dirs', []) + library_dirs
        kwds['library_dirs'] = stable_uniq(lib_dirs)

        # Process include_dirs
        inc_dirs = kwds.get('include_dirs', []) + include_dirs + [self.build_dir]
        kwds['include_dirs'] = stable_uniq(inc_dirs)

        return default_create_extension(template, kwds)