<div dir="ltr"><div>Hi,</div><div><br></div><div>I made an experimental MSVC port. Of cause, dllimport/dllexport and the driver for linking and many other part is not implemented. But dynamic linking was possible with some trick.</div><div><br></div><div>I think it is useful for designing, my observation about the experimental building of libswiftCore.dll, libswiftSwiftOnoneSupport.dll and linking of Hello.exe - its source has only &#39;print(&quot;Hello&quot;)&#39;.</div><div><br></div><div>1) SWIFT_RUNTIME_EXPORT was not enough for dllexport.</div><div>  Hello.obj needed defined in libswift*.dll</div><div>    _swift_getExistentialTypeMetadata,</div><div>    _TFs5printFTGSaP__9separatorSS10terminatorSS_T_,</div><div>    _TMSS,</div><div>    _TZvOs7Process5_argcVs5Int32,</div><div>    swift_bufferAllocate, .... </div><div>  Some of above are dllexported by the macro, but _T* are not. Maybe, it generated by swiftc.exe.</div><div>  I used the utility &#39;dlltool.exe&#39; from Cygwin/MinGW world. It extracts all symbols and generates &#39;allsymbol.def&#39;.</div><div>  With that .def, I could build the all-symbol-dllexported libswiftCore.dll.</div><div>  (I&#39;m hoping we can build it without this trick.)</div><div><br></div><div>2) Imediate mode just worked with libswift*.dll.</div><div>  Using the libswiftCore.dll, I could just run &#39;swift -O Hello.swift&#39; and it worked. I was happy.</div><div>  But I don&#39;t know how Immediate mode work. How could this work without any consideration about dllimport or import library?</div><div>  Anyway, after building libswiftSwiftOnoneSupport.dll, I could run &#39;swift Hello.swift&#39; without -O. </div><div><br></div><div>3) Building Hello.exe with some trick.</div><div>  I compiled the Hello.swift to Hello.ll, and simply replace the string &quot;external global/constant&quot; to &quot;external dllimport global/contant&quot; in the file, and pass it to &#39;clang&#39; for Hello.obj, and link with previously built import library of swiftCore.</div><div>  It worked well. It will be happy swiftc could generate the dllimport.</div><div><br></div><div>4) In building libswiftSwiftOnoneSupport.dll, there is SOME MORE.</div><div>  To build libswiftSwiftOnoneSupport.dll, it needed to link with libswiftCore.dll. I used the same method - &#39;injecting dllimport into *.ll&#39;.</div><div>  When linking swiftOnone, only _TWVBo was not resolved.</div><div>  To make it linkable, in the SwiftOnoneSupport.ll,</div><div>    @_TWVBo = external global i8*, align 8</div><div>  should be replaced to </div><div>    @__imp__TWVBo = external global i8*, align 8</div><div>  not</div><div>    @_TWVBo = external dllimport global i8*, align 8.</div><div><br></div><div>  I don&#39;t know well what _TWVBo is. I only guess this related to indirect access the variable _TWVBo.</div><div>  But I think we should know what the root cause to this.</div><div><br></div><div>- Han Sangjin</div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-05-04 10:34 GMT+09:00 Jordan Rose via swift-dev <span dir="ltr">&lt;<a href="mailto:swift-dev@swift.org" target="_blank">swift-dev@swift.org</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><br><div><blockquote type="cite"><div>On Apr 26, 2016, at 08:43, Saleem Abdulrasool &lt;<a href="mailto:compnerd@compnerd.org" target="_blank">compnerd@compnerd.org</a>&gt; wrote:</div><br><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">On Tue, Apr 12, 2016 at 9:32 AM, Saleem Abdulrasool<span> </span><span dir="ltr">&lt;<a href="mailto:compnerd@compnerd.org" target="_blank">compnerd@compnerd.org</a>&gt;</span><span> </span>wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>On Monday, April 11, 2016, Joe Groff &lt;<a href="mailto:jgroff@apple.com" target="_blank">jgroff@apple.com</a>&gt; wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>&gt; On Apr 11, 2016, at 3:19 PM, Saleem Abdulrasool via swift-dev &lt;<a>swift-dev@swift.org</a>&gt; wrote:<br>&gt;<br>&gt; On Thu, Apr 7, 2016 at 2:12 PM, Saleem Abdulrasool &lt;<a>compnerd@compnerd.org</a>&gt; wrote:<br>&gt; On Wed, Apr 6, 2016 at 10:21 AM, Saleem Abdulrasool &lt;<a>compnerd@compnerd.org</a>&gt; wrote:<br>&gt; Hi,<br>&gt;<br>&gt; I was playing around with the idea of swift and Windows since there are some interesting differences between COFF/PE and (ELF and MachO).<br>&gt;<br>&gt; PE/COFF does not directly address symbols in external modules (DSOs/dylibs/DLLs).  Instead, there is an indirect addressing model (thunks in Windows parlance).  Fortunately, LLVM has a nice way to model this: GlobalValues have an associated &quot;DLLStorageClass&quot; which indicates whether something is &quot;imported&quot; (provided by an external module), &quot;exported&quot; (provided to external modules), or &quot;default&quot; (everything else).<br>&gt;<br>&gt; Adjusting the IRGen to correctly annotate this part of the semantics should get us part of the way to supporting swift on PE/COFF.<br>&gt;<br>&gt; The thing to consider with this is that the DLL storage class is dependent on how the module(s) are being built.  For example, something may change from the exported storage to default if being built into a static library rather than a shared object and is not meant to be re-exported.<br>&gt;<br>&gt; Part of this information really needs to be threaded from the build system so that we know whether a given SIL module is external or internal.<br>&gt;<br>&gt; To the DLL Storage semantics support, Ive taken a quick first stab at it.  Ive pushed the changes to<span> </span><a href="https://github.com/compnerd/apple-swift/tree/dllstorage" target="_blank">https://github.com/compnerd/apple-swift/tree/dllstorage</a><span> </span>and created a Pull Request at<span> </span><a href="https://github.com/apple/swift/pull/2080" target="_blank">https://github.com/apple/swift/pull/2080</a><span> </span>.<br>&gt;<br>&gt; However, as I expected, this is going to cause problems for building some of the core libraries.  In particular, there are mismatches between what gets compiled and is desired.  The swiftStubs and swiftRuntime are statically compiled and then merged into swiftCore.  There is also the concern of the the support modules (e.g. Platform).  If there are stubs that are being used (e.g. via _silgen_name) then there are issues with calculating the correct DLL storage for the associated global values.<br>&gt;<br>&gt; Playing around with this, I was trying to special case the building of the standard library (as the runtime will be statically linked into it, the symbols that it is expecting to be externally available are actually private linkage.  Not hacking up the compiler like this causes issues since there are inverse dependencies (swiftCore gets dllimport interfaces from swiftRuntime, which has dependencies on swiftCore).  The crux of the problem is that we do not have a way to represent that in swift.<br>&gt;<br>&gt; The easiest answer that seems to come to mind is to actually introduce an attribute to indicate that an interface is part of a specific module and assume that everything else is locally defined.  This would also potentially allow us to handle things like @inline(always) @transparent interfaces which get imported to ensure that a static inline function is given local visibility rather than a DLL Import storage.<br>&gt;<br>&gt; Unfortunately, I believe that currently Im stuck as I do not have a good way to determine what type of dll storage class a symbol should be given (since currently, theres no way to determine if we will have a symbol available locally or not when actually linking).<br>&gt;<br>&gt; It seems to me, at least initially, that we need a way to treat SwiftModule as a container (a la llvm::Module) and indicate which of the TopLevelDecls are meant to be a single &quot;module&quot; (DSO, DLL, whatever you want to call it) so that we can properly track the DLL storage associated with them.  Am I confusing something there?<br>&gt;<br>&gt; Is there a preference on a means to handle this?<br><br>The runtime is linked as part of the standard library, and its ABI interface should be exported from libswiftCore.dylib/so/dll like the standard library&#39;s. We should already mark up the ABI entry points with the SWIFT_RUNTIME_EXPORT and SWIFT_RUNTIME_STDLIB_INTERFACE macros. Is it not sufficient to expand these macros to __dllexport?</blockquote><div><br></div></span><div>The definitions can be marked as __declspec(dllexport) but the compiler generated references need to be dllimport for the wrapped runtime functions (easy for the most part -- see my changes).  There&#39;s also the concern of stubs for the aliases (via silgen_name).  Those are defined externally with no indication that they are locally available and thus should have default rather than dllimport storage.  Similar things for standard library metadata (type, witness tables, etc).</div></blockquote><div><br></div><div>A gentle reminder on this topic.  I would like to get something sorted out so that we can try to get this resolved, preferably before the swift 3 release.</div></div></div></div></div></blockquote><br></div></span><div>Just to chime in here (as asked by Saleem, um, a month ago) I think this is the right way to go. We should handle the DLL-ish case (mark public things ‘dllexport’ and references outside the Swift module ‘dllimport’), and not worry about static linking (unnecessary dllimports).</div><div><br></div><div>(It seems __declspec(dllexport) is exactly the same as LLVM ‘public’ vs ‘hidden’—at least for Swift’s uses, even if that isn’t true generally.)</div><div><br></div><div>We can then come back later and design / add some kind of “I know this object file is going to be statically linked into the executable” mode, which will drop all the dllexports. We’d also want to encode this flag into the serialized “swiftmodule” files (a library’s public interface), so that we know not to use dllimport for anything we use from there.</div><div><br></div><div>Thanks for pushing on this!</div><div>Jordan</div></div><br>_______________________________________________<br>
swift-dev mailing list<br>
<a href="mailto:swift-dev@swift.org">swift-dev@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-dev" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-dev</a><br>
<br></blockquote></div><br></div>