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
Thursday, 12 December 2024
यदि आप जहाज के लिए कोशिश कर रहे हैं एक एकल के रूप में, देशी एक्जीक्यूटेबल अनुप्रयोग, आपने संभवतः पहली बार एओटीत में चेहरे का उपयोग किया है। आप सब कुछ प्राप्त करें, निर्माण सफलता प्राप्त करें, और फिर - bolox-t-twows, और फिर - समय चलाने के साथ क्रैश DllNotFoundException के बारे में त्रुटि e_sqlite3.. मुझे तुम्हें निराशा के घंटे बचाने के लिए मैं के माध्यम से चला गया और आपको सही तरह से दिखाने के लिए...
चलो पूर्ण आधारों के साथ शुरू करते हैं. यदि आप कभी एक निर्माण अनुप्रयोग बनाया है और आश्चर्य है कि क्यों आप सर्वर पर ".नेट रन समय" स्थापित करने की जरूरत है या क्यों अपने चैन एओ एओ एओ एओ एओए उन समस्याओं का जवाब है.
जब आप C# कोड लिखते हैं और अपने अनुप्रयोग का निर्माण करते हैं, वे सत्यापन मशीन कोड नहीं बनाते जो आपका सीपीयू सीधे कार्य कर सकता है. इसके बजाय, यह कुछ भी उत्पन्न करता है जिसे बुलाया जाता है. इंटरेक्शन भाषा (आईएल)— इसकी गंभीरता आपके C# कोड और वास्तविक मशीन निर्देशों के बीच में है.
जब आप अपने .NET ऐप चलाने के लिए, यहाँ क्या होता है:
यह एक अनुवादक है जो अपनी रेसिपि (IL) को पढ़ता है और इसे लाइन में अनुवाद करता है जब वे खाना पकाने के दौरान. यह काम करता है, लेकिन वहाँ मुख्य है:
नेटिव एओटी इस मॉडल को उसके सिर पर घुमाता है. अपने कोड का अनुवाद कम से कम करने के बजाय, यह सब कुछ का अनुवाद करता है बिल्ड समय. आप एक एकल एक्जीक्यूटेबल फ़ाइल के साथ अंत है जिसमें आपका सीपीयू कोड सीधे चला सकता है - कोई अनुवादक नहीं, इंतजार नहीं कर रहा है.
इसके बारे में सोचिए कि एक जीवित अनुवादक के बजाय एक पेशेवर रूप से अनुवादित रेसिपि बुक प्राप्त करना ।
यहाँ जो कहा गया एओटी आपको देता है:
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 मशीन कोड पैदा करता है के लिए एक विशिष्ट प्लेटफॉर्म.. आप के लिए अलग से निर्माण की जरूरत है:
हम बाद में GiHHb क्रिया के साथ इस स्वचालित को कवर करेंगे.
3 निर्माण समय
सेकंड में lOT मशीन कोड के लिए सभी तरह से कंपाइल करने के बजाय। आशा है कि 10 सेकंड के बजाय 2-5 मिनट। यह स्थायी लाभ के लिए एक बार खर्च है।
4. कुछ फीचर अतिरिक्त विन्यास की आवश्यकता है.
JSON सीरियलीकरण, एंटिटी फ्रेमवर्क, और भारी प्रतिबिंब का उपयोग करने के लिए कुछ भी आप स्पष्ट रूप से कंपाइलर बताने के लिए की जरूरत हो सकती है क्या प्रकार रखने के लिए. हम इस कवर को कवर करेंगे.
एनओटी के लिए सही है:
इसके लिए एक नमूना छोड़ें:
जब आप डाटाबेस को जोड़ते हैं तब वहाँ पकड़ लेते हैं जब आप डाटाबेस को जोड़ते हैं - विशेष रूप से विशिष्ट होते हैं.
अब कि आप समझ में क्या AOT है, चलो एक सबसे बड़ी दर्द बिंदु के बारे में बात करते हैं. यह दीवार सबसे ज्यादा लोगों को हिट है जब डाटाबेस के साथ AOT अनुप्रयोग का उपयोग करने की कोशिश कर रहा है.
यहाँ एक आम यात्रा है:
Microsoft.Data.Sqlite अपनी परियोजना मेंPublishAot=true अपने में .csprojDllNotFoundException: 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. ए. डी.: किसी भी कोड को हटा देना यह सोचता है कि आप उपयोग नहीं कर रहे हैं. यदि यह स्थिर रूप से साबित नहीं कर सकते हैं आप कुछ साबित हो सकते हैं, तो यह मिटाया जाता है. गतिशील लाइब्रेरी लोड 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. इसमें प्रत्येक मुख्य प्लेटफ़ॉर्म के लिए प्री-म्प्ड लाइब्रेरी शामिल हैं:
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() क्या करें?इस विधि में बर्न बंडल को बताता है:
Microsoft.Data.Sqlite और स्थानीय लाइब्रेरीइसे "ब्रोटर" कहा जाता है क्योंकि यह "बाटरों में शामिल है"- जो कुछ भी आप की जरूरत है पैकेजित है।
रखें Batteries.Init() के रूप में पहली पंक्ति अपने में Main विधि, पहले:
इसे चालू करने की कोशिश करने से पहले कल्पना कीजिए । Init(), आप अभी भी मिल जाएगा DllNotFoundException हालांकि डीएल आपके आवेदन में सही तरह से लपेट दिया गया है.
यदि आप कॉल करना भूल जाते हैं Batteries.Init(), आपका ऐप:
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 यदि आपका ए आईटी:
यदि आप स्थानीयीकरण के बारे में एक क्लिकआई उपकरण या एपीआई गेटवे निर्माण कर रहे हैं, तो यह मुफ़्त बचत है. यदि आप कुछ बना रहे हैं जो फ्रांसीसी उपभोक्ताओं या किसी प्रकार तुर्की पाठ के लिए तिथियों को सही रूप में फ़ॉर्मेट करने की जरूरत है, इस सेटिंग को छोड़ दें.
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. इस तरह से करना होगा - लेकिन हम इसे स्वचालित बना सकते हैं.
यदि आप परिचित नहीं हैं, तो GiHb क्रिया एक मुक्त सी आई/सीडी (CACyyyyysy) सेवा है जो किरब में बनाया गया है. यह आप जब भी कोड को धक्का देने या एक रिलीज टैग बनाने देता है.
इसके बारे में सोचिए कि यह एक निर्माण सर्वर है कि:
v1.0.0यह सब 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 (प्रायंश मंच)तो जब आप धक्का v1.0.0, Git को एक साथ:
हर बिल्ड में 3 कदम
प्रत्येक मंच बनाने के लिए एक ही कदम:
dotnet publish उस विशिष्ट मंच के लिए फ्लैग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)myapp + libe_sqlite3.dylib (ब्लू.gz)उपयोक्ता जो अभिलेख खींच रहे हैं तथा चलाने लायक नहीं है. देशी लाइब्रेरी चलाने लायक एक्जीक्यूटेबल के बगल में है, और यह स्वचालित रूप से चालू होने पर पाया जाता है.
ध्यान दें workflow_dispatch शीर्ष पर ट्रिगरः
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Version to publish'
required: true
यह आपको GHHHHh के वेब इंटरफेस को बिना किसी टैग को दबाने के लिए दस्ती रूप से तैयार करता है. कार्य फ्लोवेशन या निर्माण के लिए उपयोगी बनाता है.
लिनक्स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 रिहाई से, अनुमानित अनुमान नहीं:
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 कटौती.
कमी:
दोनों फ़ाइलें एक साथ वितरित की जानी चाहिए, लेकिन वे अभी भी पारंपरिक की तुलना में नाटकीय रूप से छोटे हैं.
ठंडा प्रारंभ (पहले निवेदन्ड) एक सादा लिनक्स वीपीएस में:
यह बात बहुत बड़ी है:
खाली स्मृति (तैयार, कोई ट्रैफिक नहीं):
लोड करने के लिए (1000 निवेदन/सेकेंड):
निचली मेमोरी का अर्थ है:
Batteries.Init()यह # गलती है. यह भी सही तरह से इस्तेमाल किया गया टुकड़ा के साथ, कॉल करने के लिए भूल गया SQLitePCL.Batteries.Init() आपके बारे में बहुत ही प्रारंभ में Main विधि क्रैश हो जाएगा.
सही अनुवादः
public static void Main(string[] args)
{
SQLitePCL.Batteries.Init(); // FIRST LINE
// ... rest of your code
}
यह गलती # 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
उपयोक्ता को अभिलेख निकाली जानी चाहिए तथा चलाने चाहिए. देशी लाइब्रेरी को उसी डिरेक्ट्री में होना चाहिए.
winsqlite3 प्रदाताआप उपयोग करने के लिए सिफारिशों को देख सकते हैं SQLitePCLRaw.provider.winsqlite3 ओएस- सोर्स प्रयोग करने के लिए विंडोज़ पर. यह सिर्फ विंडोज़ पर काम करता है, मैनुअल प्रारंभ होता है, तथा क्रास- डिफॉर्मेशन प्रोटेस्टंट बनाता है. के साथ जारी रखें. bundle_e_sqlite3.
यदि आप पा रहे हैं एंटिटी फ्रेमवर्क का उपयोग कर रहे हैं, आप smmmm चेतावनी मिलेगी (I2026, IL3050). ये आम तौर पर EF कोरस के एएस(GERSRRServerters) के लिए दबाने के लिए सुरक्षित हैं, लेकिन अच्छी तरह से परीक्षण कर रहे हैं:
<PropertyGroup>
<NoWarn>$(NoWarn);IL2026;IL3050</NoWarn>
</PropertyGroup>
बेहतर है, फिर भी, Dappapper या रॉ एड. AOTiT अनुप्रयोग के साथ lociT, वे अधिक AOTTT-TTy रहे हैं.
विंडोज़ पर, नेटिव एओटी को दिखाई देने की जरूरत है MrovC लिंकर. यदि आप एक डेवलपर कमांड संकेत के बाहर निर्माण करते हैं, आप के बारे में त्रुटियाँ प्राप्त करेंगे vswhere.exeGithb क्रिया इसे स्वचालित संभालती है, लेकिन स्थानीय निर्माण के लिए:
या फिर आपके बिल्ड स्क्रिप्ट में वातावरण प्रारंभ करें:
& "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 समर्थन पर स्पष्ट दस्तावेज़ हैं. भविष्य देशी है, और यह आप से भी तेजी से है.
मैं करने के लिए अपने एटी-फोन द्वार तैनात करता हूं:
तैनातिंग प्रक्रिया हर जगह एक समान है:
कोई "विद्वीव करें" कदम ". कोई हल नहीं नरक. कोई संस्करण संघर्ष नहीं केवल बाहर और चलाने के लिए.
डॉकर के लिए, मेरे लिए 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 प्रॉक्सी को बॉटर के साथ पलटता है जो कि वीडियो हस्ताक्षर के लिए लॉग हस्ताक्षर करता है. यह प्रदर्शित करता है:
एक व्यक्ति इसका अध्ययन करता है, इसे अपने आप के लिए एक टैम्प्लेट के रूप में इस्तेमाल करें ।
अब थोड़ा और तेजी से कुछ बनाने के लिए जाओ.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.