2016-08-22 8 views
6

मैं लिनक्स पर कुछ एंट्री लेवल स्विफ्ट कोड लिख रहा हूं जो सीखने के अभ्यास के रूप में है।लिनक्स पर स्विफ्ट - तीसरे पक्ष के मॉड्यूल आयात करना

एक सामान्य कार्य के रूप में, मैं अपने कोड में किसी तृतीय-पक्ष स्विफ्ट मॉड्यूल का उपयोग करना चाहता हूं। आइए इस मॉड्यूल को "फू" कहते हैं। फू मॉड्यूल में एक पैकेज.swift फ़ाइल है, और उस निर्देशिका में swift build चलाने के बाद, इसने .build/debug/libFoo.so बनाया है।

अब मैं इस के साथ दो काम करने की इच्छा:

  1. आरईपीएल में import Foo करने में सक्षम हो।
  2. शायद इस साझा ऑब्जेक्ट से लिंक करके, अपने स्वयं के स्विफ्ट प्रोग्राम में फू आयात करने में सक्षम हो।

मुझे लगता है कि दोनों कार्य संबंधित हैं, इसलिए अब वे एक ही प्रश्न में हैं।

1. के लिए, मुझे समझ में नहीं आता कि पैकेज कैसे आरईपीएल द्वारा 'खोजने योग्य' बन जाते हैं। मैंने 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 के बजाय 2.2 के लिए किया गया है क्योंकि swift build नहीं है - लेकिन यह वही आउटपुट उत्पन्न करता है जो मुझे विश्वास है)।

ध्यान दें कि मैं समझता हूं कि swift build स्वचालित रूप से डाउनलोड और तृतीय पक्ष मॉड्यूल का निर्माण कर सकता है, हालांकि मैं जानना चाहता हूं कि ऑन-डिस्क मॉड्यूल को कैसे शामिल किया जाए क्योंकि वे मेरे स्वयं के कार्य-प्रगति मॉड्यूल हो सकते हैं।


संपादित करें: मैं एक खोज है कि आप कम से कम स्थानीय विकास के लिए पैकेज के dependencies: सूची में url: पैरामीटर के रूप में स्थानीय पथ का उपयोग कर सकते हैं, के आधार पर swift3 साथ एक छोटी सी प्रयोग करने की कोशिश की।

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

मैं भी Bar/Sources/bar.swift बनाई युक्त:

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

मंशा है कि मॉड्यूल Bar समारोह bar(arg:) कहा जाता है प्रदान करता है

मैं एक निर्देशिका Bar और Bar/Package.swift बनाया।

मैं इस मॉड्यूल के लिए एक टैग किए गए स्थानीय Git रेपो बनाने के लिए एक git init, git 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 के लिए रिश्तेदार पथ:

तो शीर्ष स्तर पर वापस मैं निर्देशिका Foo और Foo/Package.swift बनाया।

मैं भी Foo/Sources/main.swift बनाया:

import Bar 
print(bar(arg: 11)) 

अब जब मैं swift buildFoo अंदर, यह 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

मैं आपके हालिया प्रयासों के साथ समस्याओं को पुन: उत्पन्न नहीं कर सका: मैंने आपके द्वारा वर्णित चरणों का पालन किया और 'फू' सफलतापूर्वक 'बार' आयात किया और 'बार' फ़ंक्शन कहा। एक और सवाल: आपने एक मॉड्यूल बनाने का प्रबंधन कैसे किया जिसने 'libFoo.so' लाइब्रेरी बनाई? जब मैंने आपके नवीनतम उदाहरण से 'बार' मॉड्यूल बनाया, तो '.build/debug' – OmniProg

+0

@OmniProg में इसका प्रयास करने के लिए धन्यवाद' libBar.so' नहीं था। मुझे यकीन नहीं है कि यह आपके लिए क्यों काम करता है। मैं स्विफ्ट के एक अलग संस्करण के साथ प्रयास करेंगे। यह उत्साहजनक है कि यह आपके लिए काम करता है। आपके दूसरे बिंदु पर, मैंने फू/बार उदाहरण बनाने से पहले, मैं एक थर्ड-पार्टी मॉड्यूल के साथ काम कर रहा था जिसे 'बार' नहीं कहा गया था (इसे स्विफ्ट कहा जाता था) और यह libswifter.so फ़ाइल उत्पन्न करता था, लेकिन मैं चाहता था एक सामान्य के रूप में सवाल उठाने के लिए। मैंने धारणा की कि .so एक मानक आउटपुट था, लेकिन स्पष्ट रूप से यह नहीं है। मुझे स्विफ्ट में कुछ भी दिखाई नहीं दे रहा है जो बता सकता है कि यह क्यों उत्पन्न हुआ। इसलिए या तो। – meowsqueak

+0

क्षमा करें, यह उल्लेख करना भूल गया कि मैं सटीक उसी संस्करण, स्विफ्ट-3.0-PREVIEW-4-ubuntu14.04 का उपयोग कर रहा हूं, इसलिए यह सभी व्युत्पन्न फ़ाइलों को साफ़ करने और स्क्रैच से पुनः प्रयास करने के लायक हो सकता है। – OmniProg

उत्तर

0

जैसा कि प्रलेखन में बताया गया है, लिनक्स पर अपने पैकेज प्रबंधक के साथ स्विफ्ट प्रगति पर है, इसलिए कोई आश्चर्य नहीं कि बग और जानकारी की कमी है। हालांकि, यहां प्रयोग और प्रयोग पढ़ने से मुझे मिला है।

मॉड्यूल Foo एक पुस्तकालय, libFoo.so, /LibLocation और /ModuleLocation में Foo.swiftmodule में है, तो यह संभव आयात करने के लिए और एक स्विफ्ट कार्यक्रम में Foo उपयोग करते हैं, इसे कहते main.swift, और फिर

swiftc -I /ModuleLocation -L /LibLocation -lFoo main.swift 
करके यह संकलन है

एक भी रूप में

swift -I /ModuleLocation -L /LibLocation -lFoo 

यह शुरू करके आरईपीएल में कर सकते हैं यानी अनिवार्य रूप से यह 012 के रूप में एक ही तर्क दे रही है। बीटीडब्ल्यू, यदि मॉड्यूल swift build का उपयोग करके बनाया गया था, ModuleLocationLibLocation जैसा ही हो सकता है।

मैं पहले के एक टिप्पणी में उल्लेख किया है, Foo और Bar के साथ अपने उदाहरण, दोनों swift build का उपयोग कर बनाया गया है, मुझे ठीक के लिए काम किया है, इसलिए मैं समस्या को पुन: नहीं कर सका।

बीटीडब्ल्यू, swift.org प्रलेखन और कमांड लाइन सहायता पढ़ने के अलावा, swift build और -v ध्वज के साथ अन्य आदेशों को चलाकर बहुत रोचक और संभावित रूप से उपयोगी जानकारी प्राप्त कर सकते हैं। swiftc के साथ उपलब्ध कुछ छिपा विकल्पों के बारे में पता लगाने के लिए कर

swiftc -help-hidden 
2

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

उदाहरण आप के बाद अपने प्रश्न में पोस्ट का उपयोग करना "संपादित करें," यह ठीक आप swift build का उपयोग प्रदान की काम करने के लिए लगता है। Swift Package Manager आप के लिए निर्भरता के सभी संभाल लेंगे, भले ही वे डिस्क पर हैं (यह स्विफ्ट 3 पर काम करता है और 4):

$ 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 

नोट फू/.build/डिबग कुछ भी नहीं है कि। इसलिए फाइलें:

$ 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 पाया।अपने उदाहरण में इसे लागू करने के लिए आपको दो विकल्प हैं:

  • 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 
    


  • ,210 (इस स्विफ्ट 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. और यह है कि कैसे आप का निर्माण करते हैं और आरईपीएल फोन:

      $ 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/डिबग निर्देशिका में libBar.so बनाता है:

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

आप इन परिणामों पुन: पेश करने, मैं किसी भी .build निर्देशिका और .so फ़ाइलों की सफाई, और स्विफ्ट की एक साफ संस्करण को स्थापित करने का सुझाव देते हैं असमर्थ हैं, तो (मैं इस के लिए swiftenv सलाह देते हैं)।

संबंधित मुद्दे