Author: Maciej Fijalkowski <[email protected]>
Branch: 
Changeset: r74159:0d91180baad9
Date: 2014-10-24 13:29 +0200
http://bitbucket.org/pypy/pypy/changeset/0d91180baad9/

Log:    (arigo, fijal) Merge a branch that exports symbols via
        __attribute__((visibility("default"))) or equivalent hack.

        This should improve performance that dropped after -fPIC is compiled
        by default

diff too long, truncating to 2000 out of 3152 lines

diff --git a/pypy/module/_cffi_backend/test/_test_lib.c 
b/pypy/module/_cffi_backend/test/_test_lib.c
--- a/pypy/module/_cffi_backend/test/_test_lib.c
+++ b/pypy/module/_cffi_backend/test/_test_lib.c
@@ -1,12 +1,8 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <errno.h>
+#include "src/precommondefs.h"
 
-#ifdef _WIN32
-#define DLLEXPORT __declspec(dllexport)
-#else
-#define DLLEXPORT
-#endif
 
 static char _testfunc0(char a, char b)
 {
@@ -180,7 +176,7 @@
     return -42;
 }
 
-DLLEXPORT void *gettestfunc(int num)
+RPY_EXPORTED void *gettestfunc(int num)
 {
     void *f;
     switch (num) {
diff --git a/pypy/module/_cffi_backend/test/test_c.py 
b/pypy/module/_cffi_backend/test/test_c.py
--- a/pypy/module/_cffi_backend/test/test_c.py
+++ b/pypy/module/_cffi_backend/test/test_c.py
@@ -22,6 +22,7 @@
 from rpython.tool.udir import udir
 from pypy.interpreter import gateway
 from pypy.module._cffi_backend import Module
+from rpython.translator import cdir
 from rpython.translator.platform import host
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
@@ -51,7 +52,7 @@
         test_lib_c = tmpdir.join('_test_lib.c')
         src_test_lib_c = py.path.local(__file__).dirpath().join('_test_lib.c')
         src_test_lib_c.copy(test_lib_c)
-        eci = ExternalCompilationInfo()
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         test_lib = host.compile([test_lib_c], eci, standalone=False)
 
         cdll = ctypes.CDLL(str(test_lib))
diff --git a/pypy/module/_lsprof/interp_lsprof.py 
b/pypy/module/_lsprof/interp_lsprof.py
--- a/pypy/module/_lsprof/interp_lsprof.py
+++ b/pypy/module/_lsprof/interp_lsprof.py
@@ -20,8 +20,8 @@
 
 srcdir = py.path.local(cdir).join('src')
 eci = ExternalCompilationInfo(
-    separate_module_files=[srcdir.join('profiling.c')],
-    export_symbols=['pypy_setup_profiling', 'pypy_teardown_profiling'])
+    include_dirs          = [cdir],
+    separate_module_files = [srcdir.join('profiling.c')])
 
 c_setup_profiling = rffi.llexternal('pypy_setup_profiling',
                                   [], lltype.Void,
diff --git a/pypy/module/_multibytecodec/c_codecs.py 
b/pypy/module/_multibytecodec/c_codecs.py
--- a/pypy/module/_multibytecodec/c_codecs.py
+++ b/pypy/module/_multibytecodec/c_codecs.py
@@ -1,6 +1,7 @@
 import py
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.translator import cdir
 
 UNICODE_REPLACEMENT_CHARACTER = u'\uFFFD'
 
@@ -49,20 +50,7 @@
         srcdir.join('src', 'cjkcodecs', 'multibytecodec.c'),
     ],
     includes = ['src/cjkcodecs/multibytecodec.h'],
-    include_dirs = [str(srcdir)],
-    export_symbols = [
-        "pypy_cjk_dec_new",
-        "pypy_cjk_dec_init", "pypy_cjk_dec_free", "pypy_cjk_dec_chunk",
-        "pypy_cjk_dec_outbuf", "pypy_cjk_dec_outlen",
-        "pypy_cjk_dec_inbuf_remaining", "pypy_cjk_dec_inbuf_consumed",
-        "pypy_cjk_dec_replace_on_error",
-
-        "pypy_cjk_enc_new",
-        "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk",
-        "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen",
-        "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed",
-        "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec",
-    ] + ["pypy_cjkcodec_%s" % codec for codec in codecs],
+    include_dirs = [str(srcdir), cdir],
 )
 
 MBERR_TOOSMALL = -1  # insufficient output buffer space
diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h 
b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
--- a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
+++ b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h
@@ -2,6 +2,8 @@
 #ifndef _PYPY_MULTIBYTECODEC_H_
 #define _PYPY_MULTIBYTECODEC_H_
 
+#include "src/precommondefs.h"
+
 
 #include <stddef.h>
 #include <assert.h>
@@ -95,15 +97,24 @@
   Py_UNICODE *outbuf_start, *outbuf, *outbuf_end;
 };
 
+RPY_EXPORTED_FOR_TESTS
 struct pypy_cjk_dec_s *pypy_cjk_dec_new(const MultibyteCodec *codec);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_dec_init(struct pypy_cjk_dec_s *d,
                              char *inbuf, Py_ssize_t inlen);
