<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Daniel Duan's Articles About swift</title>
        <link>https://duan.ca/tag/swift/</link>
        <atom:link href="https://duan.ca/tag/swift/feed.xml" rel="self" type="application/rss+xml" />
            <item>
                <title>Let&#39;s Play LLVM in Swift: Setup</title>
                <description>&#60;p&#62;&#60;em&#62;The prospect of Swift being open-source excites me. In preparation for it, I
decided to learn a little bit about LLVM. In the offical &#60;a href=&#34;http://llvm.org/docs/tutorial/index.html&#34;&#62;tutorial&#60;/a&#62;, C++
and OCaml are used to create a programming language. So I asked myself: why not
Swift? As you&#39;ll see in this post, Swift is as good as any language when it
comes to leveraging LLVM.&#60;/em&#62;&#60;/p&#62;
&#60;p&#62;LLVM is an &#38;quot;compiler infrastructure&#38;quot;. As a user, that translates to &#38;quot;a set of
libraries to help us create programming language and tools&#38;quot;. Since this is
not an introduction to the LLVM project, it suffices to say that LLVM makes
creating programming language easy: give your language in &#60;a href=&#34;http://llvm.org/docs/LangRef.html&#34;&#62;LLVM IR&#60;/a&#62; form
and you get the rest of a native/JIT language for free, optimization included!&#60;/p&#62;
&#60;p&#62;LLVM&#39;s default API is in C++. In addition, it officially offers a C wrapper.
Lucky for us, Swift is C-interoperable – no bridging necessary :)&#60;/p&#62;
&#60;p&#62;Now we arrive at our goal for this post: create an Xcode project that can make
calls into LLVM&#39;s C API, aka to compile this single line of code:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;let module = LLVMModuleCreateWithName(&#38;quot;my_module&#38;quot;)
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;I assume you have Xcode 7.1 installed on OS X 10.11, but no more.&#60;/p&#62;
&#60;h2&#62;1. Getting LLVM&#60;/h2&#62;
&#60;p&#62;There are a lot of materials on the internet dedicated to setting up an LLVM
environment. As we are not working &#60;em&#62;on&#60;/em&#62; LLVM itself, and we are not on some
crazy custom Linux environment (to be fair, it&#39;s trivial to set LLVM up on
most major Linux distributions), the &#60;a href=&#34;http://llvm.org/releases/download.html&#34;&#62;pre-built Clang binaries&#60;/a&#62; is good
enough. Download and unpack the .tar file somewhere handy in on your hard
drive. For example, I put it at &#60;code&#62;$(HOME)/usr/local/clang-3.4&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;Aaaand we&#39;re done. We have LLVM.&#60;/p&#62;
&#60;p&#62;&#60;em&#62;Sidenote: Xcode installs clang the compiler, but a lot of LLVM tools are
missing. That&#39;s why we need a separate LLVM/Clang setup.&#60;/em&#62;&#60;/p&#62;
&#60;h2&#62;2. Create an Xcode Project&#60;/h2&#62;
&#60;p&#62;Create a new OS X - Command Line Tool Xcode project, choose Swift as it&#39;s
language.&#60;/p&#62;
&#60;p&#62;&#60;img src=&#34;/assets/2015/10/llvm-swift-01-create-cmd-project.png&#34; alt=&#34;Create A Command Line Xcode Project For LLVM&#34; /&#62;&#60;/p&#62;
&#60;p&#62;Accessing C stuff in Swift is the same as using your Objective-C
classes. So we need to &#60;a href=&#34;https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html&#34;&#62;create a bridging header&#60;/a&#62;. (I usually create
a Objective-C class so that Xcode prompts me for creating the header, then I
delete the .h and .m files). The project layout is now:&#60;/p&#62;
&#60;p&#62;&#60;img src=&#34;/assets/2015/10/llvm-swift-02-bridging-header.png&#34; alt=&#34;Create a bridging header to import LLVM C libraries&#34; /&#62;&#60;/p&#62;
&#60;p&#62;Import the LLVM headers for its C interface. For our example, this is the
entire bridging header:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;#import &#38;lt;llvm-c/Core.h&#38;gt;
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;It&#39;s probably a good time to replace content of &#60;code&#62;main.swift&#60;/code&#62; with our awesome
LLVM IR-generating code:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;let module = LLVMModuleCreateWithName(&#38;quot;my_module&#38;quot;)
&#60;/code&#62;&#60;/pre&#62;
&#60;h2&#62;3. Teach Xcode About LLVM&#60;/h2&#62;
&#60;p&#62;Our code would not compile at this point. Xcode complains that the LLVM header
can not be found. Before you jump to the target build settings, allow me
introduce &#60;code&#62;llvm-config&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;It turns out that the compliler flags for building a compiler can get complex
pretty quickly. So LLVM comes with a command that generates them. For me it
lives under &#60;code&#62;$(HOME)/usr/local/clang-3.4/bin&#60;/code&#62;. We can ask it for flags that
compiles standard C++, links standard and core libraries like so:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;llvm-config --cxxflags --ldflags --system-libs --libs core
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;(As we use more and more LLVM libraries in the future, the list following
&#60;code&#62;--libs&#60;/code&#62; will grow. &#60;code&#62;core&#60;/code&#62; is all we need to compile our example). To anyone
who&#39;s used GCC/Clang in command line, the output should be pretty
self-explanatory:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;-I/Users/drchrono/local/clang-3.4/include  -DNDEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -O3  -std=c++11 -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -fno-common -Wcast-qual
-L/Users/drchrono/local/clang-3.4/lib 
-lLLVMCore -lLLVMSupport
-lz -lpthread -ledit -lcurses -lm
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;I&#39;ll walk through how to ask Xcode to respect these.&#60;/p&#62;
&#60;p&#62;First, go to build settings and set search paths for header files and
libraries according to output from &#60;code&#62;llvm-config&#60;/code&#62;. For me that means:&#60;/p&#62;
&#60;p&#62;&#60;img src=&#34;/assets/2015/10/llvm-swift-03-header-search-path.png&#34; alt=&#34;Set LLVM header search path in Xcode&#34; /&#62;
&#60;img src=&#34;/assets/2015/10/llvm-swift-04-library-search-path.png&#34; alt=&#34;Set LLVM library search path in Xcode&#34; /&#62;&#60;/p&#62;
&#60;p&#62;If you try to compile, now Xcode tells you some #define is missing. Again,
we can find them in &#60;code&#62;llvm-config&#60;/code&#62;&#39;s result. Navigate to &#38;quot;Preprocessing&#38;quot; in
build setting and add those values starting with &#60;code&#62;-D&#60;/code&#62;, with out the &#60;code&#62;-D&#60;/code&#62;:&#60;/p&#62;
&#60;p&#62;&#60;img src=&#34;/assets/2015/10/llvm-swift-05-macros.png&#34; alt=&#34;Set preprocessor macros&#34; /&#62;&#60;/p&#62;
&#60;p&#62;Remember to add these for both &#38;quot;Debug&#38;quot; and &#38;quot;Release&#38;quot;.&#60;/p&#62;
&#60;p&#62;The last step is asking Xcode to link againt the LLVM libraries. Paste in the
&#60;code&#62;-l&#60;/code&#62; flags from &#60;code&#62;llvm-config&#60;/code&#62; at &#38;quot;Other Linker Flags&#38;quot;:&#60;/p&#62;
&#60;p&#62;&#60;img src=&#34;/assets/2015/10/llvm-swift-06-link-libraries.png&#34; alt=&#34;Ask Xcode to link against LLVM libraries&#34; /&#62;&#60;/p&#62;
&#60;h2&#62;4. Conclusion&#60;/h2&#62;
&#60;p&#62;Now our Swift LLVM code compiles! Looking back, setting LLVM up with Xcode is
no more special than setting up with any C libraries. Hopefully this post will
cut down research time for some. Now go create awesome natively languages in
Swift!&#60;/p&#62;
</description>
                <pubDate>Sun, 25 Oct 2015 11:53:15 -0700</pubDate>
                <link>https://duan.ca/2015/10/25/lets-play-llvm-in-swift-setup/</link>
                <guid isPermaLink="true">https://duan.ca/2015/10/25/lets-play-llvm-in-swift-setup/</guid>
            </item>
    </channel>
</rss>