-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-11410: Standardize and use symbol visibility attributes across POSIX and Windows. #16347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
#include "grammar.h" | ||
grammar _PyParser_Grammar; | ||
Py_EXPORTED_SYMBOL grammar _PyParser_Grammar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to not export private symbols (names starting with "_Py"). Or is there a good reason to export that one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't export it, e.g. by using just plain extern
, the parser module fails to build:
building 'parser' extension
gcc -pthread -fPIC -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I/home/vinay/.local/include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/home/vinay/projects/python/master/Include -I/home/vinay/projects/python/master -c /home/vinay/projects/python/master/Modules/parsermodule.c -o build/temp.linux-x86_64-3.9/home/vinay/projects/python/master/Modules/parsermodule.o
gcc -pthread -shared build/temp.linux-x86_64-3.9/home/vinay/projects/python/master/Modules/parsermodule.o -L/home/vinay/.local/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.9/parser.cpython-39-x86_64-linux-gnu.so
*** WARNING: renaming "parser" since importing it failed: build/lib.linux-x86_64-3.9/parser.cpython-39-x86_64-linux-gnu.so: undefined symbol: _PyParser_Grammar
@@ -106,7 +106,7 @@ PyArg_Parse(PyObject *args, const char *format, ...) | |||
return retval; | |||
} | |||
|
|||
int | |||
PyAPI_FUNC(int) | |||
_PyArg_Parse_SizeT(PyObject *args, const char *format, ...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have to export _PyArg symbols in specific? Can't we only configure the visibility in header files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem here is that these aren't declared in any header file - there are forward declarations at the top of Python/getargs.c
with PyAPI_FUNC
(example), but the actual definitions didn't have PyAPI_FUNC
, with the end result that the symbols weren't exported. Adding PyAPI_FUNC
to the definitions fixed that.
To add to the fun, Include/modsupport.h
contains definitions like
#define PyArg_Parse _PyArg_Parse_SizeT
if PY_SSIZE_T_CLEAN
is defined. So a public API is aliased in a common case to what looks like a private API through a #define
! Of course, Include/modsupport.h
is included in Include/Python.h
, so these are used in a lot of places.
@@ -183,4 +185,4 @@ extern PyObject *_PyIO_str_write; | |||
extern PyObject *_PyIO_empty_str; | |||
extern PyObject *_PyIO_empty_bytes; | |||
|
|||
extern PyTypeObject _PyBytesIOBuffer_Type; | |||
extern Py_EXPORTED_SYMBOL PyTypeObject _PyBytesIOBuffer_Type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you export these _io types, they should be private, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if I remove Py_EXPORTED_SYMBOL
here in the header, it's exported via the definition in /Modules/_io/bytesio.c
. If I remove it there too, the _testcapi
module fails to build:
running build
running build_ext
INFO: Can't locate Tcl/Tk libs and/or headers
*** WARNING: renaming "_testcapi" since importing it failed: build/lib.linux-x86_64-3.9/_testcapi.cpython-39-x86_64-linux-gnu.so: undefined symbol: _PyBytesIOBuffer_Type
@@ -0,0 +1,20 @@ | |||
#ifndef Py_EXPORTS_H | |||
#define Py_EXPORTS_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to restrict the number of header files: why not reusing pyport.h?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because exporting symbols is orthogonal to other things. Consider graminit.c
- it's a very low-level module which needs to export a symbol, but doesn't really use any other Python-specific or system-specific stuff. If you replace "exports.h" with "pyport.h" in graminit.c
, you get an error when compiling:
gcc -pthread -c -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I. -I./Include -DPy_BUILD_CORE -o Python/graminit.o Python/graminit.c
In file included from Python/graminit.c:3:0:
./Include/pyport.h:105:9: error: unknown type name ‘ssize_t’
typedef ssize_t Py_ssize_t;
^
./Include/pyport.h:117:9: error: unknown type name ‘size_t’
typedef size_t Py_uhash_t;
^
Makefile:1711: recipe for target 'Python/graminit.o' failed
Including <stddef.h>
before "pyport.h"
doesn't fix things:
gcc -pthread -c -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I. -I./Include -DPy_BUILD_CORE -o Python/graminit.o Python/graminit.c
In file included from Python/graminit.c:3:0:
./Include/pyport.h:105:9: error: unknown type name ‘ssize_t’
typedef ssize_t Py_ssize_t;
^
Makefile:1711: recipe for target 'Python/graminit.o' failed
So you end up having to include "Python.h"
instead, which appears to be overkill as it exposes a lot of things to code in graminit.c
which aren't needed by that code.
When you're done making the requested changes, leave the comment: |
I have made the requested changes; please review again. |
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
BTW I've no idea why GitHub thinks I've started a review of my own PR - I was only replying to Victor's comments, so it's not clear what happened. I can't seem to cancel my spurious review, either. |
OK, refreshing the page seems to have got rid of my spurious review :-) |
Include/exports.h
Outdated
#define Py_EXPORTED_SYMBOL __declspec(dllexport) | ||
#define Py_LOCAL_SYMBOL | ||
#else | ||
#if __GNUC__ >= 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang also supports this attribute.
Using #if __has_attribute(visibility)
should work with both clang and gcc without hardcoding compiler names. This does require GCC 5 or later though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some versions of e.g. Ubuntu and CentOS are still on GCC 4.8. I'll try to generalise it.
visibility attribute is available.
I'd like to merge this - I believe I've adequately addressed comments by both @vstinner and @ronaldoussoren - if there are any objections to merging, please let me know! |
I would suggest checking with the buildbots before merging, as the pr is changing the autotools scripts. |
Pushed this branch to |
@vsajip Thanks for checking! |
https://bugs.python.org/issue11410