Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cython
Commits
fc4bde50
Commit
fc4bde50
authored
Mar 29, 2017
by
Jeroen Demeyer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Automatic late includes.
parent
9c6af17f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
65 additions
and
16 deletions
+65
-16
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+1
-0
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+18
-5
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+13
-3
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+26
-8
docs/src/userguide/external_C_code.rst
docs/src/userguide/external_C_code.rst
+7
-0
No files found.
Cython/Compiler/Code.py
View file @
fc4bde50
...
@@ -985,6 +985,7 @@ class GlobalState(object):
...
@@ -985,6 +985,7 @@ class GlobalState(object):
'
global_var
',
'
global_var
',
'
string_decls
',
'
string_decls
',
'
decls
',
'
decls
',
'
late_includes
',
'
all_the_rest
',
'
all_the_rest
',
'
pystring_table
',
'
pystring_table
',
'
cached_builtins
',
'
cached_builtins
',
...
...
Cython/Compiler/ModuleNode.py
View file @
fc4bde50
...
@@ -90,7 +90,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -90,7 +90,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
x
not
in
L1
:
if
x
not
in
L1
:
L1
.
append
(
x
)
L1
.
append
(
x
)
extend_if_not_in
(
self
.
scope
.
include_files
,
scope
.
include_files
)
extend_if_not_in
(
self
.
scope
.
include_files_early
,
scope
.
include_files_early
)
extend_if_not_in
(
self
.
scope
.
include_files_late
,
scope
.
include_files_late
)
extend_if_not_in
(
self
.
scope
.
included_files
,
scope
.
included_files
)
extend_if_not_in
(
self
.
scope
.
included_files
,
scope
.
included_files
)
extend_if_not_in
(
self
.
scope
.
python_include_files
,
extend_if_not_in
(
self
.
scope
.
python_include_files
,
scope
.
python_include_files
)
scope
.
python_include_files
)
...
@@ -137,6 +138,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -137,6 +138,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env
.
return_type
=
PyrexTypes
.
c_void_type
env
.
return_type
=
PyrexTypes
.
c_void_type
self
.
referenced_modules
=
[]
self
.
referenced_modules
=
[]
self
.
find_referenced_modules
(
env
,
self
.
referenced_modules
,
{})
self
.
find_referenced_modules
(
env
,
self
.
referenced_modules
,
{})
env
.
fixup_includes
()
self
.
sort_cdef_classes
(
env
)
self
.
sort_cdef_classes
(
env
)
self
.
generate_c_code
(
env
,
options
,
result
)
self
.
generate_c_code
(
env
,
options
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
...
@@ -362,6 +364,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -362,6 +364,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
""
)
code
.
putln
(
""
)
code
.
putln
(
"/* Implementation of '%s' */"
%
env
.
qualified_name
)
code
.
putln
(
"/* Implementation of '%s' */"
%
env
.
qualified_name
)
code
=
globalstate
[
'late_includes'
]
code
.
putln
(
"/* Late includes */"
)
self
.
generate_includes
(
env
,
modules
,
code
,
early
=
False
)
code
=
globalstate
[
'all_the_rest'
]
code
=
globalstate
[
'all_the_rest'
]
self
.
generate_cached_builtins_decls
(
env
,
code
)
self
.
generate_cached_builtins_decls
(
env
,
code
)
...
@@ -653,7 +659,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -653,7 +659,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#define %s"
%
Naming
.
h_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
h_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
code
.
putln
(
"/* Early includes */"
)
self
.
generate_includes
(
env
,
cimported_modules
,
code
,
late
=
False
)
code
.
putln
(
""
)
code
.
putln
(
""
)
code
.
putln
(
"#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS)"
)
code
.
putln
(
"#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS)"
)
code
.
putln
(
"#define CYTHON_WITHOUT_ASSERTIONS"
)
code
.
putln
(
"#define CYTHON_WITHOUT_ASSERTIONS"
)
...
@@ -727,16 +734,22 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -727,16 +734,22 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
" #define DL_IMPORT(_T) _T"
)
code
.
putln
(
" #define DL_IMPORT(_T) _T"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
def
generate_includes
(
self
,
env
,
cimported_modules
,
code
):
def
generate_includes
(
self
,
env
,
cimported_modules
,
code
,
early
=
True
,
late
=
True
):
includes
=
[]
includes
=
[]
for
filename
in
env
.
include_files
:
if
early
:
includes
+=
env
.
include_files_early
if
late
:
includes
+=
env
.
include_files_late
for
filename
in
includes
:
byte_decoded_filenname
=
str
(
filename
)
byte_decoded_filenname
=
str
(
filename
)
if
byte_decoded_filenname
[
0
]
==
'<'
and
byte_decoded_filenname
[
-
1
]
==
'>'
:
if
byte_decoded_filenname
[
0
]
==
'<'
and
byte_decoded_filenname
[
-
1
]
==
'>'
:
code
.
putln
(
'#include %s'
%
byte_decoded_filenname
)
code
.
putln
(
'#include %s'
%
byte_decoded_filenname
)
else
:
else
:
code
.
putln
(
'#include "%s"'
%
byte_decoded_filenname
)
code
.
putln
(
'#include "%s"'
%
byte_decoded_filenname
)
code
.
putln_openmp
(
"#include <omp.h>"
)
if
early
:
code
.
putln_openmp
(
"#include <omp.h>"
)
def
generate_filename_table
(
self
,
code
):
def
generate_filename_table
(
self
,
code
):
from
os.path
import
isabs
,
basename
from
os.path
import
isabs
,
basename
...
...
Cython/Compiler/Nodes.py
View file @
fc4bde50
...
@@ -461,17 +461,27 @@ class StatNode(Node):
...
@@ -461,17 +461,27 @@ class StatNode(Node):
class
CDefExternNode
(
StatNode
):
class
CDefExternNode
(
StatNode
):
# include_file string or None
# include_file string or None
# body StatNode
# body Stat
List
Node
child_attrs
=
[
"body"
]
child_attrs
=
[
"body"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
self
.
include_file
:
env
.
add_include_file
(
self
.
include_file
)
old_cinclude_flag
=
env
.
in_cinclude
old_cinclude_flag
=
env
.
in_cinclude
env
.
in_cinclude
=
1
env
.
in_cinclude
=
1
self
.
body
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
env
.
in_cinclude
=
old_cinclude_flag
env
.
in_cinclude
=
old_cinclude_flag
inc
=
self
.
include_file
if
inc
:
stats
=
self
.
body
.
stats
if
inc
[
0
]
==
'<'
and
inc
[
-
1
]
==
'>'
:
# System include => always early
env
.
add_include_file
(
inc
)
elif
stats
and
all
(
isinstance
(
node
,
CVarDefNode
)
for
node
in
stats
):
# Generate a late include if the body is not empty and
# all statements are variable or function declarations.
env
.
add_include_file
(
inc
,
late
=
True
)
else
:
env
.
add_include_file
(
inc
)
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
return
self
return
self
...
...
Cython/Compiler/Symtab.py
View file @
fc4bde50
...
@@ -1067,7 +1067,8 @@ class ModuleScope(Scope):
...
@@ -1067,7 +1067,8 @@ class ModuleScope(Scope):
# doc_cname string C name of module doc string
# doc_cname string C name of module doc string
# utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py
# utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py
# python_include_files [string] Standard Python headers to be included
# python_include_files [string] Standard Python headers to be included
# include_files [string] Other C headers to be included
# include_files_early [string] C headers to be included before Cython decls
# include_files_late [string] C headers to be included after Cython decls
# string_to_entry {string : Entry} Map string const to entry
# string_to_entry {string : Entry} Map string const to entry
# identifier_to_entry {string : Entry} Map identifier string const to entry
# identifier_to_entry {string : Entry} Map identifier string const to entry
# context Context
# context Context
...
@@ -1111,7 +1112,8 @@ class ModuleScope(Scope):
...
@@ -1111,7 +1112,8 @@ class ModuleScope(Scope):
self
.
utility_code_list
=
[]
self
.
utility_code_list
=
[]
self
.
module_entries
=
{}
self
.
module_entries
=
{}
self
.
python_include_files
=
[
"Python.h"
]
self
.
python_include_files
=
[
"Python.h"
]
self
.
include_files
=
[]
self
.
include_files_early
=
[]
self
.
include_files_late
=
[]
self
.
type_names
=
dict
(
outer_scope
.
type_names
)
self
.
type_names
=
dict
(
outer_scope
.
type_names
)
self
.
pxd_file_loaded
=
0
self
.
pxd_file_loaded
=
0
self
.
cimported_modules
=
[]
self
.
cimported_modules
=
[]
...
@@ -1247,15 +1249,31 @@ class ModuleScope(Scope):
...
@@ -1247,15 +1249,31 @@ class ModuleScope(Scope):
module
=
module
.
lookup_submodule
(
submodule
)
module
=
module
.
lookup_submodule
(
submodule
)
return
module
return
module
def
add_include_file
(
self
,
filename
):
def
add_include_file
(
self
,
filename
,
late
=
False
):
if
filename
not
in
self
.
python_include_files
\
if
filename
in
self
.
python_include_files
:
and
filename
not
in
self
.
include_files
:
return
self
.
include_files
.
append
(
filename
)
# Possibly, the same include appears both as early and as late
# include. We'll deal with this in fixup_includes().
if
late
:
incs
=
self
.
include_files_late
else
:
incs
=
self
.
include_files_early
if
filename
not
in
incs
:
incs
.
append
(
filename
)
def
fixup_includes
(
self
):
for
filename
in
self
.
include_files_early
:
try
:
self
.
include_files_late
.
remove
(
filename
)
except
ValueError
:
pass
def
add_imported_module
(
self
,
scope
):
def
add_imported_module
(
self
,
scope
):
if
scope
not
in
self
.
cimported_modules
:
if
scope
not
in
self
.
cimported_modules
:
for
filename
in
scope
.
include_files
:
for
filename
in
scope
.
include_files_early
:
self
.
add_include_file
(
filename
)
self
.
add_include_file
(
filename
,
late
=
False
)
for
filename
in
scope
.
include_files_late
:
self
.
add_include_file
(
filename
,
late
=
True
)
self
.
cimported_modules
.
append
(
scope
)
self
.
cimported_modules
.
append
(
scope
)
for
m
in
scope
.
cimported_modules
:
for
m
in
scope
.
cimported_modules
:
self
.
add_imported_module
(
m
)
self
.
add_imported_module
(
m
)
...
...
docs/src/userguide/external_C_code.rst
View file @
fc4bde50
...
@@ -129,6 +129,13 @@ A few more tricks and tips:
...
@@ -129,6 +129,13 @@ A few more tricks and tips:
cdef extern from *:
cdef extern from *:
...
...
* If a ``cdef extern from "inc.h"`` block is not empty and contains only
function or variable declarations (and no type declarations of any kind),
Cython will put the ``#include "inc.h"`` statement after all
declarations generated by Cython. This means that the included file
has access to the variables, functions, structures, ... which are
declared by Cython.
Implementing functions in C
Implementing functions in C
---------------------------
---------------------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment