1
1
#!/usr/bin/python
2
2
# ----------------- BEGIN LICENSE BLOCK ---------------------------------
3
3
#
4
- # Copyright (c) 2019-2020 Intel Corporation
4
+ # Copyright (c) 2019-2022 Intel Corporation
5
5
#
6
6
# ----------------- END LICENSE BLOCK -----------------------------------
7
7
@@ -33,15 +33,15 @@ def get_list_of_files(directory, ignore_files):
33
33
for ignore_file in ignore_files :
34
34
if full_path .find (ignore_file ) != - 1 :
35
35
skip = True
36
- print ("Skipping file: " + full_path )
36
+ print ("Skipping file: " + full_path )
37
37
if not skip :
38
38
if full_path .endswith (".h" ) or full_path .endswith (".hpp" ):
39
39
all_files .append (full_path )
40
40
41
41
return all_files
42
42
43
43
44
- def generate_python_wrapper (header_directories , include_paths , library_name , cpp_filename , declarations , main_namespace = "" , ignore_declarations = {}, ignore_files = {}):
44
+ def generate_python_wrapper (header_directories , include_paths , library_name , cpp_filename , declarations , main_namespace = "" , ignore_declarations = {}, ignore_files = {}, add_declarations = {} ):
45
45
"""
46
46
Function to generate Python-C++ binding code by calling pygccxml and py++
47
47
@@ -60,27 +60,30 @@ def generate_python_wrapper(header_directories, include_paths, library_name, cpp
60
60
:type ignore_declarations: list<string>
61
61
:param ignore_files: a list of files to be ignored
62
62
:type ignore_files: list<string>
63
+ :param add_declarations: a list of declarations to be explicitly enabled searched for in
64
+ against the full declaration string resulting from '"{}".format(decl)' output
65
+ (useful e.g. for typedefs to template types which are not as such visible in the delcarations)
66
+ :type add_declarations: list<string>
63
67
:return:
64
68
"""
65
69
66
70
warnings .filterwarnings (action = "once" , category = DeprecationWarning )
67
71
68
72
# Find out the xml generator (gccxml or castxml)
69
73
generator_path , generator_name = utils .find_xml_generator ()
70
- compiler = "g++"
71
- compiler_path = "/usr/bin/g++"
74
+ compiler = "@CXX@"
72
75
73
76
# Create configuration for CastXML
74
77
xml_generator_config = parser .xml_generator_configuration_t (
75
78
xml_generator_path = generator_path ,
76
79
xml_generator = generator_name ,
77
80
compiler = compiler ,
78
- compiler_path = compiler_path ,
79
81
start_with_declarations = declarations )
80
82
81
83
# Set include dirs and cflags to avoid warnings and errors
82
84
xml_generator_config .append_cflags ("-std=c++@CMAKE_CXX_STANDARD@" )
83
85
xml_generator_config .append_cflags ("-Wno-error=invalid-constexpr" )
86
+ xml_generator_config .append_cflags ("-DSAFE_DATATYPES_EXPLICIT_CONVERSION=1" )
84
87
85
88
for inc_dir in include_paths :
86
89
xml_generator_config .include_paths .append (inc_dir )
@@ -124,32 +127,57 @@ def generate_python_wrapper(header_directories, include_paths, library_name, cpp
124
127
top_namespace , main_namespace ))
125
128
126
129
for decl in builder .decls ():
127
- for ignore_declaration in ignore_declarations :
128
- if ignore_declaration in decl .name or ignore_declaration in decl .alias :
129
- decl .exclude ()
130
- decl .ignore = True
131
- decl .already_exposed = True
132
- # print("declaration to ignore found: {} (alias {})".format(decl, decl.alias))
133
- break
130
+ decl_full_string_and_type = "{}" .format (decl )
131
+ # print("declaration {} (alias {}, full {})".format(decl.name, decl.alias, decl_full_string_and_type))
134
132
if main_namespace != "" :
135
- if isinstance (decl , decl_wrappers .class_wrapper .class_t ) or isinstance (decl , decl_wrappers .class_wrapper .class_declaration_t ) or isinstance (decl , decl_wrappers .typedef_wrapper .typedef_t ):
136
- decl_full_string = "{}" . format ( decl )
133
+ if isinstance (decl , decl_wrappers .class_wrapper .class_t ) or isinstance (decl , decl_wrappers .class_wrapper .class_declaration_t ) or isinstance (decl , decl_wrappers .typedef_wrapper .typedef_t ) or isinstance ( decl , decl_wrappers . enumeration_wrapper . enumeration_t ) :
134
+ decl_full_string = decl_full_string_and_type . split ( " " )[ 0 ]
137
135
if main_namespace in decl_full_string :
138
136
# namespace present, ok
139
- # print("typedef/class main namespace found: {}".format(decl_full_string))
140
- continue
141
- if decl_full_string in main_namespace :
137
+ # print("typedef/class/enum main namespace found [ignore-{},exposed-{}]:
138
+ # {}".format(decl.ignore, decl.already_exposed,
139
+ # decl_full_string_and_type))
140
+ pass
141
+ elif decl_full_string in main_namespace :
142
142
# declaration is a parent of main namespace, ok
143
- # print("typedef/class declaration of upper level namespace found: {}".format(decl_full_string))
144
- continue
145
- if top_namespace != "" and not top_namespace in decl_full_string :
143
+ # print("typedef/class/enum declaration of upper level namespace found
144
+ # [ignore{},exposed{}]: {}".format(decl.ignore, decl.already_exposed,
145
+ # decl_full_string_and_type))
146
+ pass
147
+ elif top_namespace != "" and not top_namespace in decl_full_string :
146
148
# global or std defaults, ok
147
- # print("typedef/class outside top namespace found: {}".format(decl_full_string))
148
- continue
149
- # print("typedef/class outside of main namespace found. Ignoring: {}".format(decl_full_string))
149
+ # print("typedef/class/enum outside top namespace found
150
+ # [ignore-{},exposed-{}]: {}".format(decl.ignore, decl.already_exposed,
151
+ # decl_full_string_and_type))
152
+ pass
153
+ else :
154
+ # print("typedef/class/enum outside of main namespace found
155
+ # [ignore-{},exposed-{}]. Ignoring: {}".format(decl.ignore,
156
+ # decl.already_exposed, decl_full_string_and_type))
157
+ decl .exclude ()
158
+ decl .ignore = True
159
+ # try to enforce that it's not exported anymore
160
+ decl .already_exposed = True
161
+
162
+ if decl .ignore :
163
+ if decl_full_string in declarations :
164
+ decl .ignore = False
165
+ decl .already_exposed = False
166
+ # print("Ignored typedef/class/enum explicitly listed in delclarations
167
+ # found. Reenable {}".format(decl_full_string_and_type))
168
+ for add_declaration in add_declarations :
169
+ if (add_declaration in decl .name ) or (add_declaration in decl .alias ) or (add_declaration in decl_full_string_and_type ):
170
+ decl .ignore = False
171
+ decl .already_exposed = False
172
+ # print("declaration to explicitly add found: {} (alias {})".format(decl, decl.alias))
173
+ break
174
+ for ignore_declaration in ignore_declarations :
175
+ if (ignore_declaration in decl .name ) or (ignore_declaration in decl .alias ) or (ignore_declaration in decl_full_string_and_type ):
150
176
decl .exclude ()
151
177
decl .ignore = True
152
178
decl .already_exposed = True
179
+ # print("declaration to ignore found: {} (alias {})".format(decl, decl.alias))
180
+ break
153
181
154
182
# debug declarations
155
183
# builder.print_declarations()
@@ -168,7 +196,7 @@ def generate_python_wrapper(header_directories, include_paths, library_name, cpp
168
196
print ("generate_python_wrapper(): {} written." .format (cpp_filename ))
169
197
170
198
171
- def post_process_python_wrapper (header_directories , cpp_filename_in , cpp_filename_out , additional_replacements = {} , additional_includes = {}, spdx_license = "MIT" , fix_include_directives = True , fix_enum_class = True ):
199
+ def post_process_python_wrapper (header_directories , cpp_filename_in , cpp_filename_out , additional_replacements = [] , additional_includes = {}, spdx_license = "MIT" , fix_include_directives = True , fix_enum_class = True ):
172
200
"""
173
201
Post process generated binding code
174
202
@@ -204,7 +232,7 @@ def post_process_python_wrapper(header_directories, cpp_filename_in, cpp_filenam
204
232
file_output .write ("/*\n "
205
233
" * ----------------- BEGIN LICENSE BLOCK ---------------------------------\n "
206
234
" *\n "
207
- " * Copyright (c) 2020 Intel Corporation\n "
235
+ " * Copyright (c) 2020-2021 Intel Corporation\n "
208
236
" *\n "
209
237
" * SPDX-License-Identifier: " + spdx_license + "\n "
210
238
" *\n "
@@ -228,15 +256,15 @@ def post_process_python_wrapper(header_directories, cpp_filename_in, cpp_filenam
228
256
for header_dir in header_directories :
229
257
if not header_dir .endswith ("/" ):
230
258
header_dir = header_dir + "/"
231
- line = line .replace (header_dir , "" )
259
+ line = str .replace (line , header_dir , "" )
232
260
233
261
# Fix C++ enum classes
234
262
if fix_enum_class :
235
263
if enum_started :
236
264
if line .find ("export_values()" ) != - 1 :
237
265
enum_started = False
238
266
else :
239
- line = line .replace (enum_namespace , enum_namespace_full )
267
+ line = str .replace (line , enum_namespace , enum_namespace_full )
240
268
else :
241
269
match = enum_declaration_start .match (line )
242
270
if match :
@@ -246,7 +274,7 @@ def post_process_python_wrapper(header_directories, cpp_filename_in, cpp_filenam
246
274
enum_namespace_full = match .group (1 ) + "::"
247
275
248
276
for replacement in additional_replacements :
249
- line = line .replace (replacement [0 ], replacement [1 ])
277
+ line = str .replace (line , replacement [0 ], replacement [1 ])
250
278
251
279
file_output .write (line )
252
280
0 commit comments