2016-08-22 6 views
6

私は学習の練習として、Linuxにいくつかのエントリーレベルのスウィフトコードを書いています。Linux上でSwift - サードパーティのモジュールをインポートする

一般的な作業として、自分のコードでサードパーティのSwiftモジュールを使用したいと考えています。このモジュールを "Foo"と呼ぶことにしましょう。 FooモジュールにはPackage.swiftファイルがあり、そのディレクトリにswift buildを実行すると、.build/debug/libFoo.soが作成されています。

は今、私はこれで2つのことを行うことを望む:

  1. はREPLでimport Fooすることができます。
  2. おそらくこの共有オブジェクトにリンクすることで、私自身の迅速なプログラムでFooをインポートすることができます。

私は両方のタスクが関連していると感じているので、今のところ同じ質問になります。

については、REPLによってパッケージが「発見可能」になる方法はわかりません。私はswift -F .build/debug -framework Fooを試しましたが、「このようなモジュールはありません」というエラーが表示されます。私もswift -I .build/debugと同じ結果を試しました。 2.については

、私はswiftc --helpを検討し、私はこれらを使用するための正しい方法を見つけることができませんでしたが-L-lのオプションがあります。

$ swiftc main.swift -L ../foo.git/.build/debug -llibFoo.so 
main.swift:1:8: error: no such module 'Foo' 
import Foo 
    ^

私は両方/どちらかスウィフト2.2または3.0を使用しています(swift buildではなくswimを2.2として使用していますが、それはswift buildではありませんが、私はそれと同じ出力を生成します)。

swift buildは自動的にサードパーティのモジュールをダウンロードしてビルドすることができますが、オンディスクモジュールを自分自身の作業中のモジュールとして組み込む方法を知りたいと思います。


編集:私はあなたが、少なくとも地域開発のために、パッケージのdependencies:リストにurl:パラメータとしてローカルパスを使用することができるという発見に基づいてswift3と少し実験を試みました。

私は、ディレクトリBarBar/Package.swift作成:

import PackageDescription 
let package = Package(name: "Bar") 

を私も含むBar/Sources/bar.swiftを作成:

public func bar(arg: Int) -> Int { 
    return arg * 2 
} 

意図は、そのモジュールBarbar(arg:)と呼ばれる機能を提供しています。

私は、このモジュールのタグ付けローカル Gitのレポを作成するgit initgit add .git commit -m "Initial commit."、その後git tag 1.0.0をしました。

import PackageDescription 
let package = Package(
    name: "Foo", 
    dependencies: [ .Package(url: "../Bar", majorVersion: 1) ] 
) 

../Barの相対パス:

はその後戻って、トップレベルの私は、ディレクトリFooFoo/Package.swiftを作成しました。

私もFoo/Sources/main.swiftを作成しました:

import Bar 
print(bar(arg: 11)) 

Foo内部swift build、それはBarのクローンとそれを構築する場合。しかし、私は次のエラーを取得します。 そのようなモジュール:私は、これはうまくいくかもしれないことを期待していた

$ swift build 
Compile Swift Module 'Foo' (1 sources) 
Linking .build/debug/Bar 
.../Foo/Sources/main.swift:3:7: error: use of unresolved identifier 'bar' 
print(bar(arg: 11)) 
     ^~~ 
<unknown>:0: error: build had 1 command failures 
error: exit(1): .../swift-3.0-PREVIEW-4-ubuntu14.04/usr/bin/swift-build-tool -f .../Foo/.build/debug.yaml 

:私はもう一度まったく同じビルドコマンドを実行する場合

$ swift build 
Compile Swift Module 'Bar' (1 sources) 
Compile Swift Module 'Foo' (1 sources) 
.../Foo/Sources/main.swift:1:8: error: no such module 'Bar' 
import Bar 
    ^
<unknown>:0: error: build had 1 command failures 
error: exit(1): .../swift-3.0-PREVIEW-4-ubuntu14.04/usr/bin/swift-build-tool -f .../Foo/.build/debug.yaml 

奇妙なことに、私は別のエラーを取得していません。

+0

最新の試みで問題を再現できませんでした。私が説明した手順に従って、 'Foo'が' Bar'を読み込み、 'bar'関数を呼び出しました。もう1つの質問: 'libFoo.so'ライブラリを作成したモジュールをどうやってビルドしましたか?あなたの最新の例から 'Bar'モジュールをビルドしたとき、' .build/debug'に 'libBar.so'がありませんでした。 – OmniProg

+0

@OmniProg試してみてください。なぜそれがあなたのために働いたのか分かりません。私はSwiftの別のバージョンで試してみます。それはあなたのために働くことを奨励しています。あなたの2番目のポイントは、私がFoo/Barの例を作る前に、私はBarと呼ばれていないサードパーティのモジュール(Swifterと呼ばれていた)を使って作業していましたが、libSwifter.soファイルを生成しました。質問を一般的なものとして提起する。私は.soが標準出力であると仮定しましたが、明らかにそうではありません。私はSwifterの中に何が出ているのか分からない。 – meowsqueak

+0

申し訳ありませんが、正確に同じバージョンのswift-3.0-PREVIEW-4-ubuntu14.04を使用していることを忘れてしまったので、すべての派生ファイルをクリーンアップしてゼロから再試行する価値があります。 – OmniProg

答えて

0

ドキュメントに記載されているように、Linux上でパッケージマネージャーを使用しているSwiftは進行中ですので、バグや情報の不足はありません。しかし、ここで私は実験と助けを読んで見つけたものです。

モジュールFooが、インポートして使用スウィフトプログラムでFooを、main.swiftそれを呼び出すし、その後

swiftc -I /ModuleLocation -L /LibLocation -lFoo main.swift 
を行うことによって、それをコンパイルすることが可能である、 /LibLocation/ModuleLocationFoo.swiftmoduleに、ライブラリー、 libFoo.soを持っている場合

一つも

すなわち、本質的にそれを012に同じ引数を与え
swift -I /ModuleLocation -L /LibLocation -lFoo 

としてそれを起動することによってREPLでそれを行うことができます。ところで、モジュールがswift buildを使用して構築された場合、ModuleLocationはおそらくLibLocationと同じです。

私が前のコメントで述べたように、FooBarの両方の例は、どちらもswift buildを使用して作成されていますので問題は再現できませんでした。

swift.orgのドキュメントとコマンドラインのヘルプを読むだけでなく、swift buildと他のコマンドを-vフラグで実行することで、面白い情報や役に立つ情報をたくさん集めることができます。 swiftcで利用可能ないくつかの隠しオプションについて調べるには、あなたは、これはあなたがswift buildを使用して正常に動作するようだ「EDIT」の後、あなたの質問に投稿された例を使用して

swiftc -help-hidden 
2

Be able to import Foo in my own swift program, perhaps by linking with this shared object.

を行います。フー/ .build /デバッグがいずれも含まれていないことを

$ cd Foo 

$ swift build 
Cloning /path/to/Bar 
HEAD is now at 0c3fd6e Initial commit. 
Resolved version: 1.0.0 
Compile Swift Module 'Bar' (1 sources) 
Compile Swift Module 'Foo' (1 sources) 
Linking ./.build/debug/Foo 

$ .build/debug/Foo 
22 

注:Swift Package Manager(これはスウィフト3上で動作し、4)は、ディスク上の方にも、あなたのための依存関係のすべてを処理します。 soファイル:

$ ls Foo/.build/debug 
Bar.build Bar.swiftdoc Bar.swiftmodule Foo Foo.build Foo.swiftdoc Foo.swiftmodule ModuleCache 

私は、代わりに.swiftdocと.swiftmoduleファイルが使用されると考えています。

Be able to import Foo in the REPL.

この部分は、ビットメシエだが、私は解決策hereを見つけました。あなたの例に適用するには、次の2つのオプションがあります。

  • Use swift build with extra flagsを(これはスウィフト3上で動作し、4):

    $ cd Bar 
    
    $ swift build -Xswiftc -emit-library 
    Compile Swift Module 'Bar' (1 sources) 
    
    $ swift -I .build/debug -L . -lBar 
        1> import Bar 
        2> bar(arg: 11) 
    $R0: Int = 22 
        3> 
    

    これが現在のディレクトリにlibBar.soを作成します。

    $ ls 
    libBar.so Package.swift Sources 
    


  • Update your Package.manifest(これはスウィフト4に固有のものです):

    1. 更新Package.manifestはこのようなものになります。

      // swift-tools-version:4.0 
      import PackageDescription 
      
      let package = Package(
          name: "Bar", 
          products: [ 
           .library(
            name: "Bar", 
            type: .dynamic, 
            targets: ["Bar"]), 
          ], 
          targets: [ 
           .target(
            name: "Bar", 
            dependencies: [], 
            path: "Sources"), 
          ] 
      ) 
      
    2. を、これはあなたがビルドを行うと、REPLを呼び出す方法です:

      $ cd Bar 
      
      $ swift build 
      Compile Swift Module 'Bar' (1 sources) 
      Linking ./.build/x86_64-unknown-linux/debug/libBar.so 
      
      $ swift -I .build/debug -L .build/debug -lBar 
          1> import Bar 
          2> bar(arg: 11) 
      $R0: Int = 22 
          3> 
      

    これは.build/debugディレクトリにlibBar.soを作成します。

    $ ls .build/debug 
    Bar.build Bar.swiftdoc Bar.swiftmodule libBar.so ModuleCache 
    

あなたはこれらの結果を再現することができない場合、私は(私はこれのためにswiftenvをお勧めします)任意の.buildディレクトリとの.soファイルを一掃し、スウィフトのクリーンバージョンをインストールすることをお勧め。

関連する問題