<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Hi,</p>
    <p>We all know that we are lacking an environment check in Swift. It
      shouldn't be a important feature if we were only targeting
      Apple(macOS, iOS...) and Linux or if we are targeting only one
      Windows ABI. But our community are working hard to port swift to
      Windows targeting various ABIs. There are currently three main
      variants of Windows ABIs: MSVC, Cygwin and MinGW. Of course, their
      ABI's varies too. So when porting Swift to windows with targeting
      these ABIs and when writing swift code on windows, we need an
      environment check .<br>
    </p>
    <p>By using the `environment check` term we are talking about the
      mechanism that will provide us the information about the ABI that
      the swift compiler is targeting.</p>
    <p>When porting stdlib and Foundation to windows, community members
      are using the method 'ad hoc -D flag'. But to me and to the
      community this method is not sufficient or a long term solution. 
      Saleem Abdulrasool and Han Sangjin have pointed out this in
      following threads:</p>
    <p>1.
<a class="moz-txt-link-freetext" href="https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20160704/002360.html">https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20160704/002360.html</a></p>
    <p>2.
<a class="moz-txt-link-freetext" href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016381.html">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016381.html</a></p>
    <p>But unfortunately the core team haven't succeeded to make or
      choose a solution. But as we are expecting a swift release, we
      should make a solution.</p>
    <p>As Saleem pointed out that there are ABI problems in Linux also:</p>
    <p>&gt; This is not a problem strictly limited to Windows.  It also
      appears in<br>
      &gt; other OSes.  As a concrete example, Linux has traditionally
      had the "gnu"<br>
      &gt; environment (libc).  However, there is also "uclibc" which is
      pretty<br>
      &gt; common, and these days, "musl" as different targets.<br>
    </p>
    <p>So we have multiple environment(ABI?) in Linux also.</p>
    <p>I have seen some core members want to know how other languages
      handles this issue like Chris Lattner wanted to know:</p>
    <p>&gt; I am not a windows guru (and haven’t used it for over a
      decade) but my understanding is that Cygwin is a different target
      (as in different target triple, different ABI, different
      environment) from MSVC and MinGW.  If that is the case, it should
      be its own “arch” or “os”.  MSVC and MinGW (again, AFAIK) use the
      same C ABI, and thus could be treated as the same target.<br>
      <br>
      &gt; I think it would be defensible to treat MSVC/MinGW as an
      os(Windows) but treat Cygwin as os(Cygwin).<br>
      &gt;<br>
      &gt; How do other languages handle this?  What does dlang do, for
      example?<br>
      &gt;<br>
      &gt; -Chris</p>
    <p>So I want to put some information how other languages handles
      this issue.<br>
    </p>
    <p>## D lang</p>
    <p><a class="moz-txt-link-freetext" href="https://dlang.org/spec/version.html#predefined-versions">https://dlang.org/spec/version.html#predefined-versions</a></p>
    <p>On D, anyone can handle this by using `version()` block.</p>
    <p>```</p>
    <p>version(<span class="d_inlinecode donthyphenate notranslate">Cygwin</span>)<br>
      {<br>
          // Environment is Windows Cygwin</p>
    <p>} else {</p>
    <p>    // Not a Windows Cygwin environment</p>
    <p>}</p>
    <p>```</p>
    <p>## Rust</p>
    <p>On windows Rust supports two ABI's: MSVC and Mingw(gnu). On rust
      we can check the environment by:</p>
    <p>```</p>
    <p><span class="pl-c">#[cfg(target_env = <span class="pl-s">"msvc"</span>)]</span></p>
    <p><span class="pl-c">// MSVC environment</span></p>
    <p><br>
      <span class="pl-c">#[cfg(target_env = <span class="pl-s">"gnu"</span>)]</span></p>
    <p><span class="pl-c">// Mingw environment</span></p>
    <p><span class="pl-c">```</span></p>
    <p><span class="pl-c">## Environment check &amp; Swift</span></p>
    <p><span class="pl-c">Here I want to propose some conditionals:<br>
      </span></p>
    <p><span class="pl-c">```</span></p>
    <p><span class="pl-c">environment(MSVC)</span></p>
    <p><span class="pl-c">environment(CYGWIN)</span></p>
    <p><span class="pl-c">environment(MUSL)</span></p>
    <p><span class="pl-c">// or</span></p>
    <p><span class="pl-c">target(</span><span class="pl-c"><span
          class="pl-c">MSVC</span>)</span></p>
    <p><span class="pl-c">target(</span><span class="pl-c"><span
          class="pl-c">MUSL</span>)<br>
      </span></p>
    <p><span class="pl-c">// or</span></p>
    <p><span class="pl-c">os(Windows, target: MSVC)</span></p>
    <p><span class="pl-c">os(Linux, target: MUSL)<br>
      </span></p>
    <p><span class="pl-c">// or</span></p>
    <p><span class="pl-c">os(Windows, environment: MSVC)</span></p>
    <p><span class="pl-c">os(Linux, environment: MUSL)</span></p>
    <p><span class="pl-c">```<br>
      </span></p>
    <p><span class="pl-c"><br>
        We can discuss about this topic and submit a proposal when
        everyone is agreed to a decision. So lets start!<br>
      </span></p>
    <p><span class="pl-c"><br>
      </span></p>
    <p><span class="pl-c">Thanks</span></p>
    <p><span class="pl-c">Mominul<br>
      </span></p>
  </body>
</html>