+RPY_EXPORTED_FOR_TESTS
 void pypy_cjk_dec_free(struct pypy_cjk_dec_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_dec_chunk(struct pypy_cjk_dec_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_UNICODE *pypy_cjk_dec_outbuf(struct pypy_cjk_dec_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_dec_outlen(struct pypy_cjk_dec_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_dec_inbuf_remaining(struct pypy_cjk_dec_s *d);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_dec_inbuf_consumed(struct pypy_cjk_dec_s* d);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_dec_replace_on_error(struct pypy_cjk_dec_s* d,
                                          Py_UNICODE *, Py_ssize_t, Py_ssize_t);
 
@@ -114,24 +125,35 @@
   unsigned char *outbuf_start, *outbuf, *outbuf_end;
 };
 
+RPY_EXPORTED_FOR_TESTS
 struct pypy_cjk_enc_s *pypy_cjk_enc_new(const MultibyteCodec *codec);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_init(struct pypy_cjk_enc_s *d,
                              Py_UNICODE *inbuf, Py_ssize_t inlen);
+RPY_EXPORTED_FOR_TESTS
 void pypy_cjk_enc_free(struct pypy_cjk_enc_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_chunk(struct pypy_cjk_enc_s *, Py_ssize_t);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_reset(struct pypy_cjk_enc_s *);
+RPY_EXPORTED_FOR_TESTS
 char *pypy_cjk_enc_outbuf(struct pypy_cjk_enc_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_outlen(struct pypy_cjk_enc_s *);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_inbuf_remaining(struct pypy_cjk_enc_s *d);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_inbuf_consumed(struct pypy_cjk_enc_s* d);
+RPY_EXPORTED_FOR_TESTS
 Py_ssize_t pypy_cjk_enc_replace_on_error(struct pypy_cjk_enc_s* d,
                                          char *, Py_ssize_t, Py_ssize_t);
+RPY_EXPORTED_FOR_TESTS
 const MultibyteCodec *pypy_cjk_enc_getcodec(struct pypy_cjk_enc_s *);
 
 /* list of codecs defined in the .c files */
 
 #define DEFINE_CODEC(name)                              \
-    MultibyteCodec *pypy_cjkcodec_##name(void);
+    RPY_EXPORTED_FOR_TESTS MultibyteCodec *pypy_cjkcodec_##name(void);
 
 // _codecs_cn
 DEFINE_CODEC(gb2312)
diff --git a/pypy/module/_rawffi/alt/test/test_funcptr.py 
b/pypy/module/_rawffi/alt/test/test_funcptr.py
--- a/pypy/module/_rawffi/alt/test/test_funcptr.py
+++ b/pypy/module/_rawffi/alt/test/test_funcptr.py
@@ -1,4 +1,5 @@
 from rpython.rtyper.lltypesystem import rffi
+from rpython.translator import cdir
 from rpython.rlib.clibffi import get_libc_name
 from rpython.rlib.libffi import types
 from rpython.rlib.libffi import CDLL
@@ -18,11 +19,8 @@
         c_file = udir.ensure("test__ffi", dir=1).join("foolib.c")
         # automatically collect the C source from the docstrings of the tests
         snippets = ["""
-        #ifdef _WIN32
-        #define DLLEXPORT __declspec(dllexport)
-        #else
-        #define DLLEXPORT
-        #endif
+        #include "src/precommondefs.h"
+        #define DLLEXPORT RPY_EXPORTED
         """]
         for name in dir(cls):
             if name.startswith('test_'):
@@ -33,7 +31,7 @@
                     snippets.append(meth.__doc__)
         #
         c_file.write(py.code.Source('\n'.join(snippets)))
-        eci = ExternalCompilationInfo(export_symbols=[])
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         return str(platform.compile([c_file], eci, 'x', standalone=False))
 
     def setup_class(cls):
diff --git a/pypy/module/_rawffi/test/test__rawffi.py 
b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -1,5 +1,6 @@
 from rpython.translator.platform import platform
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.translator import cdir
 from pypy.module._rawffi.interp_rawffi import TYPEMAP, TYPEMAP_FLOAT_LETTERS
 from pypy.module._rawffi.tracker import Tracker
 
@@ -12,6 +13,7 @@
         from rpython.tool.udir import udir
         c_file = udir.ensure("test__rawffi", dir=1).join("xlib.c")
         c_file.write(py.code.Source('''
+        #include "src/precommondefs.h"
         #include <stdlib.h>
         #include <stdio.h>
 
@@ -23,15 +25,18 @@
            struct x* next;
         };
 
+        RPY_EXPORTED
         void nothing()
         {
         }
 
+        RPY_EXPORTED
         char inner_struct_elem(struct x *x1)
         {
            return x1->next->x3;
         }
 
+        RPY_EXPORTED
         struct x* create_double_struct()
         {
            struct x* x1, *x2;
@@ -43,6 +48,7 @@
            return x1;
         }
 
+        RPY_EXPORTED
         void free_double_struct(struct x* x1)
         {
             free(x1->next);
@@ -50,25 +56,32 @@
         }
 
         const char *static_str = "xxxxxx";
+        RPY_EXPORTED
         long static_int = 42;
+        RPY_EXPORTED
         double static_double = 42.42;
+        RPY_EXPORTED
         long double static_longdouble = 42.42;
 
+        RPY_EXPORTED
         unsigned short add_shorts(short one, short two)
         {
            return one + two;
         }
 
+        RPY_EXPORTED
         void* get_raw_pointer()
         {
            return (void*)add_shorts;
         }
 
+        RPY_EXPORTED
         char get_char(char* s, unsigned short num)
         {
            return s[num];
         }
 
+        RPY_EXPORTED
         const char *char_check(char x, char y)
         {
            if (y == static_str[0])
@@ -76,26 +89,31 @@
            return NULL;
         }
 
+        RPY_EXPORTED
         int get_array_elem(int* stuff, int num)
         {
            return stuff[num];
         }
 
+        RPY_EXPORTED
         struct x* get_array_elem_s(struct x** array, int num)
         {
            return array[num];
         }
 
+        RPY_EXPORTED
         long long some_huge_value()
         {
            return 1LL<<42;
         }
 
+        RPY_EXPORTED
         unsigned long long some_huge_uvalue()
         {
            return 1LL<<42;
         }
 
+        RPY_EXPORTED
         long long pass_ll(long long x)
         {
            return x;
@@ -103,11 +121,13 @@
 
         static int prebuilt_array1[] = {3};
 
+        RPY_EXPORTED
         int* allocate_array()
         {
             return prebuilt_array1;
         }
 
+        RPY_EXPORTED
         long long runcallback(long long(*callback)())
         {
             return callback();
@@ -118,10 +138,12 @@
             long y;
         };
 
+        RPY_EXPORTED
         long sum_x_y(struct x_y s) {
             return s.x + s.y;
         }
 
+        RPY_EXPORTED
         long op_x_y(struct x_y s, long(*callback)(struct x_y))
         {
             return callback(s);
@@ -132,6 +154,7 @@
             short y;
         };
 
+        RPY_EXPORTED
         struct s2h give(short x, short y) {
             struct s2h out;
             out.x = x;
@@ -139,6 +162,7 @@
             return out;
         }
 
+        RPY_EXPORTED
         struct s2h perturb(struct s2h inp) {
             inp.x *= 2;
             inp.y *= 3;
@@ -149,6 +173,7 @@
             int bah[2];
         };
 
+        RPY_EXPORTED
         struct s2a get_s2a(void) {
             struct s2a outp;
             outp.bah[0] = 4;
@@ -156,10 +181,12 @@
             return outp;
         }
 
+        RPY_EXPORTED
         int check_s2a(struct s2a inp) {
             return (inp.bah[0] == 4 && inp.bah[1] == 5);
         }
 
+        RPY_EXPORTED
         int AAA_first_ordinal_function()
         {
             return 42;
@@ -170,6 +197,7 @@
             long y;
         } UN;
 
+        RPY_EXPORTED
         UN ret_un_func(UN inp)
         {
             inp.y = inp.x * 100;
@@ -177,21 +205,7 @@
         }
 
         '''))
-        symbols = """get_char char_check get_raw_pointer
-                     add_shorts
-                     inner_struct_elem create_double_struct free_double_struct
-                     get_array_elem get_array_elem_s
-                     nothing
-                     some_huge_value some_huge_uvalue pass_ll
-                     runcallback
-                     allocate_array
-                     static_int static_double static_longdouble
-                     sum_x_y op_x_y
-                     give perturb get_s2a check_s2a
-                     AAA_first_ordinal_function
-                     ret_un_func
-                  """.split()
-        eci = ExternalCompilationInfo(export_symbols=symbols)
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         return str(platform.compile([c_file], eci, 'x', standalone=False))
     prepare_c_example = staticmethod(prepare_c_example)
 
diff --git a/pypy/module/_ssl/thread_lock.py b/pypy/module/_ssl/thread_lock.py
--- a/pypy/module/_ssl/thread_lock.py
+++ b/pypy/module/_ssl/thread_lock.py
@@ -65,8 +65,7 @@
 eci = rthread.eci.merge(ExternalCompilationInfo(
     separate_module_sources=[separate_module_source],
     post_include_bits=[
-        "int _PyPy_SSL_SetupThreads(void);"],
-    export_symbols=['_PyPy_SSL_SetupThreads'],
+        "RPY_EXPORTED_FOR_TESTS int _PyPy_SSL_SetupThreads(void);"],
     libraries = libraries,
 ))
 
diff --git a/pypy/module/cppyy/src/dummy_backend.cxx 
b/pypy/module/cppyy/src/dummy_backend.cxx
--- a/pypy/module/cppyy/src/dummy_backend.cxx
+++ b/pypy/module/cppyy/src/dummy_backend.cxx
@@ -1,3 +1,4 @@
+#include "src/precommondefs.h"
 #include "cppyy.h"
 #include "capi.h"
 
@@ -348,24 +349,29 @@
 
 
 /* name to opaque C++ scope representation -------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 int cppyy_num_scopes(cppyy_scope_t handle) {
     return 0;
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_resolve_name(const char* cppitem_name) {
     return cppstring_to_cstring(cppitem_name);
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_scope_t cppyy_get_scope(const char* scope_name) {
     return s_handles[scope_name];  // lookup failure will return 0 (== error)
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t /* obj */) {
     return klass;
 }
 
 
 /* memory management ------------------------------------------------------ */
+RPY_EXPORTED_FOR_TESTS
 void cppyy_destruct(cppyy_type_t handle, cppyy_object_t self) {
     if (handle == s_handles["example01"])
        delete (dummy::example01*)self;
@@ -373,6 +379,7 @@
 
 
 /* method/function dispatching -------------------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* 
args) {
     long idx = (long)method;
     if (idx == 
s_methods["static_example01::staticSetPayload_payload*_double"]) {
@@ -462,6 +469,7 @@
     }
 }
 
+RPY_EXPORTED_FOR_TESTS
 unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int 
nargs, void* args) {
     unsigned char result = 0;
     const long idx = (long)method;
@@ -474,6 +482,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* 
args) {
     char result = 0;
     const long idx = (long)method;
@@ -489,6 +498,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
     short result = 0;
     const long idx = (long)method; 
@@ -504,6 +514,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* 
args) {
     int result = 0;
     const long idx = (long)method;
@@ -536,6 +547,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* 
args) {
     long result = 0;
     const long idx = (long)method;
@@ -677,6 +689,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 long long cppyy_call_ll(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
     long long result = 0;
     const long idx = (long)method;
@@ -692,6 +705,7 @@
     return result;
 }   
 
+RPY_EXPORTED_FOR_TESTS
 float cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
     float result = 0;
     const long idx = (long)method;
@@ -704,6 +718,7 @@
     return result;
 }   
 
+RPY_EXPORTED_FOR_TESTS
 double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
     double result = 0.;
     const long idx = (long)method;
@@ -725,6 +740,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
     char* result = 0;
     const long idx = (long)method;
@@ -737,6 +753,7 @@
     return result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t handle, 
int nargs, void* args) {
     void* result = 0;
     const long idx = (long)method;
@@ -759,12 +776,14 @@
     return (cppyy_object_t)result;
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t /* handle */, 
cppyy_index_t /* method_index */) {
     return (cppyy_methptrgetter_t)0;
 }
 
 
 /* handling of function argument buffer ----------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 void* cppyy_allocate_function_args(int nargs) {
     CPPYY_G__value* args = 
(CPPYY_G__value*)malloc(nargs*sizeof(CPPYY_G__value));
     for (int i = 0; i < nargs; ++i)
@@ -774,30 +793,36 @@
 
 
 /* handling of function argument buffer ----------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 void cppyy_deallocate_function_args(void* args) {
     free(args);
 }
 
+RPY_EXPORTED_FOR_TESTS
 size_t cppyy_function_arg_sizeof() {
     return sizeof(CPPYY_G__value);
 }
 
+RPY_EXPORTED_FOR_TESTS
 size_t cppyy_function_arg_typeoffset() {
     return offsetof(CPPYY_G__value, type);
 }
 
 
 /* scope reflection information ------------------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 int cppyy_is_namespace(cppyy_scope_t /* handle */) {
     return 0;
 }   
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_is_enum(const char* /* type_name */) {
     return 0;
 }
     
     
 /* class reflection information ------------------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_final_name(cppyy_type_t handle) {
     for (Handles_t::iterator isp = s_handles.begin(); isp != s_handles.end(); 
++isp) {
         if (isp->second == handle)
@@ -806,61 +831,75 @@
     return cppstring_to_cstring("<unknown>");
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_scoped_final_name(cppyy_type_t handle) {
     return cppyy_final_name(handle);
 }   
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_has_complex_hierarchy(cppyy_type_t /* handle */) {
     return 0;
 }
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_num_bases(cppyy_type_t /*handle*/) {
    return 0;
 }
 
 
 /* method/function reflection information --------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 int cppyy_num_methods(cppyy_scope_t handle) {
     return s_scopes[handle].m_methods.size();
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_index_t cppyy_method_index_at(cppyy_scope_t /* scope */, int imeth) {
     return (cppyy_index_t)imeth;
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t method_index) {
     return 
cppstring_to_cstring(s_scopes[handle].m_methods[(int)method_index].m_name);
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t 
method_index) {
     return 
cppstring_to_cstring(s_scopes[handle].m_methods[method_index].m_returntype);
 }
     
