Commits

Amaury Forgeot d'Arc committed 330fe35

Add support for shared modules with the mingw32 compiler.

I needed to pass the "target" file name to _exportsymbols_link_flags(),
hence the changes for other platforms.

Comments (0)

Files changed (4)

pypy/translator/platform/__init__.py

     def _preprocess_library_dirs(self, library_dirs):
         return library_dirs
 
-    def _link_args_from_eci(self, eci, standalone):
+    def _link_args_from_eci(self, eci, target, standalone):
         library_dirs = self.preprocess_library_dirs(eci.library_dirs)
         library_dirs = self._libdirs(library_dirs)
         libraries = self._libs(eci.libraries)
         link_files = self._linkfiles(eci.link_files)
-        export_flags = self._exportsymbols_link_flags(eci)
+        export_flags = self._exportsymbols_link_flags(eci, target)
         return (library_dirs + list(self.link_flags) + export_flags +
                 link_files + list(eci.link_extra) + libraries)
 
-    def _exportsymbols_link_flags(self, eci, relto=None):
+    def _exportsymbols_link_flags(self, eci, target, relto=None):
         if eci.export_symbols:
             raise ValueError("This platform does not support export symbols")
         return []
             cc_link = 'g++'      # XXX hard-coded so far
         else:
             cc_link = self.cc
-        largs = self._link_args_from_eci(eci, standalone)
+        largs = self._link_args_from_eci(eci, exe_name, standalone)
         return self._link(cc_link, ofiles, largs, standalone, exe_name)
 
     # below are some detailed informations for platforms

pypy/translator/platform/darwin.py

             args.append(f)
         return args
 
-    def _link_args_from_eci(self, eci, standalone):
-        args = super(Darwin, self)._link_args_from_eci(eci, standalone)
+    def _link_args_from_eci(self, eci, target, standalone):
+        args = super(Darwin, self)._link_args_from_eci(eci, target, standalone)
         frameworks = self._frameworks(eci.frameworks)
         include_dirs = self._includedirs(eci.include_dirs)
         return (args + frameworks + include_dirs)
 
-    def _exportsymbols_link_flags(self, eci, relto=None):
+    def _exportsymbols_link_flags(self, eci, target, relto=None):
         if not eci.export_symbols:
             return []
 

pypy/translator/platform/posix.py

                                  cwd=str(cfile.dirpath()))
         return oname
 
-    def _link_args_from_eci(self, eci, standalone):
-        return Platform._link_args_from_eci(self, eci, standalone)
+    def _link_args_from_eci(self, eci, target, standalone):
+        return Platform._link_args_from_eci(self, eci, target, standalone)
 
-    def _exportsymbols_link_flags(self, eci, relto=None):
+    def _exportsymbols_link_flags(self, eci, target, relto=None):
         if not eci.export_symbols:
             return []
 
         if shared:
             linkflags = self._args_for_shared(linkflags)
 
-        linkflags += self._exportsymbols_link_flags(eci, relto=path)
-
         if shared:
             libname = exe_name.new(ext='').basename
             target_name = 'lib' + exe_name.new(ext=self.so_ext).basename
         else:
             target_name = exe_name.basename
 
+        linkflags += self._exportsymbols_link_flags(eci, target_name, relto=path)
+
         if shared:
             cflags = self.cflags + self.shared_only
         else:

pypy/translator/platform/windows.py

         # see src/thread_nt.h
         return False
 
-    def _link_args_from_eci(self, eci, standalone):
+    def _link_args_from_eci(self, eci, target, standalone):
         # Windows needs to resolve all symbols even for DLLs
-        return super(MsvcPlatform, self)._link_args_from_eci(eci, standalone=True)
+        return super(MsvcPlatform, self)._link_args_from_eci(eci, target,
+                                                             standalone=True)
 
-    def _exportsymbols_link_flags(self, eci, relto=None):
+    def _exportsymbols_link_flags(self, eci, target, relto=None):
         if not eci.export_symbols:
             return []
 
         m.exe_name = exe_name
         m.eci = eci
 
-        linkflags = list(self.link_flags)
         if shared:
             linkflags = self._args_for_shared(linkflags) + [
                 '/EXPORT:$(PYPY_MAIN_FUNCTION)']
-        linkflags += self._exportsymbols_link_flags(eci, relto=path)
-
-        if shared:
             so_name = exe_name.new(purebasename='lib' + exe_name.purebasename,
                                    ext=self.so_ext)
             target_name = so_name.basename
         else:
+            linkflags = list(self.link_flags)
             target_name = exe_name.basename
 
+        linkflags += self._exportsymbols_link_flags(eci, target_name, relto=path)
+
         def pypyrel(fpath):
             rel = py.path.local(fpath).relto(pypypath)
             if rel:
         # Mingw tools write compilation errors to stdout
         super(MingwPlatform, self)._handle_error(
             returncode, '', stderr + stdout, outname)
+
+    def _exportsymbols_link_flags(self, eci, target, relto=None):
+        if not eci.export_symbols:
+            return []
+
+        def_file = self._make_response_file("dynamic-symbols-")
+        f = def_file.open("w")
+        f.write("EXPORTS\n")
+        for sym in eci.export_symbols:
+            f.write("%s\n" % (sym,))
+        f.close()
+
+        exp_file = def_file.new(ext='.exp')
+        self._execute_c_compiler('dlltool',
+                                 ['--dllname', str(target),
+                                  '--output-exp', str(exp_file),
+                                  '--def', str(def_file)],
+                                 exp_file)
+
+        if relto:
+            exp_file = relto.bestrelpath(exp_file)
+        return ["-Wl,%s" % (exp_file,)]
+