Back to "जी हाँ, यह काम कैसे किया जा सकता है!"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

.NET AOT DevOps SQLite

जी हाँ, यह काम कैसे किया जा सकता है!

Thursday, 12 December 2024

यदि आप जहाज के लिए कोशिश कर रहे हैं एक एकल के रूप में, देशी एक्जीक्यूटेबल अनुप्रयोग, आपने संभवतः पहली बार एओटीत में चेहरे का उपयोग किया है। आप सब कुछ प्राप्त करें, निर्माण सफलता प्राप्त करें, और फिर - bolox-t-twows, और फिर - समय चलाने के साथ क्रैश DllNotFoundException के बारे में त्रुटि e_sqlite3.. मुझे तुम्हें निराशा के घंटे बचाने के लिए मैं के माध्यम से चला गया और आपको सही तरह से दिखाने के लिए...

( और आपको परवाह क्यों करनी चाहिए?)

चलो पूर्ण आधारों के साथ शुरू करते हैं. यदि आप कभी एक निर्माण अनुप्रयोग बनाया है और आश्चर्य है कि क्यों आप सर्वर पर ".नेट रन समय" स्थापित करने की जरूरत है या क्यों अपने चैन एओ एओ एओ एओ एओए उन समस्याओं का जवाब है.

कैसे.नेट आम तौर पर काम करता है (प्रयोग)

जब आप C# कोड लिखते हैं और अपने अनुप्रयोग का निर्माण करते हैं, वे सत्यापन मशीन कोड नहीं बनाते जो आपका सीपीयू सीधे कार्य कर सकता है. इसके बजाय, यह कुछ भी उत्पन्‍न करता है जिसे बुलाया जाता है. इंटरेक्शन भाषा (आईएल)— इसकी गंभीरता आपके C# कोड और वास्तविक मशीन निर्देशों के बीच में है.

जब आप अपने .NET ऐप चलाने के लिए, यहाँ क्या होता है:

  1. आपका कम्प्यूटर बोझिल करता है.नेटटी रन टाइम (एक अलग प्रोग्राम)
  2. स्वतः पूर्ण स्क्रीन आपके IL कोड को पढ़ता है
  3. सिर्फ समय में (JTT) इन्जेक्शनों में IL को स्थानीय मशीन कोड में मदद करता है जैसे आपका एख्तियार है
  4. आपका सीपीयू अंत में उस मशीन कोड को चला रहा है

यह एक अनुवादक है जो अपनी रेसिपि (IL) को पढ़ता है और इसे लाइन में अनुवाद करता है जब वे खाना पकाने के दौरान. यह काम करता है, लेकिन वहाँ मुख्य है:

  • .नेट रन टाइम है 5050 बजे अतिरिक्त फ़ाइलों की आप तैनात करने की जरूरत है
  • Jed कंपाइलिंग कोड अनुवाद करने में समय लगता है (आपके ए आईएईएस पहली बार धीमा है)
  • JITN कंपाइलर स्वयं स्मृति में बैठता है जब आपका app चलता है

एओटी भरें (अ- हेड- समय कंशनल्शन)

नेटिव एओटी इस मॉडल को उसके सिर पर घुमाता है. अपने कोड का अनुवाद कम से कम करने के बजाय, यह सब कुछ का अनुवाद करता है बिल्ड समय. आप एक एकल एक्जीक्यूटेबल फ़ाइल के साथ अंत है जिसमें आपका सीपीयू कोड सीधे चला सकता है - कोई अनुवादक नहीं, इंतजार नहीं कर रहा है.

इसके बारे में सोचिए कि एक जीवित अनुवादक के बजाय एक पेशेवर रूप से अनुवादित रेसिपि बुक प्राप्त करना ।

खेल-चिंग फायदे

यहाँ जो कहा गया एओटी आपको देता है:

1. छोटा एक्जीक्यूटेबल: 150MB+ के बजाय 10- 30MB

आपका ए प्लगइन तथा जो कुछ भी है उसे एक छोटा बाइनरी में कम्पाइल किया जाता है. कोई अलग श्रेणी फ़ाइलें नहीं हैं.

2. तत्काल प्रारंभ होता है: 80% तेजी से ठंड शुरू होती है

मेरी जाँच: सामान्य .NT शुरू करने के लिए ~ 800ms लिया, AOT ~150ms ले लिया. वहाँ कोई Jam- अप समय नहीं है, मशीन कोड तुरंत चलाने के लिए तैयार है.

शून्य शून्य डिपेंडेंसीज़.: नहीं.

आप किसी भी मशीन के लिए अपने एक्जीक्यूटेबल की नक़ल कर सकते हैं ठीक ओएस (लिनक्स/ब्लिक) के साथ और यह सिर्फ चला जाता है. कोई "pod. TTRT 9 बार" की तरह.

4 कम मेमोरी उपयोग.: 50% कम मेमोरी के बारे में

याद में कोई जेआई कंपाइलर नहीं है. मेरे गेटवे अनुप्रयोग में, सामान्य.ETXMB इस्तेमाल किया जाता है, AOT का इस्तेमाल 42MB.

सीमित वातावरण के लिए ५.: वहां काम करता है जहाँ Jaat' नहीं कर सकता

कुछ वातावरण (स्टॉक्स, आईएसएसएस, अंतर्निर्मित सिस्टम) कोड पीढ़ी की अनुमति नहीं देता है. एओटी हर जगह काम करता है.

ट्रेफ्स (हमेशा एक होल्डर है)

AOT एक जादू नहीं है। आप व्यापार कम कर रहे हैं ऊपर स्वाश अनुकूलन के लिए:

1. कोई गतिशील कोड बनाना नहीं

जो भी है जो कोड चालू करने पर काम नहीं करेगा:

  • System.Reflection.Emit (स्टिंग क़िस्म गतिशीलता)
  • गतिशील सम्मेलन लोड किया जा रहा है (लोड कर रहा है पर गति से)
  • कुछ कल्पना प्रतिबिंब चाल

सामान्य सामान्य .NT कोड ठीक है, लेकिन कुछ सेटों पर निर्भर करता है जो विशेष कॉन्फ़िगरेशन की जरूरत पर निर्भर हैं.

2. प्लेटफॉर्म विशिष्ट बनाने के लिए

JITIIZIZIL जो किसी भी मंच पर चलता है. AOT मशीन कोड पैदा करता है के लिए एक विशिष्ट प्लेटफॉर्म.. आप के लिए अलग से निर्माण की जरूरत है:

  • विंडोज़ एक्स64
  • लिनक्स x64
  • लिनक्स ARM64 (माफ़ॉफ़ॉयर पि)
  • मोलल
  • एमास एपिकॉन

हम बाद में GiHHb क्रिया के साथ इस स्वचालित को कवर करेंगे.

3 निर्माण समय

सेकंड में lOT मशीन कोड के लिए सभी तरह से कंपाइल करने के बजाय। आशा है कि 10 सेकंड के बजाय 2-5 मिनट। यह स्थायी लाभ के लिए एक बार खर्च है।

4. कुछ फीचर अतिरिक्त विन्यास की आवश्यकता है.

JSON सीरियलीकरण, एंटिटी फ्रेमवर्क, और भारी प्रतिबिंब का उपयोग करने के लिए कुछ भी आप स्पष्ट रूप से कंपाइलर बताने के लिए की जरूरत हो सकती है क्या प्रकार रखने के लिए. हम इस कवर को कवर करेंगे.

आपको कब इस्तेमाल करना चाहिए?

एनओटी के लिए सही है:

  • क्लिक किए उपकरण: कमांड लाइन स्कैन जहां तत्काल प्रारंभ होता है
  • माइक्रोफ़ॉर्मेट: छोटा डॉकर छवियों, तेज स्केलिंग में
  • सर्वरलेस/ गैंबिया: ठंडे आरंभ समय आपके बिल को सीधे प्रभावित करता है
  • किनारा औज़ार: राफेवरी पी, ईओटी उपकरणों के साथ कम साधन वाले चित्र
  • गेटवे अनुप्रयोग: विपरीत प्रॉक्सी, एपीआई गेटवे के साथ उच्च हाथों से
  • डेस्कटॉप उपकरण: कोई "विद्विष्टि" कदम के साथ एक एकल जहाज जहाज

इसके लिए एक नमूना छोड़ें:

  • पारंपरिक वेब apps जहां आरंभ समय नहीं होता है
  • अनेक उत्प्रवासन के साथ भारी एंटिटी फ्रेमवर्क का प्रयोग कर रहा है
  • प्लगइन तंत्र जो गतिशील रूप से लोड करता है
  • कोई चीज जो प्रत्यक्ष पर कोड तैयार करती है

जब आप डाटाबेस को जोड़ते हैं तब वहाँ पकड़ लेते हैं जब आप डाटाबेस को जोड़ते हैं - विशेष रूप से विशिष्ट होते हैं.

यु. पू.

अब कि आप समझ में क्या AOT है, चलो एक सबसे बड़ी दर्द बिंदु के बारे में बात करते हैं. यह दीवार सबसे ज्यादा लोगों को हिट है जब डाटाबेस के साथ AOT अनुप्रयोग का उपयोग करने की कोशिश कर रहा है.

क्या होता है (उंटिंग अनुभव)

यहाँ एक आम यात्रा है:

  1. आप जोड़ रहे हैं Microsoft.Data.Sqlite अपनी परियोजना में
  2. आप कॉन्फ़िगर PublishAot=true अपने में .csproj
  3. निर्माण बिना त्रुटियों के पूर्ण है, सब कुछ अच्छा लग रहा है!
  4. आप एक्जीक्यूटेबल चलाते हैं तथा तुरंत मिलता है:
DllNotFoundException: Unable to load DLL 'e_sqlite3' or one of its dependencies

कौन - सी बात आपको देती है?

वैज्ञानिक लाइब्रेरी को समझना (आर्किंग)

समस्या को समझने के लिए, आप के बारे में जानने की जरूरत है %s के लिए दृश्य चुनें: %s.

जी.नेट - यह सी. में लिखा हुआ नहीं है. यह मंच के विशिष्ट देशी कोड के लिए कम्पाइल किया गया है:

  • e_sqlite3.dll विंडोज़ पर
  • libe_sqlite3.so लिनक्स में
  • libe_sqlite3.dylib मेक्स- ओएस

जब आप इस्तेमाल करते हैं Microsoft.Data.Sqlite सामान्य में, यह सिर्फ इस स्थानीय हितन लाइब्रेरी के चारों ओर एक लपेटर है। गतिशील रूप से लोड आपके प्लेटफ़ॉर्म के लिए उचित स्थानीय फ़ाइल.

यह सामान्य के साथ ठीक काम करता है क्योंकि:

  1. बंद कर सकता है
  2. लागू करें पैकेजेस को सभी प्लेटफ़ॉर्म के लिए स्थानीय लाइब्रेरीेस में शामिल कर सकता है
  3. दायाँ एक चुना जाता है एट

ऐसा क्यों?

नेटिव एओटी की दो विशेषताएँ हैं जो वुल्फ के दृष्टिकोण से संघर्ष करती हैं:

1. ए. डी.: किसी भी कोड को हटा देना यह सोचता है कि आप उपयोग नहीं कर रहे हैं. यदि यह स्थिर रूप से साबित नहीं कर सकते हैं आप कुछ साबित हो सकते हैं, तो यह मिटाया जाता है. गतिशील लाइब्रेरी लोड smmer - यह अपने कोड और देशी DL के बीच कनेक्शन नहीं देख सकता.

2. कोई गतिशील लोड समर्थन नहीं: AOT एक स्व-रूपित बाइनरी पैदा करता है. यह सभी देशी निर्भरता की आशा करता है कि स्पष्ट रूप से कंपाइल समय पर जुड़े हुए हों, न कि तेज़ रूप से लोड हो.

परिणाम: Microsoft.Data.Sqlite उम्मीद है कि एक देशी Spacial लाइब्रेरी को बंद पर खोजने की उम्मीद है, लेकिन AOT यह या तो दूर चला गया है या नहीं जानता कि कैसे इसे ठीक से इकट्ठा करने के लिए।

ट्रांसलेटेक्टेक्टेक्टर

इससे भी बुरा, यदि आपके पास अन्य Nuops पैकेज है जो कि श्रोत इस्तेमाल करता है (जैसा कि कुछ ओ पायथन लाइब्रेरी या मेरे मेरे mostlylucid.ephemeral.complete पैकेज, आप अंत कर सकते हैं के साथ बहुत से असंगत प्रबंधन प्रबंधक अपने पेड़ में.

हर प्रदाता अलग से काम करने की कोशिश करता है:

  • कोई उम्मीद कर सकता है कि ओएस- मुद्रा (सिर्फविंडोज़)
  • एक और पहलू जो शायद अपने आप को अलग रखे
  • एक और शायद कोई भिन्न स्थानीय लाइब्रेरी संस्करण इस्तेमाल करे

AOT कंपाइलर जिसके बारे में एक का उपयोग करने के लिए उलझन में पड़ जाता है, और परिणाम यह है कि इसमें से कोई भी शामिल नहीं है - या उससे भी बुरा, परस्पर विरोध फ़ाइलें शामिल हैं जो एक साथ काम नहीं कर सकते.

समाधानः बंडल इस्तेमाल करें

निराशा के घंटों बाद, मुझे हल मिल गया: SQLitePCLRaw.bundle_e_sqlite3. यह एक विशेष Nuop पैकेज है विशेष रूप से AOT के साथ काम करने के लिए बनाया गया है।

जोड़ें ये दो संकुल को:

<ItemGroup>
  <PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.0" />
  <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />
</ItemGroup>

बंडल क्या करता है?

वह bundle_e_sqlite3 पैकेज सामान्य प्रदाता से भिन्न है:

1. इसमें प्रत्येक मुख्य प्लेटफ़ॉर्म के लिए प्री-म्प्ड लाइब्रेरी शामिल हैं:

  • विंडोज़ (x64, x6, ARM64)
  • लिनक्स (x64, ARM64, एम. आई.
  • MCOS (x64 इनलॆल, ARM64 एपिकॉन)

2. ये स्थानीय लाइब्रेरी एक ऐसे तरीके से पैकेज किया जाता है जो AOTCNC को समझने में मदद देता है

अतिसक्रियता चिन्हित करता है इसीलिए एओटी कंपाइलर इन्हें अंतिम द्विचर में शामिल करने के लिए जानता है. कोई गतिशील लोड नहीं है, फ़ाइल के लिए कोई भी खोज नहीं कर रहा है.

3 यह क्रॉस-ब्भ्व निर्माण के लिए बनाया गया है

सभी प्लेटफ़ॉर्म के लिए एक पैकेज काम करता है. आपको प्लेटफ़ॉर्म- विशिष्ट पैकेजों की आवश्यकता नहीं है या वांछित संदर्भों की आवश्यकता नहीं है.

यह क्यों कार्य करता है

हमने जो दो समस्याओं की पहचान की, उसे याद रखें?

समस्या 1: AOT की जाँच की जा रही है लाइब्रेरी इसे इस्तेमाल नहीं किया जा रहा है

  • हल: अलग - अलग जगहों में अपने देश के लाइब्रेरीों को साफ - साफ बताया जाता है कि उन्हें कौन - सी संपत्ति दी जानी चाहिए

समस्या 2: AOT गतिशील लोड का समर्थन नहीं करता है

  • हल:

परिणाम: जब आप विंडोज़ एक्स64 के लिए बिल्ड करते हैं, जो बंडल भी शामिल है e_sqlite3.dll. जब आप लिनक्स ARM64 के लिए निर्माण करते हैं, इसमें 6464 शामिल हैं libe_sqlite3.so.. सब कुछ सिर्फ काम करता है।

गंभीर: बंडल प्रारंभ करें (इसे मत छोड़ें!)

यहाँ हिस्सा है कि 90% लोगों का उपयोग करने की कोशिश कर रहे हैं AOT के साथ , मुझे मेरी पहली कोशिश पर भी.

सामान्य .नेट के साथ, Gocrasphhhhaths अपने आप को पहली बार प्रारंभ करता है आप locent का उपयोग करते हैं. जादू दृश्यों के पीछे होता है - आप कुछ भी करने की जरूरत नहीं है.

नेटिव एओटी के साथ, यह स्वचालित प्रारंभ नहीं करता है. एओटी कंपाइलर स्वचालित प्रारंभ कोड नहीं देख सकता (यह उपयोग किए गए कोड की तरह दिखता है और जाता है) दस्ती रूप से प्रारंभ होना चाहिए आपके अनुप्रयोग के प्रारंभ में जो बंडल है.

यहाँ जादू लाइन आप की जरूरत है:

using SQLitePCL;

public class Program
{
    public static void Main(string[] args)
    {
        // THIS IS CRITICAL: Initialize SQLite FIRST, before ANYTHING else
        SQLitePCL.Batteries.Init();

        // Now you can do normal application setup
        var builder = WebApplication.CreateBuilder(args);

        // This is now safe - SQLite is initialized
        builder.Services.AddDbContext<MyDbContext>(options =>
            options.UseSqlite("Data Source=app.db"));

        var app = builder.Build();
        app.Run();
    }
}

क्या करता है Batteries.Init() क्या करें?

इस विधि में बर्न बंडल को बताता है:

  1. अपने मौजूदा प्लेटफ़ॉर्म के लिए उचित स्थानीय लाइब्रेरी ढूंढें
  2. इसे मेमोरी में लोड करें
  3. के बीच सभी कनेक्शनों को तार करें Microsoft.Data.Sqlite और स्थानीय लाइब्रेरी

इसे "ब्रोटर" कहा जाता है क्योंकि यह "बाटरों में शामिल है"- जो कुछ भी आप की जरूरत है पैकेजित है।

इसे कहाँ रखना है

रखें Batteries.Init() के रूप में पहली पंक्ति अपने में Main विधि, पहले:

  • अनुप्रयोग निर्माता बनाया जा रहा है
  • इंजेक्शन इन्जेक्शन को कॉन्फ़िगर किया जा रहा है
  • डाटाबेस कनेक्शन खोला जा रहा है
  • विन्यास फ़ाइलों को पढ़ा जा रहा है जो जीरोफिक्स का उपयोग कर सकते हैं

इसे चालू करने की कोशिश करने से पहले कल्पना कीजिए । Init(), आप अभी भी मिल जाएगा DllNotFoundException हालांकि डीएल आपके आवेदन में सही तरह से लपेट दिया गया है.

अगर आप भूल जाते हैं, तो क्या होता है?

यदि आप कॉल करना भूल जाते हैं Batteries.Init(), आपका ऐप:

  1. बिल्ड सफलता पूर्वक (जोरल आप चेतावनी नहीं देते)
  2. चल रहा है
  3. क्रैश पल यह के साथ हास का उपयोग करने की कोशिश करता है:
DllNotFoundException: Unable to load DLL 'e_sqlite3' or one of its dependencies

यह इसलिए उलझन में पड़ रहा है क्योंकि डीएल है अपने कार्यक्रम में इकट्ठा, यह सिर्फ आरंभ नहीं है. मैं इस गलती के लिए दो घंटे खो दिया है. मेरे जैसे मत बनो.

परियोजना कॉन्फ़िगरेशन पूर्ण

यहाँ पूरा है .csproj जीरोएल एओटी के साथ बहु- कम्पेटिव एओटी के लिए कॉन्फ़िगर किया गया:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <!-- Native AOT -->
    <PublishAot>true</PublishAot>
    <PublishTrimmed>true</PublishTrimmed>
    <TrimMode>full</TrimMode>
    <InvariantGlobalization>true</InvariantGlobalization>

    <!-- Single File -->
    <PublishSingleFile>true</PublishSingleFile>
    <StripSymbols>true</StripSymbols>

    <!-- Optimization -->
    <OptimizationPreference>Speed</OptimizationPreference>

    <!-- Multi-platform targets -->
    <RuntimeIdentifiers>
      win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64
    </RuntimeIdentifiers>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.0" />
    <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />
  </ItemGroup>

</Project>

कुंजी विन्यास पारिभाषित ( सादा अंग्रेज़ी में)

मुझे इन सभी सेटिंगों को तोड़ने दो:

PublishAot=true

यह मास्टर स्विच है कि इस के बिना, आप सामान्य व्यवहार (JTITIN) मिलता है। इस के साथ, आप आगे प्राप्त प्राप्त प्राप्त प्राप्त करें अपने मूल कोड।

PublishTrimmed=true और TrimMode=full

ये नीचे कहते हैं कि किसी भी कोड को हटाने के लिए जिसे आप इस्तेमाल नहीं कर रहे हैं. इसके बारे में सोचो आगे बढ़ने से पहले अपने फ्लैट साफ करने की तरह - क्यों आप की जरूरत नहीं है?

  • PublishTrimmed=true परीक्षा सक्षम करता है
  • TrimMode=full इसका मतलब है "बेषी, हर चीज़ को हटा देना जो तुम कर सकते हो"

चेतावनी: यह कोड जो भारी प्रतिबिंबों का उपयोग करता है (जैसे कि कुछ JSON श्रृंखला या Opsss) को तोड़ सकते हैं क्योंकि ifmer हमेशा नहीं देख सकता कि आप क्या उपयोग कर रहे हैं। हम इस बाद को कैसे संभाल सकते हैं।

InvariantGlobalization=true

यह आपके ए से सभी संस्कृति- विशिष्ट डाटा को हटाता है - फ़ॉर्मेट, मुद्रा चिह्न, पाठ छंटाई भिन्न भाषाओं के लिए नियम. 5-10MB सहेजने देता है.

सिर्फ इसे सेट करें true यदि आपका ए आईटी:

  • सिर्फ अंग्रेज़ी का प्रयोग करें
  • संस्कृति- विशिष्ट तिथि/ समय फ़ॉर्मेटिंग की आवश्यकता नहीं है
  • सिर्फ वाक्यांश या प्रसंग प्रयोग करें (t)

यदि आप स्थानीयीकरण के बारे में एक क्लिकआई उपकरण या एपीआई गेटवे निर्माण कर रहे हैं, तो यह मुफ़्त बचत है. यदि आप कुछ बना रहे हैं जो फ्रांसीसी उपभोक्ताओं या किसी प्रकार तुर्की पाठ के लिए तिथियों को सही रूप में फ़ॉर्मेट करने की जरूरत है, इस सेटिंग को छोड़ दें.

PublishSingleFile=true

प्रत्येक वस्तु को एक एक्जीक्यूटेबल फ़ाइल में दिखाता है. @ info: whatsthis

myapp.exe
myapp.dll
System.Text.Json.dll
... 50 more files

तुम बस मिलता है:

myapp.exe

तैनाती के लिए बहुत आसान है.

StripSymbols=true

डिबग मदद आप चर नाम या पंक्ति संख्या को दिखाएँ जब डिबगिंग रूप में काम कर रहे हो. वे विकास के दौरान उपयोगी हैं लेकिन बहुत से सहारा लें अपने अंतिम द्विचर में.

यह व्यवस्था उन्हें हटा देती है ।

OptimizationPreference=Speed

यह निर्णय करते समय पहले क्या करने के लिए सत्यापन बताता है:

  • Speed: इसे तेजी से बनाओ (बिल्कुल बड़ा, लेकिन बेहतर प्रदर्शन)
  • Size: इसे छोटा बनाओ (हल आसान है, लेकिन छोटा बाइनरी आकार)

अधिकांश अनुप्रयोगों के लिए, Speed आम तौर पर आकार केवल 2-3MB होता है, लेकिन प्रदर्शन में जो फर्क होता है, उसे नज़रअंदाज़ किया जा सकता है ।

RuntimeIdentifiers

यह घोषणा करता है कि कौन सा मंच आप समर्थन करना चाहते हैं. यह उन्हें नहीं बनाता - यह सिर्फ उपकरण बताता है "ये सही लक्ष्य हैं."

उपलब्ध पहचानकारक:

  • win-x64: विंडोज़ 64- बिट (यूलाला/एम)
  • win-arm64: विंडोज़ 6464 (सबसे, आदि)
  • linux-x64लिनक्स 64- बिट (यूम्बी, डेबियन, आरएचएल, आदि.)
  • linux-arm64: लिनक्स DARM64 (मार्च 4/5, AWSFestton)
  • osx-x64: मैक्लेल (नए मैकल्स)
  • osx-arm64: एमएसएस- एपिकॉन (एम2/M2 मैकेस)

आप एक प्लेटफ़ॉर्म एक समय में उपयोग कर dotnet publish -r linux-x64उदाहरण के लिए ।

बहुत से प्लेटफ़ॉर्मों के लिए निर्माण

याद रखें कि कैसे मैंने कहा कि एओटी को मंच- विशिष्ट निर्माण की जरूरत है? आपको विंडोज, लिनक्स x64, लिनक्स, लिनक्स $164 के लिए अलग से अलग करने की जरूरत है, MSCOSCTCon, और MSTCTCTCon. इस तरह से करना होगा - लेकिन हम इसे स्वचालित बना सकते हैं.

Git क्रिया क्या है?

यदि आप परिचित नहीं हैं, तो GiHb क्रिया एक मुक्त सी आई/सीडी (CACyyyyysy) सेवा है जो किरब में बनाया गया है. यह आप जब भी कोड को धक्का देने या एक रिलीज टैग बनाने देता है.

इसके बारे में सोचिए कि यह एक निर्माण सर्वर है कि:

  1. अपनी GiB सेमी भंडार की निगरानी करें
  2. जब आप एक टैग को धक्का देते हैं v1.0.0
  3. यह स्वचलित विंडोज, लिनक्स तथा एमएसएस आभासी मशीनों को चलाता है
  4. सभी समानांतर इंच के लिए आपका app बनाता है
  5. संलग्न सभी बाइनरी के साथ GiB से जारी करता है

यह सब GiHhb के सर्वर पर चला जाता है - आप किसी भी इन्फर्जन को बनाए रखने की जरूरत नहीं है. खुले स्रोत परियोजनाओं और छोटे निजी परियोजनाओं के लिए, यह पूरी तरह से मुक्त है.

पूरा काम फूलों की तरह हो जाता है

यहाँ एक Girb क्रिया है जो सभी मुख्य मंचों के लिए बनाता है कि:

name: Build Native AOT Binaries

on:
  push:
    tags:
      - 'v*'

jobs:
  build-binaries:
    name: Build ${{ matrix.runtime }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            runtime: linux-x64
            artifact-name: myapp-linux-x64

          - os: ubuntu-latest
            runtime: linux-arm64
            artifact-name: myapp-linux-arm64

          - os: windows-latest
            runtime: win-x64
            artifact-name: myapp-win-x64

          - os: macos-latest
            runtime: osx-x64
            artifact-name: myapp-osx-x64

          - os: macos-latest
            runtime: osx-arm64
            artifact-name: myapp-osx-arm64

    steps:
    - uses: actions/checkout@v4

    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: '9.0.x'

    - name: Install ARM64 tools (Linux ARM64 only)
      if: matrix.runtime == 'linux-arm64'
      run: |
        sudo apt-get update
        sudo apt-get install -y clang zlib1g-dev gcc-aarch64-linux-gnu

    - name: Publish
      shell: bash
      run: |
        # Set objcopy for ARM64 cross-compilation
        if [ "${{ matrix.runtime }}" = "linux-arm64" ]; then
          OBJCOPY_PARAM="-p:ObjCopyName=aarch64-linux-gnu-objcopy"
        else
          OBJCOPY_PARAM=""
        fi

        dotnet publish \
          -c Release \
          -r ${{ matrix.runtime }} \
          --self-contained \
          --output ./publish/${{ matrix.runtime }} \
          -p:PublishAot=true \
          -p:PublishTrimmed=true \
          -p:StripSymbols=true \
          $OBJCOPY_PARAM

    - name: Create distribution package
      shell: bash
      run: |
        mkdir -p ./dist
        cd ./publish/${{ matrix.runtime }}

        # Copy the main executable
        cp myapp${{ matrix.file-ext }} ../../dist/

        # CRITICAL: Copy native libraries (SQLite and any other native dependencies)
        # PublishSingleFile bundles .NET code, but native DLLs remain separate
        cp *.dll ../../dist/ 2>/dev/null || true
        cp *.so ../../dist/ 2>/dev/null || true
        cp *.dylib ../../dist/ 2>/dev/null || true

        # Copy config files if needed
        cp ../../appsettings.json ../../dist/ || true

        cd ../../dist

        # Create archive with all files
        if [ "${{ runner.os }}" = "Windows" ]; then
          7z a -tzip ../${{ matrix.artifact-name }}.zip *
        else
          tar czf ../${{ matrix.artifact-name }}.tar.gz *
        fi

    - name: Upload artifact
      uses: actions/upload-artifact@v4
      with:
        name: ${{ matrix.artifact-name }}
        path: |
          ${{ matrix.artifact-name }}.zip
          ${{ matrix.artifact-name }}.tar.gz
        retention-days: 7
        if-no-files-found: ignore

यह कार्य कैसे कार्य करता है ( चरण द्वारा क़दम तक)

YAएमएल भयभीत लग रहा है, यहाँ यह स्पष्ट अंग्रेज़ी में क्या करता है:

1 ट्रिगर (. ट्रिगर)on: push: tags)

काम फ्लोज दौड़ता है जब आप एक Git टैग को धक्का देते हैं कि इससे प्रारंभ होता है v (की तरह v1.0.0, v2.3.1छोड़ने वाले संस्करण को चिन्हित करने के लिए यह मानक तरीका है.

2. आयामी कौशल

यह चतुर हिस्सा है । मैट्रिक्स बनाने काः

  • प्रत्येक बिल्ड एक अलग हो जाता है os (रक्षार मशीन) और runtime (प्रायंश मंच)
  • GiHHW क्रिया सभी पांच उत्पादन चलाता है समानांतर
  • प्रत्येक स्रोत एकीकरण उत्पन्न करता है (अनुप्रयोगात्मक द्विचर)

तो जब आप धक्का v1.0.0, Git को एक साथ:

  • लिनक्स x64 तथा 6464 बनाने के लिए एक उबुन्टू मशीन को स्पिनित करता है
  • विंडोज एक्स64 के निर्माण के लिए एक विंडोज़ मशीन स्पिन
  • MCSUS X64 और 6464 निर्माण के लिए एक एमएस मशीन चलाता है

हर बिल्ड में 3 कदम

प्रत्येक मंच बनाने के लिए एक ही कदम:

  1. जाँच बाहर कोड: भंडार से अपना श्रोत कोड प्राप्त करें
  2. सेटअप .नेटटी: संस्थापित करें .NT 9 SKS
  3. ARM64 औज़ार संस्थापित करें (लिनक्स464 केवल): क्रास- कम्प्लीशन औज़ार संस्थापित करता है
  4. प्रकाशन: भागो dotnet publish उस विशिष्ट मंच के लिए फ्लैग
  5. अपलोड क़िस्म:: कम्पाइलर बाइनरी को सहेजता है ताकि अगला कार्य इसे एक्सेस कर सके

4 परिणाम.

सभी उत्पादन पूरा होने के बाद आपके पास 5 वस्तुएँ (द्विष्टि) हैं BAR आप इन्हें क्रियाएँ चलाने से डाउनलोड कर सकते हैं, या एक दूसरा काम का उपयोग कर सकते हैं जो कि GiHWWK रिलीज को स्वचलित तैयार करता है (इस में दिखाया नहीं गया है, लेकिन जोड़ने के लिए आसान है BAR

गंभीर: अवैध लाइब्रेरी शैक्षिक नहीं

यहाँ कुछ है जो मुझे घंटों के लिए उलझन में डाल दिया है: PublishSingleFile=true सिर्फ ग्रेड-स्तर .नेटटी कोड. नेटिव लाइब्रेरी जैसे e_sqlite3.dll अलग रहो.

यह इसलिए है कि " वितरण पैकेज" चरण इतना महत्वपूर्ण है:

# Copy native libraries - these are NOT included in the main executable
cp *.dll ../../dist/ 2>/dev/null || true    # Windows
cp *.so ../../dist/ 2>/dev/null || true     # Linux
cp *.dylib ../../dist/ 2>/dev/null || true  # macOS

वह 2>/dev/null || true भाग का अर्थ है "यदि इस पैटर्न से मेल खाता कोई फ़ाइल नहीं है, तो नहीं असफल हो जाओ - बस जारी रखें." यह सभी मंच पर एक ही स्क्रिप्ट कार्य करता है.

और जो कुछ तुम छिपाकर करते हो

  • विंडोज़: myapp.exe + e_sqlite3.dll (संगीत में एक साथ वर्गीकृत)
  • लिनक्सः myapp + libe_sqlite3.so (ब्लू.gz)
  • कोढ़: (S) myapp + libe_sqlite3.dylib (ब्लू.gz)

उपयोक्ता जो अभिलेख खींच रहे हैं तथा चलाने लायक नहीं है. देशी लाइब्रेरी चलाने लायक एक्जीक्यूटेबल के बगल में है, और यह स्वचालित रूप से चालू होने पर पाया जाता है.

क्यों मैनुअल लेना फायदेमंद है

ध्यान दें workflow_dispatch शीर्ष पर ट्रिगरः

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to publish'
        required: true

यह आपको GHHHHh के वेब इंटरफेस को बिना किसी टैग को दबाने के लिए दस्ती रूप से तैयार करता है. कार्य फ्लोवेशन या निर्माण के लिए उपयोगी बनाता है.

6464 क्रास- कैम्प्शन

लिनक्स464 बिल्ड विशेष ध्यान की आवश्यकता है. आपको क्रास- ट्रैकिंग औज़ारों की आवश्यकता है तथा सही उल्लेखित करना होगा. objcopy औज़ार:

# Install tools
sudo apt-get install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu

# Build with objcopy specified
dotnet publish \
  -r linux-arm64 \
  -p:PublishAot=true \
  -p:ObjCopyName=aarch64-linux-gnu-objcopy

के बिना ObjCopyName पैरामीटर, लिंक जो अपरिचित फ़ाइल प्रारूप के बारे में चिल्लार त्रुटि के साथ असफल.

वास्तविक विश्‍व परिणाम

यह एक वास्तविक परियोजना है जिसे आप कर सकते हैं Git विंडो से डाउनलोड करें.

द्विचर आकार ( वास्तविक GiB से जारी)

ये हैं वास्तविक फ़ाइल आकार मेरे GiB रिहाई से, अनुमानित अनुमान नहीं:

ALLLPREALLLLLYEALALLLLLDYEALLALLL( 2000) |----------|-----------|-------------------|-------------------| IMTAN x64 ("1. 2MB+1. 7MB6) 10.9MB (ZZP) 1999- 2006 IMSIX x64 ("1.8MB+1. 6MB साझी 12.4MB (tar.gz) INVI लिनक्स ARM64 ("1. 9MB+1. 5) 11.4MB (tar.gz) IMSUCTICONT 11.2MB + 1. 8MBMB होगे 13.0MB (tar.gz) IMSUCTIS ARM6498.8MB + 1. 7MB6) 11.5MB (tar.gz)

इस की तुलना अपने आप को खाली करने के लिए 9 तैनात करने के लिए करें 130150 प्रति मंच परहम एक के बारे में बात कर रहे हैं आकार में 10- 12x कटौती.

कमी:

  • मुख्य एक्जीक्यूटेबल: आपकी कम्पाइल्ड कोड + . newest (AT- tw)
  • नेटिव डीएल: फ्रेक्ट डाटाबेस इंजिन (सी में लिख दिया)

दोनों फ़ाइलें एक साथ वितरित की जानी चाहिए, लेकिन वे अभी भी पारंपरिक की तुलना में नाटकीय रूप से छोटे हैं.

परफ़ॉर्मेंसComment

ठंडा प्रारंभ (पहले निवेदन्ड) एक सादा लिनक्स वीपीएस में:

  • स्व-स्थ्ड .: ~ 800ms
  • नेटिव एटी: ~150ms
  • सुधार: 81% तेजी से

यह बात बहुत बड़ी है:

  • सर्वरलेस/ दिलाने के कार्य (आप प्रति भुगतान करते हैं)
  • समाहित कर्ताweather forecast
  • CLI उपकरण जहाँ हर प्रार्थना को ताजा करना शुरू होता है

मेमोरी उपयोग

खाली स्मृति (तैयार, कोई ट्रैफिक नहीं):

  • स्व-स्थ्ड .: 85MB
  • नेटिव एटी: 42MB
  • सुधार: 51% कमी

लोड करने के लिए (1000 निवेदन/सेकेंड):

  • स्व-स्थ्ड .: ~SMB
  • नेटिव एटी: ~180MB
  • सुधार: 44% कमी

निचली मेमोरी का अर्थ है:

  • प्रति होस्ट में अधिक कंटेनर
  • चेरावर बादल के बिल
  • संसाधन-चित उपकरणों पर कमी (शाइफ़ॉयर पी, आईओटी)

कॉमन पिस्ट्स

1. भुलाने के लिए Batteries.Init()

यह # गलती है. यह भी सही तरह से इस्तेमाल किया गया टुकड़ा के साथ, कॉल करने के लिए भूल गया SQLitePCL.Batteries.Init() आपके बारे में बहुत ही प्रारंभ में Main विधि क्रैश हो जाएगा.

सही अनुवादः

public static void Main(string[] args)
{
    SQLitePCL.Batteries.Init(); // FIRST LINE
    // ... rest of your code
}

2. अतिरिक्‍त लाइब्रेरी को विकृत नहीं किया जा सकता

यह गलती # 2 है, और यह मुझे दो बार मिल गया है. PublishSingleFile=true आपके एक्जीक्यूटेबल में खाली हैडरर नहीं है. आपको इन्हें अपने एक्जीक्यूटेबल के साथ वितरित करना होगा.

अगर आप भूल जाते हैं तो क्या होता है:

  • आपका ऐप बिल्डर ठीक
  • यह आपके डेवी मशीन पर ठीक से चलता है (जहाँ '/' पहले से संस्थापित हो सकता है)
  • यह उत्पादन के साथ क्रैश हो जाता है DllNotFoundException

सही अनुवादः

जब आप अपनी रिहाई का उपयोग करते हैं, तो हमेशा शामिल कीजिए:

myapp.exe               # Your main executable
e_sqlite3.dll           # SQLite native library (Windows)
# or libe_sqlite3.so    # SQLite native library (Linux)
# or libe_sqlite3.dylib # SQLite native library (macOS)

अपने GiHब क्रियाएँ या तैनात स्क्रिप्ट में:

# Copy ALL native libraries from the publish directory
cp *.dll ./dist/ 2>/dev/null || true
cp *.so ./dist/ 2>/dev/null || true
cp *.dylib ./dist/ 2>/dev/null || true

उपयोक्ता को अभिलेख निकाली जानी चाहिए तथा चलाने चाहिए. देशी लाइब्रेरी को उसी डिरेक्ट्री में होना चाहिए.

3 का उपयोग कर रहा है. winsqlite3 प्रदाता

आप उपयोग करने के लिए सिफारिशों को देख सकते हैं SQLitePCLRaw.provider.winsqlite3 ओएस- सोर्स प्रयोग करने के लिए विंडोज़ पर. यह सिर्फ विंडोज़ पर काम करता है, मैनुअल प्रारंभ होता है, तथा क्रास- डिफॉर्मेशन प्रोटेस्टंट बनाता है. के साथ जारी रखें. bundle_e_sqlite3.

4. EF कोर के साथ ट्रॉम चेतावनियाँ

यदि आप पा रहे हैं एंटिटी फ्रेमवर्क का उपयोग कर रहे हैं, आप smmmm चेतावनी मिलेगी (I2026, IL3050). ये आम तौर पर EF कोरस के एएस(GERSRRServerters) के लिए दबाने के लिए सुरक्षित हैं, लेकिन अच्छी तरह से परीक्षण कर रहे हैं:

<PropertyGroup>
  <NoWarn>$(NoWarn);IL2026;IL3050</NoWarn>
</PropertyGroup>

बेहतर है, फिर भी, Dappapper या रॉ एड. AOTiT अनुप्रयोग के साथ lociT, वे अधिक AOTTT-TTy रहे हैं.

5. गुम दृष्टिडिओ औजार (विंडोज़)

विंडोज़ पर, नेटिव एओटी को दिखाई देने की जरूरत है MrovC लिंकर. यदि आप एक डेवलपर कमांड संकेत के बाहर निर्माण करते हैं, आप के बारे में त्रुटियाँ प्राप्त करेंगे vswhere.exeGithb क्रिया इसे स्वचालित संभालती है, लेकिन स्थानीय निर्माण के लिए:

  • VS 2022 के लिए डेवलपर कमांड संकेत
  • VS 2022 के लिए विकासकर्ता शक्तिशेल

या फिर आपके बिल्ड स्क्रिप्ट में वातावरण प्रारंभ करें:

& "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64
dotnet publish -c Release -r win-x64

जब हाल ही में कहा जाता है

एनओटी के लिए सही है:

  • क्लिक किए उपकरण: तत्काल प्रारंभ समय
  • माइक्रोफ़ॉर्मेट तथा कंटेनर: छोटी तस्वीरें, तेजी से स्केलिंग
  • किनारा औज़ार: राफेवरी पी, ईओटी उपकरणों के साथ कम साधन वाले चित्र
  • सर्वरलेस/ गैंबिया: शीत प्रारंभ समय गंभीर है
  • गेटवे/ प्राक्सी अनुप्रयोग: हाई के ज़रिए, कम सिर से नीचे

इस बारे में सोचिए:

  • भारी एंटिटी फ्रेमवर्क कोर प्रयोग
  • विजुअल अनुप्रयोगों का विश्लेषण करें
  • गतिशील प्लगइन तंत्र
  • अनुप्रयोग की आवश्यकता है कि कोड पीढ़ी

क्विक प्रारंभ हेतु जांचसूची

आप इस पूरे पोस्ट को पढ़ा है और सिर्फ एक चेक करना चाहते हैं, यहाँ तुम जाओ:

1 से. पैकेज जोड़ें:

<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.0" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />

2 कॉन्फ़िगर करें.... .csproj एओटी के लिए:

<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>full</TrimMode>
<InvariantGlobalization>true</InvariantGlobalization>
<PublishSingleFile>true</PublishSingleFile>
<StripSymbols>true</StripSymbols>
<OptimizationPreference>Speed</OptimizationPreference>

3 आपके शुरू होने पर गंभीरता से जाँच कीजिए Main विधि:

SQLitePCL.Batteries.Init();

अपने लक्ष्य के लिए बिल्ड करें:

dotnet publish -c Release -r linux-x64 --self-contained

5. अपने द्विचर को जाँचो, यह सिर्फ निर्भरता के साथ चलता है!

कंटेनमेंट

वैज्ञानिक एओटी के साथ काम करना स्पष्ट नहीं है, लेकिन एक बार आप जादू पता है -SQLitePCLRaw.bundle_e_sqlite3 + Batteries.Init()- यह सीधा है। भुगतान बहुत आसान है: छोटे पैमाने पर, तत्काल स्टार्टअप, और बिना किसी मंच पर तैनात करने की क्षमता।

किसी भी निर्माण उपकरण के लिए CONI उपकरण, गेटवे या किनारे अनुप्रयोग के लिए, नेटिव एओटी के साथ अब एक वास्तविक विकल्प है. GitHT कार्य यहाँ प्रदान किया गया पूरी विविध निर्माण प्रक्रिया - बस एक रिलीज और आप कर रहे हैं.

यदि आप AOT के लिए नया कर रहे हैं, छोटे से आरंभ: एक सरल COI उपकरण या यूटिलिटी बदलने के लिए। निर्माण प्रक्रिया के साथ आराम से जाओ, क्या चेतावनी की उम्मीद है, और सीमाओं को समझने के लिए। एक बार जब आप बुनियादी नीचे मिल गया है, आप और अधिक जटिल अनुप्रयोगों का सामना कर सकते हैं।

.EEENT पर्यावरण अधिक AOTT-टी. अधिकांश आधुनिक पुस्तकालय या तो बॉक्स से बाहर काम करते हैं या AOT समर्थन पर स्पष्ट दस्तावेज़ हैं. भविष्य देशी है, और यह आप से भी तेजी से है.

वास्तविक क्षमा - प्राप्त अनुभव

मैं करने के लिए अपने एटी-फोन द्वार तैनात करता हूं:

  • डिजिटल महासागर छोड़ें (लिनक्स-64) - एक तंत्र सेवा के रूप में चलाता है
  • राप्नी पी 5 (लिनक्सARM64) - जाँच के लिए किनारा तैनाती
  • विंडोज़ सर्वर (विंडो x64) - एक विंडोज़ सेवा के रूप में चलाता है
  • खर कंटेनर - x64 और 6464 भिन्नताओं दोनों

तैनातिंग प्रक्रिया हर जगह एक समान है:

  1. "%s" से अभिलेख डाउनलोड करें
  2. इसमें निकालें
  3. एक्जीक्यूटेबल चलाएँ

कोई "विद्वीव करें" कदम ". कोई हल नहीं नरक. कोई संस्करण संघर्ष नहीं केवल बाहर और चलाने के लिए.

डॉकर के लिए, मेरे लिए Dockerfile लज्जाजनक है:

FROM debian:bookworm-slim

# Copy just the two files we need
COPY minigw /app/minigw
COPY libe_sqlite3.so /app/libe_sqlite3.so

WORKDIR /app
RUN chmod +x minigw

EXPOSE 5000
ENTRYPOINT ["./minigw"]

परिणाम छवि है ~130MB (सबसे बेस डेबियन छवि) एक पारंपरिक कंटेनर 200-2MB होगा.

पूर्ण कार्यशील उदाहरण

जो कुछ मैंने यहाँ दिखाया है वो वास्तविक है, उत्पादन की तैयारी से. आप कर सकते हैं:

परियोजना एक छोटा सा YarP प्रॉक्सी को बॉटर के साथ पलटता है जो कि वीडियो हस्ताक्षर के लिए लॉग हस्ताक्षर करता है. यह प्रदर्शित करता है:

  • वुल्फहाउंड के साथ नेटिव एओटी
  • Git Git क्रियाओं के द्वारा बहु- डिफॉर्मेशन बनाता है
  • नेटिव लाइब्रेरी ब्रीलिंग
  • क्लिक किए गए तर्क पारसिंग
  • स्ट्रक्चर्ड लॉगिंग
  • विंडो बन्द करें (l)

एक व्यक्‍ति इसका अध्ययन करता है, इसे अपने आप के लिए एक टैम्प्लेट के रूप में इस्तेमाल करें ।

संसाधन

अब थोड़ा और तेजी से कुछ बनाने के लिए जाओ.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.