+RPY_EXPORTED_FOR_TESTS
 int cppyy_method_num_args(cppyy_scope_t handle, cppyy_index_t method_index) {
     return s_scopes[handle].m_methods[method_index].m_argtypes.size();
 }
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_method_req_args(cppyy_scope_t handle, cppyy_index_t method_index) {
     return cppyy_method_num_args(handle, method_index);
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_method_arg_type(cppyy_scope_t handle, cppyy_index_t method_index, 
int arg_index) {
     return 
cppstring_to_cstring(s_scopes[handle].m_methods[method_index].m_argtypes[arg_index]);
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_method_arg_default(
         cppyy_scope_t /* handle */, cppyy_index_t /* method_index */, int /* 
arg_index */) {
     return cppstring_to_cstring("");
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_method_signature(cppyy_scope_t /* handle */, cppyy_index_t /* 
method_index */) {
     return cppstring_to_cstring("");
 }
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_method_is_template(cppyy_scope_t /* handle */, cppyy_index_t /* 
method_index */) {
     return 0;
 }
     
+RPY_EXPORTED_FOR_TESTS
 cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t 
method_index) {
     if (s_scopes.find(handle) != s_scopes.end()) {
         long id = s_scopes[handle].m_method_offset + (long)method_index;
@@ -872,6 +911,7 @@
 
 
 /* method properties -----------------------------------------------------  */
+RPY_EXPORTED_FOR_TESTS
 int cppyy_is_constructor(cppyy_type_t handle, cppyy_index_t method_index) {
     if (s_scopes.find(handle) != s_scopes.end())
         return s_scopes[handle].m_methods[method_index].m_type == kConstructor;
@@ -879,6 +919,7 @@
     return 0;
 }
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_is_staticmethod(cppyy_type_t handle, cppyy_index_t method_index) {
     if (s_scopes.find(handle) != s_scopes.end())
         return s_scopes[handle].m_methods[method_index].m_type == kStatic;
@@ -888,28 +929,34 @@
 
 
 /* data member reflection information ------------------------------------- */
+RPY_EXPORTED_FOR_TESTS
 int cppyy_num_datamembers(cppyy_scope_t handle) {
     return s_scopes[handle].m_datambrs.size();
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_datamember_name(cppyy_scope_t handle, int idatambr) {
     return cppstring_to_cstring(s_scopes[handle].m_datambrs[idatambr].m_name);
 }
 
+RPY_EXPORTED_FOR_TESTS
 char* cppyy_datamember_type(cppyy_scope_t handle, int idatambr) {
     return cppstring_to_cstring(s_scopes[handle].m_datambrs[idatambr].m_type);
 }
 
+RPY_EXPORTED_FOR_TESTS
 ptrdiff_t cppyy_datamember_offset(cppyy_scope_t handle, int idatambr) {
     return s_scopes[handle].m_datambrs[idatambr].m_offset;
 }
 
 
 /* data member properties ------------------------------------------------  */
+RPY_EXPORTED_FOR_TESTS
 int cppyy_is_publicdata(cppyy_scope_t handle, int idatambr) {
     return 1;
 }
 
+RPY_EXPORTED_FOR_TESTS
 int cppyy_is_staticdata(cppyy_scope_t handle, int idatambr) {
     return s_scopes[handle].m_datambrs[idatambr].m_isstatic;
 }
@@ -917,33 +964,44 @@
 
 /* misc helpers ----------------------------------------------------------- */
 #if defined(_MSC_VER)
+RPY_EXPORTED_FOR_TESTS
 long long cppyy_strtoll(const char* str) {
     return _strtoi64(str, NULL, 0);
 }
 
-extern "C" unsigned long long cppyy_strtoull(const char* str) {
+extern "C" {
+RPY_EXPORTED_FOR_TESTS
+unsigned long long cppyy_strtoull(const char* str) {
     return _strtoui64(str, NULL, 0);
 }
+}
 #else
+RPY_EXPORTED_FOR_TESTS
 long long cppyy_strtoll(const char* str) {
     return strtoll(str, NULL, 0);
 }
 
-extern "C" unsigned long long cppyy_strtoull(const char* str) {
+extern "C" {
+RPY_EXPORTED_FOR_TESTS
+unsigned long long cppyy_strtoull(const char* str) {
     return strtoull(str, NULL, 0);
 }
+}
 #endif
 
+RPY_EXPORTED_FOR_TESTS
 void cppyy_free(void* ptr) {
     free(ptr);
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_object_t cppyy_charp2stdstring(const char* str) {
     void* arena = new char[sizeof(std::string)];
     new (arena) std::string(str);
     return (cppyy_object_t)arena;
 }
 
+RPY_EXPORTED_FOR_TESTS
 cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr) {
     void* arena = new char[sizeof(std::string)];
     new (arena) std::string(*(std::string*)ptr);
diff --git a/pypy/module/cppyy/test/conftest.py 
b/pypy/module/cppyy/test/conftest.py
--- a/pypy/module/cppyy/test/conftest.py
+++ b/pypy/module/cppyy/test/conftest.py
@@ -38,6 +38,7 @@
             import os
             from rpython.translator.tool.cbuild import ExternalCompilationInfo
             from rpython.translator.platform import platform
+            from rpython.translator import cdir
 
             from rpython.rtyper.lltypesystem import rffi
 
@@ -48,7 +49,8 @@
 
             eci = ExternalCompilationInfo(
                 separate_module_files=[srcpath.join('dummy_backend.cxx')],
-                include_dirs=[incpath, tstpath],
+                include_dirs=[incpath, tstpath, cdir],
+                compile_extra=['-DRPY_EXPORTED_FOR_TESTS=RPY_EXPORTED'],
                 use_cpp_linker=True,
             )
 
diff --git a/pypy/module/cppyy/test/test_crossing.py 
b/pypy/module/cppyy/test/test_crossing.py
--- a/pypy/module/cppyy/test/test_crossing.py
+++ b/pypy/module/cppyy/test/test_crossing.py
@@ -50,7 +50,7 @@
 
     modname = modname.split('.')[-1]
     eci = ExternalCompilationInfo(
-        export_symbols=['init%s' % (modname,)]+symbols,
+        #export_symbols=['init%s' % (modname,)]+symbols,
         include_dirs=api.include_dirs,
         **kwds
         )
@@ -89,7 +89,8 @@
             #include <Python.h>
             %(body)s
 
-            void init%(name)s(void) {
+            PyMODINIT_FUNC
+            init%(name)s(void) {
             %(init)s
             }
             """ % dict(name=name, init=init, body=body)
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -775,6 +775,7 @@
     struct PyPyAPI {
     %(members)s
     } _pypyAPI;
+    RPY_EXPORTED_FOR_TESTS
     struct PyPyAPI* pypyAPI = &_pypyAPI;
     """ % dict(members=structmembers)
 
@@ -946,9 +947,8 @@
         name_no_star = process_va_name(name)
         header = ('%s pypy_va_get_%s(va_list* vp)' %
                   (name, name_no_star))
-        pypy_decls.append(header + ';')
+        pypy_decls.append('RPY_EXPORTED_FOR_TESTS ' + header + ';')
         functions.append(header + '\n{return va_arg(*vp, %s);}\n' % name)
-        export_symbols.append('pypy_va_get_%s' % (name_no_star,))
 
     for name, (typ, expr) in GLOBALS.iteritems():
         if name.endswith('#'):
@@ -974,7 +974,6 @@
     "NOT_RPYTHON"
     # Build code and get pointer to the structure
     kwds = {}
-    export_symbols_eci = export_symbols[:]
 
     compile_extra=['-DPy_BUILD_CORE']
 
@@ -988,7 +987,6 @@
         elif sys.platform.startswith('linux'):
             compile_extra.append("-Werror=implicit-function-declaration")
             compile_extra.append('-g')
-        export_symbols_eci.append('pypyAPI')
     else:
         kwds["includes"] = ['Python.h'] # this is our Python.h
 
@@ -1009,6 +1007,7 @@
     if sys.platform == 'win32':
         get_pythonapi_source = '''
         #include <windows.h>
+        RPY_EXPORTED_FOR_TESTS
         HANDLE pypy_get_pythonapi_handle() {
             MEMORY_BASIC_INFORMATION  mi;
             memset(&mi, 0, sizeof(mi));
@@ -1021,7 +1020,6 @@
         }
         '''
         separate_module_sources.append(get_pythonapi_source)
-        export_symbols_eci.append('pypy_get_pythonapi_handle')
 
     eci = ExternalCompilationInfo(
         include_dirs=include_dirs,
@@ -1044,7 +1042,6 @@
                                source_dir / "missing.c",
                                ],
         separate_module_sources=separate_module_sources,
-        export_symbols=export_symbols_eci,
         compile_extra=compile_extra,
         **kwds
         )
diff --git a/pypy/module/cpyext/include/Python.h 
b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -11,8 +11,8 @@
 # include <errno.h>
 # include <unistd.h>
 # define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
-# define PyAPI_FUNC(RTYPE) RTYPE
-# define PyAPI_DATA(RTYPE) extern RTYPE
+# define PyAPI_FUNC(RTYPE) __attribute__((visibility("default"))) RTYPE
+# define PyAPI_DATA(RTYPE) extern PyAPI_FUNC(RTYPE)
 # define Py_LOCAL_INLINE(type) static inline type
 #else
 # define MS_WIN32 1
@@ -47,7 +47,7 @@
 # endif
 #endif
 #ifndef DL_EXPORT
-#       define DL_EXPORT(RTYPE) RTYPE
+#       define DL_EXPORT(RTYPE) PyAPI_FUNC(RTYPE)
 #endif
 #ifndef DL_IMPORT
 #       define DL_IMPORT(RTYPE) RTYPE
diff --git a/pypy/module/cpyext/include/bufferobject.h 
b/pypy/module/cpyext/include/bufferobject.h
--- a/pypy/module/cpyext/include/bufferobject.h
+++ b/pypy/module/cpyext/include/bufferobject.h
@@ -26,18 +26,18 @@
 
 #define Py_END_OF_BUFFER       (-1)
 
-PyObject* PyBuffer_FromObject(PyObject *base,
+PyAPI_FUNC(PyObject *) PyBuffer_FromObject(PyObject *base,
                                            Py_ssize_t offset, Py_ssize_t size);
-PyObject* PyBuffer_FromReadWriteObject(PyObject *base,
+PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteObject(PyObject *base,
                                                     Py_ssize_t offset,
                                                     Py_ssize_t size);
 
-PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size);
-PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size);
+PyAPI_FUNC(PyObject *) PyBuffer_FromMemory(void *ptr, Py_ssize_t size);
+PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t 
size);
 
-PyObject* PyBuffer_New(Py_ssize_t size);
+PyAPI_FUNC(PyObject *) PyBuffer_New(Py_ssize_t size);
 
-PyTypeObject *_Py_get_buffer_type(void);
+PyAPI_FUNC(PyTypeObject *) _Py_get_buffer_type(void);
 
 #ifdef __cplusplus
 }
diff --git a/pypy/module/cpyext/include/eval.h 
b/pypy/module/cpyext/include/eval.h
--- a/pypy/module/cpyext/include/eval.h
+++ b/pypy/module/cpyext/include/eval.h
@@ -19,14 +19,14 @@
 #define PyEval_CallObject(func,arg) \
         PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
 
-PyObject * PyEval_CallFunction(PyObject *obj, const char *format, ...);
-PyObject * PyEval_CallMethod(PyObject *obj, const char *name, const char 
*format, ...);
-PyObject * PyObject_CallFunction(PyObject *obj, const char *format, ...);
-PyObject * PyObject_CallMethod(PyObject *obj, const char *name, const char 
*format, ...);
-PyObject * _PyObject_CallFunction_SizeT(PyObject *obj, const char *format, 
...);
-PyObject * _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, const 
char *format, ...);
-PyObject * PyObject_CallFunctionObjArgs(PyObject *callable, ...);
-PyObject * PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...);
+PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj, const char *format, 
...);
+PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, const char *name, 
const char *format, ...);
+PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *obj, const char 
*format, ...);
+PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj, const char *name, 
const char *format, ...);
+PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *obj, const char 
*format, ...);
+PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj, const char 
*name, const char *format, ...);
+PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, ...);
+PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(PyObject *callable, PyObject 
*name, ...);
 
 /* These constants are also defined in cpyext/eval.py */
 #define Py_single_input 256
