<?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 SwiftPM</title>
        <link>https://duan.ca/tag/swiftpm/</link>
        <atom:link href="https://duan.ca/tag/swiftpm/feed.xml" rel="self" type="application/rss+xml" />
            <item>
                <title>Using Instruments on Non-macOS, Non-iOS Executables</title>
                <description>&#60;p&#62;How do you use use Instruments, the instrumentation tool distributed alongside Xcode? It&#39;s easy if you are
profiling a macOS or iOS app. No so with a regular old command-line tool built, say, with SwiftPM. To do so,
you&#39;ll need to codesign the target binary. Otherwise Instruments will give you a &#60;code&#62;&#38;quot;Failed to gain authorization&#38;quot;&#60;/code&#62; error message.&#60;/p&#62;
&#60;p&#62;Here&#39;s the steps:&#60;/p&#62;
&#60;ol&#62;
&#60;li&#62;Create a entitlement file with &#60;code&#62;com.apple.security.get-task-allow&#60;/code&#62; set to true:&#60;/li&#62;
&#60;/ol&#62;
&#60;pre&#62;&#60;code class=&#34;language-xml&#34;&#62;&#38;lt;?xml version=&#38;quot;1.0&#38;quot; encoding=&#38;quot;UTF-8&#38;quot;?&#38;gt;
&#38;lt;!DOCTYPE plist PUBLIC &#38;quot;-//Apple//DTD PLIST 1.0//EN&#38;quot; &#38;quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#38;quot;&#38;gt;
&#38;lt;plist version=&#38;quot;1.0&#38;quot;&#38;gt;
    &#38;lt;dict&#38;gt;
        &#38;lt;key&#38;gt;com.apple.security.get-task-allow&#38;lt;/key&#38;gt;
        &#38;lt;true/&#38;gt;
    &#38;lt;/dict&#38;gt;
&#38;lt;/plist&#38;gt;
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Let&#39;s call it &#60;code&#62;Entitlements.plist&#60;/code&#62;&#60;/p&#62;
&#60;ol start=&#34;2&#34;&#62;
&#60;li&#62;
&#60;p&#62;Build the executable.&#60;/p&#62;
&#60;/li&#62;
&#60;li&#62;
&#60;p&#62;Codesign your executable with the entitlement file&#60;/p&#62;
&#60;/li&#62;
&#60;/ol&#62;
&#60;pre&#62;&#60;code&#62;codesign -s - -f --entitlements path/to/Entitlements.plist path/to/executable
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Now proceed with your profiling in Instruments.&#60;/p&#62;
&#60;p&#62;Not sure where this is officially documented. So I&#39;m officially documenting it here.&#60;/p&#62;
</description>
                <pubDate>Thu, 31 Mar 2022 20:39:05 -0700</pubDate>
                <link>https://duan.ca/2022/03/31/instrumenting-commandline-executables/</link>
                <guid isPermaLink="true">https://duan.ca/2022/03/31/instrumenting-commandline-executables/</guid>
            </item>
            <item>
                <title>Building IndexStoreDB on Linux: The Portable Technique</title>
                <description>&#60;h2&#62;The problem&#60;/h2&#62;
&#60;p&#62;As of writing of this article, when you attempt to use Apple&#39;s Swift library &#60;a href=&#34;https://github.com/apple/indexstore-db&#34;&#62;IndexStoreDB&#60;/a&#62; on Linux as
a normal SwiftPM dependency, it won&#39;t build successfully:&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-fish&#34;&#62;❯ cat Package.resolved
{
  &#38;quot;object&#38;quot;: {
    &#38;quot;pins&#38;quot;: [
      {
        &#38;quot;package&#38;quot;: &#38;quot;IndexStoreDB&#38;quot;,
        &#38;quot;repositoryURL&#38;quot;: &#38;quot;https://github.com/apple/indexstore-db&#38;quot;,
        &#38;quot;state&#38;quot;: {
          &#38;quot;branch&#38;quot;: &#38;quot;swift-5.5.2-RELEASE&#38;quot;,
          &#38;quot;revision&#38;quot;: &#38;quot;e771994778265c2efe8d33a7ca30adf5f3d2065a&#38;quot;,
          &#38;quot;version&#38;quot;: null
        }
      }
    ]
  },
  &#38;quot;version&#38;quot;: 1
}

❯ swift build &#38;gt; /dev/null

❯ echo $status
1
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;The issue is documented in the build instruction for Linux:&#60;/p&#62;
&#60;blockquote&#62;
&#60;p&#62;The C++ code in the index requires &#60;code&#62;libdispatch&#60;/code&#62;, but unlike Swift code, it cannot find it automatically on Linux. You can work around this by adding a search path manually.&#60;/p&#62;
&#60;/blockquote&#62;
&#60;pre&#62;&#60;code&#62;$ swift build -Xcxx -I&#38;lt;path_to_swift_toolchain&#38;gt;/usr/lib/swift -Xcxx -I&#38;lt;path_to_swift_toolchain&#38;gt;/usr/lib/swift/Block
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Okay, so, how would my package build in Linux environments where the Swift toolchain&#39;s setup is unknown? How
do we avoid building with one toolchain while mixing in &#60;code&#62;libdispatch&#60;/code&#62; from another toolchain somewhere? Here&#39;s
what I did for my command-line tool &#60;a href=&#34;https://github.com/dduan/Clue&#34;&#62;Clue&#60;/a&#62;.&#60;/p&#62;
&#60;h2&#62;The solution&#60;/h2&#62;
&#60;p&#62;The essence of the problem is about the installation location of the Swift toolchain. Our solution makes the
following assumptions:&#60;/p&#62;
&#60;ol&#62;
&#60;li&#62;A Swift toolchain is installed on the file system on Linux (duh!).&#60;/li&#62;
&#60;li&#62;The toolchain is at least similar to the one distributed on Swift.org. So &#60;code&#62;libdispatch&#60;/code&#62; is distributed
alongside the other binaries, in a stable relative directory.&#60;/li&#62;
&#60;/ol&#62;
&#60;p&#62;Having the &#60;code&#62;swift&#60;/code&#62; command available (assumption #1), we can just let it tell us about itself with the
&#60;code&#62;-print-target-info&#60;/code&#62; flag:&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-fish&#34;&#62;❯ swift -print-target-info
{
  &#38;quot;compilerVersion&#38;quot;: &#38;quot;Swift version 5.5.2 (swift-5.5.2-RELEASE)&#38;quot;,
  &#38;quot;target&#38;quot;: {
    &#38;quot;triple&#38;quot;: &#38;quot;x86_64-unknown-linux-gnu&#38;quot;,
    &#38;quot;unversionedTriple&#38;quot;: &#38;quot;x86_64-unknown-linux-gnu&#38;quot;,
    &#38;quot;moduleTriple&#38;quot;: &#38;quot;x86_64-unknown-linux-gnu&#38;quot;,
    &#38;quot;compatibilityLibraries&#38;quot;: [ ],
    &#38;quot;librariesRequireRPath&#38;quot;: false
  },
  &#38;quot;paths&#38;quot;: {
    &#38;quot;runtimeLibraryPaths&#38;quot;: [
      &#38;quot;/home/dan/.swiftenv/versions/5.5.2/usr/lib/swift/linux&#38;quot;
    ],
    &#38;quot;runtimeLibraryImportPaths&#38;quot;: [
      &#38;quot;/home/dan/.swiftenv/versions/5.5.2/usr/lib/swift/linux&#38;quot;,
      &#38;quot;/home/dan/.swiftenv/versions/5.5.2/usr/lib/swift/linux/x86_64&#38;quot;
    ],
    &#38;quot;runtimeResourcePath&#38;quot;: &#38;quot;/home/dan/.swiftenv/versions/5.5.2/usr/lib/swift&#38;quot;
  }
}
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Great! We see where the runtime is installed. Now we can invoke assumption #2, that &#60;code&#62;libdispatch&#60;/code&#62; is at
a relative location to the rest of the runtime. In the output from above, the value for &#60;code&#62;runtimeResourcePath&#60;/code&#62;
happens to be the parent directory for &#60;code&#62;libdispatch&#60;/code&#62;&#39;s headers. The &#60;code&#62;&#38;lt;path_to_swift_toolchain&#38;gt;&#60;/code&#62; value in
&#60;a href=&#34;https://github.com/apple/indexstore-db&#34;&#62;IndexStoreDB&#60;/a&#62;&#39;s official instruction in this particular setup would be
&#60;code&#62;/home/dan/.swiftenv/versions/5.5.2&#60;/code&#62;.  So the following command would have worked:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;swift build -Xcxx -I/home/dan/.swiftenv/versions/5.5.2/usr/lib/swift -Xcxx -I/home/dan/.swiftenv/versions/5.5.2/usr/lib/swift/Block
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;All we need to do is parse this information at build time, and it should work on every Linux setup! Choose
whatever parsing method you like. Here&#39;s (more or less) the &#60;code&#62;Makefile&#60;/code&#62; for &#60;a href=&#34;https://github.com/dduan/Clue&#34;&#62;Clue&#60;/a&#62;:&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-make&#34;&#62;SHELL = /bin/bash
ifeq ($(shell uname),Darwin)
EXTRA_SWIFT_FLAGS = &#38;quot;--disable-sandbox&#38;quot;
else
SWIFT_TOOLCHAIN = &#38;quot;$(shell swift -print-target-info | grep runtimeResourcePath | cut -f 2 -d &#39;:&#39; | cut -f 2 -d &#39;&#38;quot;&#39;)&#38;quot;
EXTRA_SWIFT_FLAGS = -Xcxx -I${SWIFT_TOOLCHAIN} -Xcxx -I${SWIFT_TOOLCHAIN}/Block
endif

define build
	@swift build --configuration $(1) -Xswiftc -warnings-as-errors ${EXTRA_SWIFT_FLAGS}
endef

.PHONY: build
build:
	$(call build,release)

.PHONY: test
test:
	@swift test ${EXTRA_SWIFT_FLAGS}

.PHONY: debug
debug:
	$(call build,debug)
&#60;/code&#62;&#60;/pre&#62;
&#60;ol&#62;
&#60;li&#62;&#60;code&#62;make build&#60;/code&#62; / &#60;code&#62;make test&#60;/code&#62; / &#60;code&#62;make debug&#60;/code&#62; all work as expected, building IndexStoreDB successfully.&#60;/li&#62;
&#60;li&#62;As-is, this snippet is project-agnostic. So you can throw it in your SwiftPM project and it should &#38;quot;just
work&#38;quot;.&#60;/li&#62;
&#60;/ol&#62;
&#60;p&#62;Alright!&#60;/p&#62;
</description>
                <pubDate>Wed, 09 Feb 2022 15:58:41 -0800</pubDate>
                <link>https://duan.ca/2022/02/09/building-indexstoredb-on-linux/</link>
                <guid isPermaLink="true">https://duan.ca/2022/02/09/building-indexstoredb-on-linux/</guid>
            </item>
    </channel>
</rss>