diff --git a/meta/classes-recipe/cython.bbclass b/meta/classes-recipe/cython.bbclass index 53b84f5f5e..dd9fc732bc 100644 --- a/meta/classes-recipe/cython.bbclass +++ b/meta/classes-recipe/cython.bbclass @@ -1,8 +1,5 @@ DEPENDS:append = " python3-cython-native" -# Remap the build paths that appear in generated .c code -export CYTHON_PREFIX_MAP = "${S}=${TARGET_DBGSRC_DIR} ${B}=${TARGET_DBGSRC_DIR}" - do_compile[postfuncs] = "strip_cython_metadata" strip_cython_metadata() { # Remove the Cython Metadata headers that we don't need after the build, and diff --git a/meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch b/meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch new file mode 100644 index 0000000000..bbafc29416 --- /dev/null +++ b/meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch @@ -0,0 +1,73 @@ +From 9b5f3b09f76899eba510c2d8f3ed2b0f752a4d1b Mon Sep 17 00:00:00 2001 +From: Oscar Benjamin +Date: Sat, 24 Aug 2024 08:30:31 +0100 +Subject: [PATCH] Output import-relative paths in generated C code. (GH-6341) + +When cython is run on a file that is not in the current working directory, +it outputs filepaths that are either absolute or are basenames. +It is not good to output absolute paths in the generated C code and +basenames mess up coverage measurement. + +Upstream-Status: Backport [20bceea6b19ffc2f65b9fba2e4f737f09e5a2b20] +Signed-off-by: Ross Burton +--- + Cython/Compiler/ExprNodes.py | 8 +++++++- + Cython/Compiler/ModuleNode.py | 9 ++++++--- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py +index a6bb1688e..0fbb15368 100644 +--- a/Cython/Compiler/ExprNodes.py ++++ b/Cython/Compiler/ExprNodes.py +@@ -21,6 +21,7 @@ import re + import sys + import copy + import os.path ++import pathlib + import operator + + from .Errors import ( +@@ -10072,7 +10073,12 @@ class CodeObjectNode(ExprNode): + func_name = code.get_py_string_const( + func.name, identifier=True, is_str=False, unicode_value=func.name) + # FIXME: better way to get the module file path at module init time? Encoding to use? +- file_path = StringEncoding.bytes_literal(func.pos[0].get_filenametable_entry().encode('utf8'), 'utf8') ++ file_path = func.pos[0].get_filenametable_entry() ++ if os.path.isabs(file_path): ++ file_path = func.pos[0].get_description() ++ # Always use / as separator ++ file_path = pathlib.Path(file_path).as_posix() ++ file_path = StringEncoding.bytes_literal(file_path.encode('utf-8'), 'utf8') + file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True) + + # This combination makes CPython create a new dict for "frame.f_locals" (see GH #1836). +diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py +index 43c6b5f07..8c29d6db7 100644 +--- a/Cython/Compiler/ModuleNode.py ++++ b/Cython/Compiler/ModuleNode.py +@@ -13,6 +13,7 @@ from collections import defaultdict + import json + import operator + import os ++import pathlib + import re + import sys + +@@ -944,9 +945,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): + for source_desc in code.globalstate.filename_list: + file_path = source_desc.get_filenametable_entry() + if isabs(file_path): +- file_path = basename(file_path) # never include absolute paths +- escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"') +- escaped_filename = as_encoded_filename(escaped_filename) ++ # never include absolute paths ++ file_path = source_desc.get_description() ++ # Always use / as separator ++ file_path = pathlib.Path(file_path).as_posix() ++ escaped_filename = as_encoded_filename(file_path) + code.putln('%s,' % escaped_filename.as_c_string_literal()) + else: + # Some C compilers don't like an empty array +-- +2.34.1 + diff --git a/meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch b/meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch deleted file mode 100644 index adc9463ffa..0000000000 --- a/meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 4d1b7911372561b22e03c7f2b4ec807502b5b9c1 Mon Sep 17 00:00:00 2001 -From: Ross Burton -Date: Mon, 4 Nov 2024 15:36:39 +0000 -Subject: [PATCH] WIP prefix map - -Upstream-Status: Inappropriate -Signed-off-by: Ross Burton ---- - Cython/Compiler/CmdLine.py | 9 ++++++++- - Cython/Compiler/Main.py | 9 +++++---- - Cython/Compiler/Options.py | 1 + - Cython/Compiler/Parsing.py | 1 + - Cython/Compiler/Scanning.py | 9 +++++++-- - 5 files changed, 22 insertions(+), 7 deletions(-) - -diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py -index 776636c..f5a7c79 100644 ---- a/Cython/Compiler/CmdLine.py -+++ b/Cython/Compiler/CmdLine.py -@@ -74,6 +74,12 @@ class SetAnnotateCoverageAction(Action): - namespace.annotate = True - namespace.annotate_coverage_xml = values - -+class SetPrefixMapAction(Action): -+ def __call__(self, parser, namespace, values, option_string=None): -+ mappings = getattr(namespace, self.dest, {}) -+ k, v = values.split("=", 1) -+ mappings[k] = v -+ setattr(namespace, self.dest, mappings) - - def create_cython_argparser(): - description = "Cython (https://cython.org/) is a compiler for code written in the "\ -@@ -157,9 +163,10 @@ def create_cython_argparser(): - 'deduced from the import path if source file is in ' - 'a package, or equals the filename otherwise.') - parser.add_argument('-M', '--depfile', action='store_true', help='produce depfiles for the sources') -+ # TODO: add help -+ parser.add_argument("--prefix-map", action=SetPrefixMapAction) - parser.add_argument('sources', nargs='*', default=[]) - -- # TODO: add help - parser.add_argument("-z", "--pre-import", dest='pre_import', action='store', type=str, help=SUPPRESS) - parser.add_argument("--convert-range", dest='convert_range', action='store_true', help=SUPPRESS) - parser.add_argument("--no-c-in-traceback", dest='c_line_in_traceback', action='store_false', help=SUPPRESS) -diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py -index 80946c0..28cfe68 100644 ---- a/Cython/Compiler/Main.py -+++ b/Cython/Compiler/Main.py -@@ -70,7 +70,7 @@ class Context(object): - language_level = None # warn when not set but default to Py2 - - def __init__(self, include_directories, compiler_directives, cpp=False, -- language_level=None, options=None): -+ language_level=None, prefix_map=None, options=None): - # cython_scope is a hack, set to False by subclasses, in order to break - # an infinite loop. - # Better code organization would fix it. -@@ -83,6 +83,7 @@ class Context(object): - self.future_directives = set() - self.compiler_directives = compiler_directives - self.cpp = cpp -+ self.prefix_map = prefix_map or {} - self.options = options - - self.pxds = {} # full name -> node tree -@@ -98,7 +99,7 @@ class Context(object): - @classmethod - def from_options(cls, options): - return cls(options.include_path, options.compiler_directives, -- options.cplus, options.language_level, options=options) -+ options.cplus, options.language_level, prefix_map=options.prefix_map, options=options) - - def set_language_level(self, level): - from .Future import print_function, unicode_literals, absolute_import, division, generator_stop -@@ -259,7 +260,7 @@ class Context(object): - rel_path = module_name.replace('.', os.sep) + os.path.splitext(pxd_pathname)[1] - if not pxd_pathname.endswith(rel_path): - rel_path = pxd_pathname # safety measure to prevent printing incorrect paths -- source_desc = FileSourceDescriptor(pxd_pathname, rel_path) -+ source_desc = FileSourceDescriptor(pxd_pathname, rel_path, prefix_map=self.prefix_map) - err, result = self.process_pxd(source_desc, scope, qualified_name) - if err: - raise err -@@ -509,7 +510,7 @@ def run_pipeline(source, options, full_module_name=None, context=None): - rel_path = source # safety measure to prevent printing incorrect paths - else: - rel_path = abs_path -- source_desc = FileSourceDescriptor(abs_path, rel_path) -+ source_desc = FileSourceDescriptor(abs_path, rel_path, prefix_map=context.prefix_map) - source = CompilationSource(source_desc, full_module_name, cwd) - - # Set up result object -diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py -index 61950a7..cc52732 100644 ---- a/Cython/Compiler/Options.py -+++ b/Cython/Compiler/Options.py -@@ -796,4 +796,5 @@ default_options = dict( - create_extension=None, - np_pythran=False, - legacy_implicit_noexcept=None, -+ prefix_map=dict(pair.split("=", 1) for pair in os.environ.get("CYTHON_PREFIX_MAP", "").split()), - ) -diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py -index 25c0de9..6c0eccf 100644 ---- a/Cython/Compiler/Parsing.py -+++ b/Cython/Compiler/Parsing.py -@@ -2106,6 +2106,7 @@ def p_include_statement(s, ctx): - s.included_files.append(include_file_name) - with Utils.open_source_file(include_file_path) as f: - source_desc = FileSourceDescriptor(include_file_path) -+ print(f"TODO Cannot use prefix map on {include_file_path}") - s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, parse_comments=s.parse_comments) - tree = p_statement_list(s2, ctx) - return tree -diff --git a/Cython/Compiler/Scanning.py b/Cython/Compiler/Scanning.py -index 372392b..0fa3b30 100644 ---- a/Cython/Compiler/Scanning.py -+++ b/Cython/Compiler/Scanning.py -@@ -195,7 +195,7 @@ class FileSourceDescriptor(SourceDescriptor): - optional name argument and will be passed back when asking for - the position()-tuple. - """ -- def __init__(self, filename, path_description=None): -+ def __init__(self, filename, path_description=None, prefix_map={}): - filename = Utils.decode_filename(filename) - self.path_description = path_description or filename - self.filename = filename -@@ -205,6 +205,7 @@ class FileSourceDescriptor(SourceDescriptor): - self.set_file_type_from_name(filename) - self._cmp_name = filename - self._lines = {} -+ self.prefix_map = prefix_map - - def get_lines(self, encoding=None, error_handling=None): - # we cache the lines only the second time this is called, in -@@ -243,7 +244,11 @@ class FileSourceDescriptor(SourceDescriptor): - return path - - def get_filenametable_entry(self): -- return self.file_path -+ entry = self.file_path -+ for k, v in self.prefix_map.items(): -+ # TODO: should just replace the prefix -+ entry = entry.replace(k, v) -+ return entry - - def __eq__(self, other): - return isinstance(other, FileSourceDescriptor) and self.filename == other.filename diff --git a/meta/recipes-devtools/python/python3-cython_3.0.11.bb b/meta/recipes-devtools/python/python3-cython_3.0.11.bb index 020a8e7205..2501e6ed23 100644 --- a/meta/recipes-devtools/python/python3-cython_3.0.11.bb +++ b/meta/recipes-devtools/python/python3-cython_3.0.11.bb @@ -7,7 +7,7 @@ SECTION = "devel/python" LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=61c3ee8961575861fa86c7e62bc9f69c" -SRC_URI += "file://0001-WIP-prefix-map.patch" +SRC_URI += "file://0001-Output-import-relative-paths-in-generated-C-code.-GH.patch" SRC_URI[sha256sum] = "7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff" inherit pypi setuptools3 cython