diff --git a/pypy/module/cpyext/include/modsupport.h 
b/pypy/module/cpyext/include/modsupport.h
--- a/pypy/module/cpyext/include/modsupport.h
+++ b/pypy/module/cpyext/include/modsupport.h
@@ -29,24 +29,24 @@
 #define PYTHON_API_VERSION 1013
 #define PYTHON_API_STRING "1013"
 
-int PyArg_Parse(PyObject *, const char *, ...);
-int PyArg_ParseTuple(PyObject *, const char *, ...);
-int PyArg_VaParse(PyObject *, const char *, va_list);
+PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...);
+PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
+PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list);
 
-int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
+PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
                                const char *, char **, ...);
-int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
+PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
                                const char *, char **, va_list);
 
-int _PyArg_Parse_SizeT(PyObject *, const char *, ...);
-int _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
-int _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
+PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
+PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
 
-int _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
                                const char *, char **, ...);
-int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
                                const char *, char **, va_list);
-  
+
 /* to make sure that modules compiled with CPython's or PyPy's Python.h
    are not importable on the other interpreter, use a #define to expect a
    different symbol: (this function is implemented in ../modsupport.py) */
@@ -60,28 +60,28 @@
        Py_InitModule4(name, methods, doc, (PyObject *)NULL, \
                       PYTHON_API_VERSION)
 
-int PyModule_AddObject(PyObject *m, const char *name, PyObject *o);
-int PyModule_AddIntConstant(PyObject *m, const char *name, long value);
-int PyModule_AddStringConstant(PyObject *m, const char *name, const char 
*value);
+PyAPI_FUNC(int) PyModule_AddObject(PyObject *m, const char *name, PyObject *o);
+PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *m, const char *name, long 
value);
+PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *m, const char *name, 
const char *value);
 #define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c)
 #define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c)
 
 
-PyObject * Py_BuildValue(const char *, ...);
-PyObject * Py_VaBuildValue(const char *, va_list);
-PyObject * _Py_BuildValue_SizeT(const char *, ...);
-PyObject * _Py_VaBuildValue_SizeT(const char *, va_list);
-int _PyArg_NoKeywords(const char *funcname, PyObject *kw);
+PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...);
+PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list);
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list);
+PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw);
 
-int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, 
Py_ssize_t max, ...);
+PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t 
min, Py_ssize_t max, ...);
 
 /*
  * This is from pyport.h.  Perhaps it belongs elsewhere.
  */
 #ifdef __cplusplus
-#define PyMODINIT_FUNC extern "C" void
+#define PyMODINIT_FUNC extern "C" PyAPI_FUNC(void)
 #else
-#define PyMODINIT_FUNC void
+#define PyMODINIT_FUNC PyAPI_FUNC(void)
 #endif
 
 PyAPI_DATA(char *) _Py_PackageContext;
diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h 
b/pypy/module/cpyext/include/numpy/arrayobject.h
--- a/pypy/module/cpyext/include/numpy/arrayobject.h
+++ b/pypy/module/cpyext/include/numpy/arrayobject.h
@@ -204,9 +204,9 @@
 #define PyArray_EMPTY(nd, dims, type_num, fortran) \
         PyArray_SimpleNew(nd, dims, type_num)
 
-void _PyArray_FILLWBYTE(PyObject* obj, int val);
-PyObject* _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran);
-int _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src);
+PyAPI_FUNC(void) _PyArray_FILLWBYTE(PyObject* obj, int val);
+PyAPI_FUNC(PyObject *) _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, 
int fortran);
+PyAPI_FUNC(int) _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src);
 
 #define PyArray_FILLWBYTE _PyArray_FILLWBYTE
 #define PyArray_ZEROS _PyArray_ZEROS
diff --git a/pypy/module/cpyext/include/object.h 
b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -563,13 +563,13 @@
 #define Py_TRASHCAN_SAFE_END(pyObj)
 
 /* Copied from CPython ----------------------------- */
-int PyObject_AsReadBuffer(PyObject *, const void **, Py_ssize_t *);
-int PyObject_AsWriteBuffer(PyObject *, void **, Py_ssize_t *);
-int PyObject_CheckReadBuffer(PyObject *);
+PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *, const void **, Py_ssize_t *);
+PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *, void **, Py_ssize_t *);
+PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *);
 
 
 /* PyPy internal ----------------------------------- */
-int PyPyType_Register(PyTypeObject *);
+PyAPI_FUNC(int) PyPyType_Register(PyTypeObject *);
 #define PyObject_Length PyObject_Size
 #define _PyObject_GC_Del PyObject_GC_Del
 
diff --git a/pypy/module/cpyext/include/pycapsule.h 
b/pypy/module/cpyext/include/pycapsule.h
--- a/pypy/module/cpyext/include/pycapsule.h
+++ b/pypy/module/cpyext/include/pycapsule.h
@@ -50,7 +50,7 @@
 
 PyAPI_FUNC(void *) PyCapsule_Import(const char *name, int no_block);
 
-PyTypeObject *_Py_get_capsule_type(void);
+PyAPI_FUNC(PyTypeObject *) _Py_get_capsule_type(void);
 
 #ifdef __cplusplus
 }
diff --git a/pypy/module/cpyext/include/pycobject.h 
b/pypy/module/cpyext/include/pycobject.h
--- a/pypy/module/cpyext/include/pycobject.h
+++ b/pypy/module/cpyext/include/pycobject.h
@@ -48,8 +48,8 @@
 } PyCObject;
 #endif
 
-PyTypeObject *_Py_get_cobject_type(void);
- 
+PyAPI_FUNC(PyTypeObject *) _Py_get_cobject_type(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/pypy/module/cpyext/include/pyerrors.h 
b/pypy/module/cpyext/include/pyerrors.h
--- a/pypy/module/cpyext/include/pyerrors.h
+++ b/pypy/module/cpyext/include/pyerrors.h
@@ -11,9 +11,9 @@
     (PyClass_Check((x)) || (PyType_Check((x)) &&                        \
       PyObject_IsSubclass((x), PyExc_BaseException)))
 
-PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict);
-PyObject *PyErr_NewExceptionWithDoc(const char *name, const char *doc, 
PyObject *base, PyObject *dict);
-PyObject *PyErr_Format(PyObject *exception, const char *format, ...);
+PyAPI_FUNC(PyObject *) PyErr_NewException(const char *name, PyObject *base, 
PyObject *dict);
+PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc(const char *name, const char 
*doc, PyObject *base, PyObject *dict);
+PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *exception, const char *format, 
...);
 
 /* These APIs aren't really part of the error implementation, but
    often needed to format error messages; the native C lib APIs are
diff --git a/pypy/module/cpyext/include/pysignals.h 
b/pypy/module/cpyext/include/pysignals.h
--- a/pypy/module/cpyext/include/pysignals.h
+++ b/pypy/module/cpyext/include/pysignals.h
@@ -9,8 +9,8 @@
 
 typedef void (*PyOS_sighandler_t)(int);
 
-PyOS_sighandler_t PyOS_setsig(int sig, PyOS_sighandler_t handler);
-PyOS_sighandler_t PyOS_getsig(int sig);
+PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int sig, PyOS_sighandler_t handler);
+PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int sig);
 
 
 #ifdef __cplusplus
diff --git a/pypy/module/cpyext/include/pythonrun.h 
b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -6,7 +6,7 @@
 extern "C" {
 #endif
 
-void Py_FatalError(const char *msg);
+PyAPI_FUNC(void) Py_FatalError(const char *msg);
 
 /* taken from Python-2.7.3/Include/pydebug.h */
 PyAPI_DATA(int) Py_DebugFlag;
diff --git a/pypy/module/cpyext/include/stringobject.h 
b/pypy/module/cpyext/include/stringobject.h
--- a/pypy/module/cpyext/include/stringobject.h
+++ b/pypy/module/cpyext/include/stringobject.h
@@ -16,8 +16,8 @@
     Py_ssize_t size;
 } PyStringObject;
 
-PyObject *PyString_FromFormatV(const char *format, va_list vargs);
-PyObject *PyString_FromFormat(const char *format, ...);
+PyAPI_FUNC(PyObject *) PyString_FromFormatV(const char *format, va_list vargs);
+PyAPI_FUNC(PyObject *) PyString_FromFormat(const char *format, ...);
 
 #ifdef __cplusplus
 }
diff --git a/pypy/module/cpyext/include/structseq.h 
b/pypy/module/cpyext/include/structseq.h
--- a/pypy/module/cpyext/include/structseq.h
+++ b/pypy/module/cpyext/include/structseq.h
@@ -19,7 +19,7 @@
        int n_in_sequence;
 } PyStructSequence_Desc;
 
-extern char* PyStructSequence_UnnamedField;
+PyAPI_DATA(char *) PyStructSequence_UnnamedField;
 
 PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type,
                                           PyStructSequence_Desc *desc);
diff --git a/pypy/module/cpyext/include/tupleobject.h 
b/pypy/module/cpyext/include/tupleobject.h
--- a/pypy/module/cpyext/include/tupleobject.h
+++ b/pypy/module/cpyext/include/tupleobject.h
@@ -8,7 +8,7 @@
 #endif
 
 /* defined in varargswrapper.c */
-PyObject * PyTuple_Pack(Py_ssize_t, ...);
+PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...);
 
 #define PyTuple_SET_ITEM PyTuple_SetItem
 #define PyTuple_GET_ITEM PyTuple_GetItem
diff --git a/pypy/module/cpyext/test/banana.c b/pypy/module/cpyext/test/banana.c
--- a/pypy/module/cpyext/test/banana.c
+++ b/pypy/module/cpyext/test/banana.c
@@ -4,7 +4,8 @@
     {NULL, NULL}
 };
 
-void initbanana(void)
+PyMODINIT_FUNC
+initbanana(void)
 {
     Py_InitModule("banana", banana_functions);
 }
diff --git a/pypy/module/cpyext/test/callback_in_thread.c 
b/pypy/module/cpyext/test/callback_in_thread.c
--- a/pypy/module/cpyext/test/callback_in_thread.c
+++ b/pypy/module/cpyext/test/callback_in_thread.c
@@ -65,7 +65,8 @@
 };
 
 
-void initcallback_in_thread(void)
+PyMODINIT_FUNC
+initcallback_in_thread(void)
 {
     PyObject *m;
     m = Py_InitModule("callback_in_thread", module_functions);
diff --git a/pypy/module/cpyext/test/comparisons.c 
b/pypy/module/cpyext/test/comparisons.c
--- a/pypy/module/cpyext/test/comparisons.c
+++ b/pypy/module/cpyext/test/comparisons.c
@@ -86,7 +86,8 @@
 };
 
 
-void initcomparisons(void)
+PyMODINIT_FUNC
+initcomparisons(void)
 {
     PyObject *m, *d;
 
diff --git a/pypy/module/cpyext/test/date.c b/pypy/module/cpyext/test/date.c
--- a/pypy/module/cpyext/test/date.c
+++ b/pypy/module/cpyext/test/date.c
@@ -4,7 +4,8 @@
     {NULL, NULL}
 };
 
-void initdate(void)
+PyMODINIT_FUNC
+initdate(void)
 {
     PyObject *module;
     Py_InitModule("date", date_functions);
diff --git a/pypy/module/cpyext/test/dotted.c b/pypy/module/cpyext/test/dotted.c
--- a/pypy/module/cpyext/test/dotted.c
+++ b/pypy/module/cpyext/test/dotted.c
@@ -4,7 +4,8 @@
     {NULL, NULL}
 };
 
-void initdotted(void)
+PyMODINIT_FUNC
+initdotted(void)
 {
     Py_InitModule("pypy.module.cpyext.test.dotted", dotted_functions);
 }
diff --git a/pypy/module/cpyext/test/foo.c b/pypy/module/cpyext/test/foo.c
--- a/pypy/module/cpyext/test/foo.c
+++ b/pypy/module/cpyext/test/foo.c
@@ -634,7 +634,8 @@
 
 /* Initialize this module. */
 
-void initfoo(void)
+PyMODINIT_FUNC
+initfoo(void)
 {
     PyObject *m, *d;
 
diff --git a/pypy/module/cpyext/test/test_cpyext.py 
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -77,7 +77,6 @@
 
     modname = modname.split('.')[-1]
     eci = ExternalCompilationInfo(
-        export_symbols=['init%s' % (modname,)],
         include_dirs=api.include_dirs,
         **kwds
         )
@@ -263,7 +262,8 @@
                 #include <Python.h>
                 %(body)s
 
-                void init%(name)s(void) {
+                PyMODINIT_FUNC
+                init%(name)s(void) {
                 %(init)s
                 }
                 """ % dict(name=name, init=init, body=body,
diff --git a/pypy/module/cpyext/test/test_import_module.c 
b/pypy/module/cpyext/test/test_import_module.c
--- a/pypy/module/cpyext/test/test_import_module.c
+++ b/pypy/module/cpyext/test/test_import_module.c
@@ -1,7 +1,8 @@
 #include "Python.h"
 /* Initialize this module. */
 
-void inittest_import_module(void)
+PyMODINIT_FUNC
+inittest_import_module(void)
 {
        PyObject *m, *d;
 
diff --git a/pypy/module/cpyext/test/test_intobject.py 
b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -79,7 +79,7 @@
             ("newEnum", "METH_VARARGS",
              """
                 EnumObject *enumObj;
-                long intval;
+                int intval;
                 PyObject *name;
 
                 if (!PyArg_ParseTuple(args, "Oi", &name, &intval))
diff --git a/pypy/module/operator/tscmp.c b/pypy/module/operator/tscmp.c
--- a/pypy/module/operator/tscmp.c
+++ b/pypy/module/operator/tscmp.c
@@ -1,11 +1,12 @@
 /* Derived from CPython 3.3.5's operator.c::_tscmp
  */
 
+#include "src/precommondefs.h"
 #include <stdlib.h>
 #include <wchar.h>
 #include "tscmp.h"
 
-int
+RPY_EXPORTED_FOR_TESTS int
 pypy_tscmp(const char *a, const char *b, long len_a, long len_b)
 {
     /* The volatile type declarations make sure that the compiler has no
@@ -42,7 +43,7 @@
     return (result == 0);
 }
 
-int
+RPY_EXPORTED_FOR_TESTS int
 pypy_tscmp_wide(const wchar_t *a, const wchar_t *b, long len_a, long len_b)
 {
     /* The volatile type declarations make sure that the compiler has no
diff --git a/pypy/module/operator/tscmp.py b/pypy/module/operator/tscmp.py
--- a/pypy/module/operator/tscmp.py
+++ b/pypy/module/operator/tscmp.py
@@ -5,6 +5,7 @@
 import py
 
 from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.translator import cdir
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
 from pypy.interpreter.error import oefmt
@@ -12,9 +13,8 @@
 cwd = py.path.local(__file__).dirpath()
 eci = ExternalCompilationInfo(
     includes=[cwd.join('tscmp.h')],
-    include_dirs=[str(cwd)],
-    separate_module_files=[cwd.join('tscmp.c')],
-    export_symbols=['pypy_tscmp', 'pypy_tscmp_wide'])
+    include_dirs=[str(cwd), cdir],
+    separate_module_files=[cwd.join('tscmp.c')])
 
 
 def llexternal(*args, **kwargs):
diff --git a/pypy/module/rctime/interp_time.py 
b/pypy/module/rctime/interp_time.py
--- a/pypy/module/rctime/interp_time.py
+++ b/pypy/module/rctime/interp_time.py
@@ -34,7 +34,9 @@
 
     eci = ExternalCompilationInfo(
         includes = ['windows.h'],
-        post_include_bits = ["BOOL pypy_timemodule_setCtrlHandler(HANDLE 
event);"],
+        post_include_bits = [
+            "RPY_EXPORTED_FOR_TESTS\n"
+            "BOOL pypy_timemodule_setCtrlHandler(HANDLE event);"],
         separate_module_sources=['''
             static HANDLE interrupt_event;
 
@@ -56,7 +58,6 @@
             }
 
         '''],
-        export_symbols=['pypy_timemodule_setCtrlHandler'],
         )
     _setCtrlHandlerRoutine = rffi.llexternal(
         'pypy_timemodule_setCtrlHandler',
@@ -177,19 +178,22 @@
 if _WIN:
     win_eci = ExternalCompilationInfo(
         includes = ["time.h"],
-        post_include_bits = ["long pypy_get_timezone();",
-                             "int pypy_get_daylight();",
-                             "char** pypy_get_tzname();"],
+        post_include_bits = ["RPY_EXPORTED_FOR_TESTS\n"
+                             "long pypy_get_timezone();\n"
+                             "RPY_EXPORTED_FOR_TESTS\n"
+                             "int pypy_get_daylight();\n"
+                             "RPY_EXPORTED_FOR_TESTS\n"
+                             "char** pypy_get_tzname();\n"
+                             "RPY_EXPORTED_FOR_TESTS\n"
+                             "void* pypy__tzset();"],
         separate_module_sources = ["""
         long pypy_get_timezone() { return timezone; }
         int pypy_get_daylight() { return daylight; }
         char** pypy_get_tzname() { return tzname; }
-        """],
-        export_symbols = [
-        '_tzset', 'pypy_get_timezone', 'pypy_get_daylight', 'pypy_get_tzname'],
-        )
+        void pypy__tzset() { return _tzset(); }
+        """])
     # Ensure sure that we use _tzset() and timezone from the same C Runtime.
-    c_tzset = external('_tzset', [], lltype.Void, win_eci)
+    c_tzset = external('pypy__tzset', [], lltype.Void, win_eci)
     c_get_timezone = external('pypy_get_timezone', [], rffi.LONG, win_eci)
     c_get_daylight = external('pypy_get_daylight', [], rffi.INT, win_eci)
     c_get_tzname = external('pypy_get_tzname', [], rffi.CCHARPP, win_eci)
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2763,7 +2763,6 @@
         NB_TESTS = 100
         c_source = []
         all_tests = []
-        export_symbols = []
 
         def prepare_c_source():
             """Pick a random choice of argument types and length,
@@ -2796,12 +2795,10 @@
                                            var_name)
                 c_source.append('static %s;' % var_decl)
                 getter_name = '%s_get%d' % (fn_name, i)
-                export_symbols.append(getter_name)
-                c_source.append('void %s(%s) { *p = %s; }' % (
+                c_source.append('RPY_EXPORTED void %s(%s) { *p = %s; }' % (
                     getter_name,
                     primitive.cdecl(primitive.PrimitiveType[ARG], '*p'),
                     var_name))
-            export_symbols.append(fn_name)
             c_source.append('')
             c_source.append('static void real%s(%s)' % (
                 fn_name, ', '.join(fn_args)))
@@ -2809,7 +2806,7 @@
             for i in range(len(ARGTYPES)):
                 c_source.append('    argcopy_%s_x%d = x%d;' % (fn_name, i, i))
             c_source.append('}')
-            c_source.append('void *%s(void)' % fn_name)
+            c_source.append('RPY_EXPORTED void *%s(void)' % fn_name)
             c_source.append('{')
             c_source.append('    return (void *)&real%s;' % fn_name)
             c_source.append('}')
@@ -2819,8 +2816,7 @@
             prepare_c_source()
 
         eci = ExternalCompilationInfo(
-            separate_module_sources=['\n'.join(c_source)],
-            export_symbols=export_symbols)
+            separate_module_sources=['\n'.join(c_source)])
 
         for k in range(NB_TESTS):
             ARGTYPES, ffitypes, fn_name = all_tests[k]
@@ -3605,12 +3601,11 @@
             # value in eax or rax.
             eci = ExternalCompilationInfo(
                 separate_module_sources=["""
-                long fn_test_result_of_call(long x)
+                RPY_EXPORTED long fn_test_result_of_call(long x)
                 {
                     return x + 1;
                 }
-                """],
-                export_symbols=['fn_test_result_of_call'])
+                """])
             f = rffi.llexternal('fn_test_result_of_call', [lltype.Signed],
                                 RESTYPE, compilation_info=eci, _nowrapper=True)
             value = intmask(0xFFEEDDCCBBAA9988)
@@ -3639,12 +3634,11 @@
             # value in eax or rax.
             eci = ExternalCompilationInfo(
                 separate_module_sources=["""
-                long fn_test_result_of_call(long x)
+                RPY_EXPORTED long fn_test_result_of_call(long x)
                 {
                     return x + 1;
                 }
-                """],
-                export_symbols=['fn_test_result_of_call'])
+                """])
             f = rffi.llexternal('fn_test_result_of_call', [lltype.Signed],
                                 RESTYPE, compilation_info=eci, _nowrapper=True)
             value = intmask(0xFFEEDDCCBBAA9988)
@@ -3673,12 +3667,11 @@
         from rpython.rlib.rarithmetic import r_longlong
         eci = ExternalCompilationInfo(
             separate_module_sources=["""
-            long long fn_test_result_of_call(long long x)
+            RPY_EXPORTED long long fn_test_result_of_call(long long x)
             {
                 return x - 100000000000000;
             }
-            """],
-            export_symbols=['fn_test_result_of_call'])
+            """])
         f = rffi.llexternal('fn_test_result_of_call', [lltype.SignedLongLong],
                             lltype.SignedLongLong,
                             compilation_info=eci, _nowrapper=True)
@@ -3701,12 +3694,11 @@
         from rpython.rlib.rarithmetic import r_longlong
         eci = ExternalCompilationInfo(
             separate_module_sources=["""
-            long long fn_test_result_of_call(long long x)
+            RPY_EXPORTED long long fn_test_result_of_call(long long x)
             {
                 return x - 100000000000000;
             }
-            """],
-            export_symbols=['fn_test_result_of_call'])
+            """])
         f = rffi.llexternal('fn_test_result_of_call', [lltype.SignedLongLong],
                             lltype.SignedLongLong,
                             compilation_info=eci, _nowrapper=True)
@@ -3730,12 +3722,11 @@
         from rpython.rlib.rarithmetic import r_singlefloat
         eci = ExternalCompilationInfo(
             separate_module_sources=["""
-            float fn_test_result_of_call(float x)
+            RPY_EXPORTED float fn_test_result_of_call(float x)
             {
                 return x / 2.0f;
             }
-            """],
-            export_symbols=['fn_test_result_of_call'])
+            """])
         f = rffi.llexternal('fn_test_result_of_call', [lltype.SingleFloat],
                             lltype.SingleFloat,
                             compilation_info=eci, _nowrapper=True)
@@ -3760,12 +3751,11 @@
         from rpython.rlib.rarithmetic import r_singlefloat
         eci = ExternalCompilationInfo(
             separate_module_sources=["""
-            float fn_test_result_of_call(float x)
+            RPY_EXPORTED float fn_test_result_of_call(float x)
             {
                 return x / 2.0f;
             }
-            """],
-            export_symbols=['fn_test_result_of_call'])
+            """])
         f = rffi.llexternal('fn_test_result_of_call', [lltype.SingleFloat],
                             lltype.SingleFloat,
                             compilation_info=eci, _nowrapper=True)
diff --git a/rpython/rlib/_rffi_stacklet.py b/rpython/rlib/_rffi_stacklet.py
--- a/rpython/rlib/_rffi_stacklet.py
+++ b/rpython/rlib/_rffi_stacklet.py
@@ -19,14 +19,6 @@
     else:
         asmsrc = 'switch_x86_msvc.asm'
     eci.separate_module_files += (cdir / 'src' / 'stacklet' / asmsrc, )
-    eci.export_symbols += (
-        'stacklet_newthread',
-        'stacklet_deletethread',
-        'stacklet_new',
-        'stacklet_switch',
-        'stacklet_destroy',
-        '_stacklet_translate_pointer',
-        )
 
 rffi_platform.verify_eci(eci.convert_sources_to_files())
 
diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py
--- a/rpython/rlib/clibffi.py
+++ b/rpython/rlib/clibffi.py
@@ -44,10 +44,12 @@
 
 if _WIN32:
     separate_module_sources = ['''
+    #include "src/precommondefs.h"
     #include <stdio.h>
     #include <windows.h>
 
     /* Get the module where the "fopen" function resides in */
+    RPY_EXPORTED_FOR_TESTS
     HANDLE pypy_get_libc_handle() {
         MEMORY_BASIC_INFORMATION  mi;
         char buf[1000];
@@ -93,7 +95,6 @@
     eci = ExternalCompilationInfo(
         libraries = libraries,
         includes = includes,
-        export_symbols = [],
         separate_module_sources = separate_module_sources,
         )
 
@@ -113,15 +114,13 @@
     eci = ExternalCompilationInfo(
         includes = ['ffi.h', 'windows.h'],
         libraries = ['kernel32'],
-        include_dirs = [libffidir],
+        include_dirs = [libffidir, cdir],
         separate_module_sources = separate_module_sources,
         separate_module_files = [libffidir.join('ffi.c'),
                                  libffidir.join('prep_cif.c'),
                                  libffidir.join(asm_ifc),
                                  libffidir.join('pypy_ffi.c'),
                                  ],
-        export_symbols = ['ffi_call', 'ffi_prep_cif', 'ffi_prep_closure',
-                          'pypy_get_libc_handle'],
         )
 
 FFI_TYPE_P = lltype.Ptr(lltype.ForwardReference())
diff --git a/rpython/rlib/entrypoint.py b/rpython/rlib/entrypoint.py
--- a/rpython/rlib/entrypoint.py
+++ b/rpython/rlib/entrypoint.py
@@ -6,6 +6,11 @@
 from rpython.rlib.objectmodel import we_are_translated
 
 
+def export_symbol(func):
+    func.exported_symbol = True
+    return func
+
+
 def entrypoint_lowlevel(key, argtypes, c_name=None, relax=False):
     """ Note: entrypoint should call llop.gc_stack_bottom on it's own.
     That's necessary for making it work with asmgcc and hence JIT
@@ -14,16 +19,13 @@
 
     if key == 'main' than it's included by default
     """
-    from rpython.translator.tool.cbuild import ExternalCompilationInfo
-
     def deco(func):
         secondary_entrypoints.setdefault(key, []).append((func, argtypes))
         if c_name is not None:
             func.c_name = c_name
         if relax:
             func.relax_sig_check = True
-        func._compilation_info = ExternalCompilationInfo(
-            export_symbols=[c_name or func.func_name])
+        export_symbol(func)
         return func
     return deco
 
@@ -33,8 +35,6 @@
 def entrypoint(key, argtypes, c_name=None):
     """if key == 'main' than it's included by default
     """
-    from rpython.translator.tool.cbuild import ExternalCompilationInfo
-
     def deco(func):
         source = py.code.Source("""
         def wrapper(%(args)s):
@@ -67,8 +67,7 @@
         wrapper.func_name = func.func_name
         if c_name is not None:
             wrapper.c_name = c_name
-        wrapper._compilation_info = ExternalCompilationInfo(
-            export_symbols=[c_name or func.func_name])
+        export_symbol(wrapper)
         return wrapper
     return deco
 
diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py
--- a/rpython/rlib/rdtoa.py
+++ b/rpython/rlib/rdtoa.py
@@ -32,10 +32,6 @@
     includes = ['src/dtoa.h'],
     libraries = [],
     separate_module_sources = [source_file],
-    export_symbols = ['_PyPy_dg_strtod',
-                      '_PyPy_dg_dtoa',
-                      '_PyPy_dg_freedtoa',
-                      ],
     )
 
 # dtoa.c is limited to 'int', so we refuse to pass it
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -91,6 +91,18 @@
             return ""
         return rffi.charp2str(res)
 
+    def _dlerror_on_dlopen_untranslated(name):
+        "NOT_RPYTHON: aaargh"
+        import ctypes
+        name = rffi.charp2str(name)
+        try:
+            ctypes.CDLL(name)
+        except OSError, e:
+            return str(e)
+        else:
+            return ("opening %r with ctypes.CDLL() works, "
+                    "but not with c_dlopen()??" % (name,))
+
     def dlopen(name, mode=-1):
         """ Wrapper around C-level dlopen
         """
@@ -103,7 +115,10 @@
             mode |= RTLD_NOW
         res = c_dlopen(name, rffi.cast(rffi.INT, mode))
         if not res:
-            err = dlerror()
+            if not we_are_translated():
+                err = _dlerror_on_dlopen_untranslated(name)
+            else:
+                err = dlerror()
             raise DLOpenError(err)
         return res
 
diff --git a/rpython/rlib/rgil.py b/rpython/rlib/rgil.py
--- a/rpython/rlib/rgil.py
+++ b/rpython/rlib/rgil.py
@@ -10,9 +10,7 @@
 eci = ExternalCompilationInfo(
     includes = ['src/thread.h'],
     separate_module_files = [translator_c_dir / 'src' / 'thread.c'],
-    include_dirs = [translator_c_dir],
-    export_symbols = ['RPyGilAllocate', 'RPyGilYieldThread', 'RPyGilRelease',
-                      'RPyGilAcquire', 'RPyFetchFastGil'])
+    include_dirs = [translator_c_dir])
 
 llexternal = rffi.llexternal
 
diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py
--- a/rpython/rlib/ropenssl.py
+++ b/rpython/rlib/ropenssl.py
@@ -34,7 +34,6 @@
 eci = ExternalCompilationInfo(
     libraries = libraries,
     includes = includes,
-    export_symbols = [],
     post_include_bits = [
         # Unnamed structures are not supported by rffi_platform.
         # So we replace an attribute access with a macro call.
@@ -171,8 +170,6 @@
 
 def external(name, argtypes, restype, **kw):
     kw['compilation_info'] = eci
-    if not kw.get('macro', False):
-        eci.export_symbols += (name,)
     return rffi.llexternal(
         name, argtypes, restype, **kw)
 
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -44,7 +44,7 @@
 
         /* This function emulates what the windows CRT
             does to validate file handles */
-        int
+        RPY_EXPORTED_FOR_TESTS int
         _PyVerify_fd(int fd)
         {
             const int i1 = fd >> IOINFO_L2E;
@@ -81,15 +81,12 @@
             return 0;
         }
     ''',]
-    export_symbols = ['_PyVerify_fd']
 else:
     separate_module_sources = []
-    export_symbols = []
     includes=['errno.h','stdio.h']
 errno_eci = ExternalCompilationInfo(
     includes=includes,
     separate_module_sources=separate_module_sources,
-    export_symbols=export_symbols,
 )
 
 _get_errno, _set_errno = CExternVariable(INT, 'errno', errno_eci,
diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py
--- a/rpython/rlib/rsignal.py
+++ b/rpython/rlib/rsignal.py
@@ -41,11 +41,6 @@
     includes = includes,
     separate_module_files = [cdir / 'src' / 'signals.c'],
     include_dirs = [str(cdir)],
-    export_symbols = ['pypysig_poll', 'pypysig_default',
-                      'pypysig_ignore', 'pypysig_setflag',
-                      'pypysig_reinstall',
-                      'pypysig_set_wakeup_fd',
-                      'pypysig_getaddr_occurred'],
 )
 
 class CConfig:
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -18,12 +18,6 @@
     includes = ['src/thread.h'],
     separate_module_files = [translator_c_dir / 'src' / 'thread.c'],
     include_dirs = [translator_c_dir],
-    export_symbols = ['RPyThreadGetIdent', 'RPyThreadLockInit',
-                      'RPyThreadAcquireLock', 'RPyThreadAcquireLockTimed',
-                      'RPyThreadReleaseLock',
-                      'RPyThreadGetStackSize', 'RPyThreadSetStackSize',
-                      'RPyOpaqueDealloc_ThreadLock',
-                      'RPyThreadAfterFork']
 )
 
 def llexternal(name, args, result, **kwds):
diff --git a/rpython/rlib/test/test_clibffi.py 
b/rpython/rlib/test/test_clibffi.py
--- a/rpython/rlib/test/test_clibffi.py
+++ b/rpython/rlib/test/test_clibffi.py
@@ -3,6 +3,7 @@
 """
 
 from rpython.translator.c.test.test_genc import compile
+from rpython.translator import cdir
 from rpython.rlib.clibffi import *
 from rpython.rlib.objectmodel import keepalive_until_here
 from rpython.rtyper.lltypesystem.ll2ctypes import ALLOCATED
@@ -268,6 +269,7 @@
 
         c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
         c_file.write(py.code.Source('''
+        #include "src/precommondefs.h"
         #include <stdlib.h>
         #include <stdio.h>
 
@@ -276,6 +278,7 @@
             long y;
         };
 
+        RPY_EXPORTED
         long sum_x_y(struct x_y s) {
             return s.x + s.y;
         }
@@ -285,7 +288,7 @@
         }
         
         '''))
-        eci = ExternalCompilationInfo(export_symbols=['sum_x_y'])
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))
 
         lib = CDLL(lib_name)
@@ -319,6 +322,7 @@
 
         c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
         c_file.write(py.code.Source('''
+        #include "src/precommondefs.h"
         #include <stdlib.h>
         #include <stdio.h>
 
@@ -327,6 +331,7 @@
             short y;
         };
 
+        RPY_EXPORTED
         struct s2h give(short x, short y) {
             struct s2h out;
             out.x = x;
@@ -334,6 +339,7 @@
             return out;
         }
 
+        RPY_EXPORTED
         struct s2h perturb(struct s2h inp) {
             inp.x *= 2;
             inp.y *= 3;
@@ -341,7 +347,7 @@
         }
         
         '''))
-        eci = ExternalCompilationInfo(export_symbols=['give', 'perturb'])
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))
 
         lib = CDLL(lib_name)
@@ -395,11 +401,13 @@
 
         c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
         c_file.write(py.code.Source('''
+        #include "src/precommondefs.h"
+        RPY_EXPORTED
         long fun(long i) {
             return i + 42;
         }
         '''))
-        eci = ExternalCompilationInfo(export_symbols=['fun'])
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))
 
         lib = CDLL(lib_name)
diff --git a/rpython/rlib/test/test_libffi.py b/rpython/rlib/test/test_libffi.py
--- a/rpython/rlib/test/test_libffi.py
+++ b/rpython/rlib/test/test_libffi.py
@@ -7,6 +7,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rtyper.lltypesystem.ll2ctypes import ALLOCATED
 from rpython.rtyper.llinterp import LLException
+from rpython.translator import cdir
 from rpython.rlib.libffi import (CDLL, ArgChain, types,
                               IS_32_BIT, array_getitem, array_setitem)
 from rpython.rlib.libffi import (struct_getfield_int, struct_setfield_int,
@@ -204,7 +205,6 @@
     def setup_class(cls):
         from rpython.tool.udir import udir
         from rpython.translator.tool.cbuild import ExternalCompilationInfo
-        from rpython.translator.tool.cbuild import STANDARD_DEFINES
         from rpython.translator.platform import platform
 
         BaseFfiTest.setup_class()
@@ -213,7 +213,6 @@
         c_file = udir.ensure("test_libffi", dir=1).join("foolib.c")
         # automatically collect the C source from the docstrings of the tests
         snippets = []
-        exports = []
         for name in dir(cls):
             if name.startswith('test_'):
                 meth = getattr(cls, name)
@@ -221,12 +220,10 @@
                 # improved: so far we just check that there is a '{' :-)
                 if meth.__doc__ is not None and '{' in meth.__doc__:
                     snippets.append(meth.__doc__)
-                    import re
-                    for match in re.finditer(" ([A-Za-z_]+)\(", meth.__doc__):
-                        exports.append(match.group(1))
         #
-        c_file.write(STANDARD_DEFINES + 
str(py.code.Source('\n'.join(snippets))))
-        eci = ExternalCompilationInfo(export_symbols=exports)
+        INCLUDE = '#include "src/precommondefs.h"\n'
+        c_file.write(INCLUDE + str(py.code.Source('\n'.join(snippets))))
+        eci = ExternalCompilationInfo(include_dirs=[cdir])
         cls.libfoo_name = str(platform.compile([c_file], eci, 'x',
                                                standalone=False))
         cls.dll = cls.CDLL(cls.libfoo_name)
@@ -269,6 +266,7 @@
 
     def test_very_simple(self):
         """
+            RPY_EXPORTED
             int diff_xy(int x, Signed y)
             {
                 return x - y;
@@ -281,6 +279,7 @@
 
     def test_simple(self):
         """
+            RPY_EXPORTED
             int sum_xy(int x, double y)
             {
                 return (x + (int)y);
@@ -299,6 +298,7 @@
 
     def test_cast_result(self):
         """
+            RPY_EXPORTED
             unsigned char cast_to_uchar_and_ovf(int x)
             {
                 return 200+(unsigned char)x;
@@ -311,6 +311,7 @@
 
     def test_cast_argument(self):
         """
+            RPY_EXPORTED
             int many_args(char a, int b)
             {
                 return a+b;
@@ -323,6 +324,7 @@
 
     def test_char_args(self):
         """
+        RPY_EXPORTED
         char sum_args(char a, char b) {
             return a + b;
         }
@@ -334,6 +336,7 @@
 
     def test_unsigned_short_args(self):
         """
+            RPY_EXPORTED
             unsigned short sum_xy_us(unsigned short x, unsigned short y)
             {
                 return x+y;
@@ -347,6 +350,7 @@
 
     def test_pointer_as_argument(self):
         """#include <stdlib.h>
+            RPY_EXPORTED
             Signed inc(Signed* x)
             {
                 Signed oldval;
@@ -391,6 +395,7 @@
 
             struct pair my_static_pair = {10, 20};
 
+            RPY_EXPORTED
             Signed* get_pointer_to_b()
             {
                 return &my_static_pair.b;
@@ -404,7 +409,9 @@
     def test_void_result(self):
         """
             int dummy;
+            RPY_EXPORTED
             void set_dummy(int val) { dummy = val; }
+            RPY_EXPORTED
             int get_dummy() { return dummy; }
         """
         libfoo = self.get_libfoo()
@@ -421,6 +428,7 @@
 
     def test_single_float_args(self):
         """
+            RPY_EXPORTED
             float sum_xy_float(float x, float y)
             {
                 return x+y;
@@ -437,6 +445,7 @@
 
     def test_slonglong_args(self):
         """
+            RPY_EXPORTED
             long long sum_xy_longlong(long long x, long long y)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to