Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged
merged 7 commits into from
Oct 15, 2019
Merged

Conversation

vsajip
Copy link
Member

@vsajip vsajip commented Sep 24, 2019

@vsajip vsajip added the type-feature A feature request or enhancement label Sep 24, 2019
@vsajip vsajip requested review from vstinner and njsmith September 24, 2019 04:34
@vsajip vsajip requested a review from pablogsal as a code owner September 24, 2019 04:35
#include "grammar.h"
grammar _PyParser_Grammar;
Py_EXPORTED_SYMBOL grammar _PyParser_Grammar;
Copy link
Member

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?

Copy link
Member Author

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, ...)
Copy link
Member

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?

Copy link
Member Author

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;
Copy link
Member

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?

Copy link
Member Author

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
Copy link
Member

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?

Copy link
Member Author

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.

@bedevere-bot
Copy link

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@vsajip
Copy link
Member Author

vsajip commented Sep 24, 2019

I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@vstinner: please review the changes made to this pull request.

@vsajip
Copy link
Member Author

vsajip commented Sep 24, 2019

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.

@vsajip
Copy link
Member Author

vsajip commented Sep 24, 2019

OK, refreshing the page seems to have got rid of my spurious review :-)

#define Py_EXPORTED_SYMBOL __declspec(dllexport)
#define Py_LOCAL_SYMBOL
#else
#if __GNUC__ >= 4
Copy link
Contributor

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.

Copy link
Member Author

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.

@vsajip
Copy link
Member Author

vsajip commented Oct 14, 2019

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!

@pablogsal
Copy link
Member

I would suggest checking with the buildbots before merging, as the pr is changing the autotools scripts.

@vsajip
Copy link
Member Author

vsajip commented Oct 14, 2019

Pushed this branch to buildbot-custom and looked at the results of the resulting builds. While there are some failures, none appear to be related to this change.

@pablogsal
Copy link
Member

@vsajip Thanks for checking!

@vsajip vsajip merged commit 0b60f64 into python:master Oct 15, 2019
@vsajip vsajip deleted the visibility branch October 15, 2019 07:26
jacobneiltaylor pushed a commit to jacobneiltaylor/cpython that referenced this pull request Dec 5, 2019
shihai1991 pushed a commit to shihai1991/cpython that referenced this pull request Jan 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants