این یک پست مهمان از ویکتور پترسون ، مدیرعامل Screenly.io است. Screenly محبوب ترین محصول علامت گذاری دیجیتال برای Raspberry Pi است. ویکتور را در توییترvpetersson بیابید.
برای کسانی که با Qt آشنا نیستند ، این یک چارچوب توسعه بین پلتفرمی است که در طیف وسیعی از محصولات از جمله اتومبیل (تسلا) ، علائم دیجیتال (Screenly) و هواپیما استفاده می شود ( لوفت هانزا). نیازی به گفتن نیست که Qt بسیار قدرتمند است. با این حال ، چیزی که نمی توانید در مورد چارچوب Qt بگویید این است که تدوین آن آسان است – حداقل برای دستگاه های تعبیه شده تعداد بیشماری از وبلاگ ها ، بخشهای انجمن و پستهای Stack Overflow در این موضوع نشان می دهد که گردآوری Qt یک سردرد معمول است.
ما به عنوان کاربران طولانی مدت Qt ، در Screenly سهم خوبی از نبردها با آن داشته ایم. ما چندین سال پیش برای نرم افزار تجاری علامت گذاری دیجیتال به Qt مهاجرت کردیم و از آن زمان به بعد ، هم از عملکرد و هم از انعطاف پذیری آن بسیار راضی بوده ایم. اخیراً ، ما تصمیم گرفتیم که نرم افزار علامت گذاری دیجیتال منبع باز (Screenly OSE) خود را نیز به Qt منتقل کنیم. از آنجا که این پروژه ها فاقد کد هستند ، این یک فرصت سبز است که به ما امکان می دهد از نو شروع کنیم و فن آوری های جدید مهیج را برای فرآیند ساخت کشف کنیم.
زیرا کامپایل Qt (و QtWebEngine) یک عملیات سنگین بسیار است ، ما باید Qt را از قبل کامپایل و توزیع کنیم تا Dockerfile بتواند آن را به سادگی بارگیری و در فرآیند ساخت قرار دهد (نه اینکه به عنوان بخشی از مراحل نصب کامپایل شود).
ما نشستیم و شرایط زیر را برای خود ایجاد کردیم روند ساخت:
- روند باید از ابتدا تا انتها کاملاً اتوماتیک باشد.
- ما باید بتوانیم Qt / QtWebEngine را برای همه صفحه های Raspberry Pi پشتیبانی شده (با Qt مناسب
بسازیم) نمایه دستگاه. - برای سرعت بخشیدن به روند کار در صورت منطقی بودن ، باید از تلفیق متقابل x86 استفاده کنیم.
- ما باید بتوانیم روند کامل را روی CI اجرا کنیم و بنابراین نمی توانیم به Raspberry اعتماد کنیم. پی.
- ما باید همه را محدود کنیم برای اجرای درون کانتینرهای Docker بنابراین ما میزبان را با بسته های ساختمانی شلوغ نمی کنیم.
با در نظر داشتن اهداف فوق ، فرصتی عالی برای امتحان کردن پشتیبانی جدید چند سکویی در Docker داشتیم. همراه با ساخت های چند مرحله ای ، ما توانستیم بهترین نتیجه را از هر دو جهان بدست آوریم:
- در مواردی که نمی توانیم تلفیق کنیم
- از شبیه سازی استفاده کنید
برای جمع آوری سنگین به مجموعه تلفیقی بروید
چگونه چند پلت فرم در کار Docker؟
ساده ترین راه برای استفاده از قابلیت های چند سکویی در Docker فراخوانی آن از خط فرمان است. با استفاده از docker buildx ، می توانیم از ویژگی های جدید بتا استفاده کنیم. با اجرای docker buildx build --platform linux / arm / v7 -t arm-buil d. این دستور با استفاده از شبیه سازی ARMv7 ، تصویر docker را همانند `Dockerfile` در فهرست فعلی ایجاد می کند. در پشت صحنه ، داکر کل مراحل ساخت داکر را در یک محیط مجازی QEMU اجرا می کند (به طور دقیق [ qemu-user-user-static ). با این کار ، پیچیدگی تنظیم یک ماشین مجازی سفارشی برطرف می شود. پس از ساخت ، حتی می توانیم از docker run برای راه اندازی کانتینرها در حالت ARMv7 به صورت اتوماتیک استفاده کنیم.
چند سکویی ، چند مرحله ای و Qt
در حالی که عملکرد چند سکویی یک ویژگی مستقل عالی است ، وقتی با ساختهای چند مرحله ای ترکیب شود ، از قدرت بیشتری نیز برخوردار می شود. در یک Dockerfile ، ما می توانیم سیستم عامل ها را با هم مخلوط کرده و بین مراحل کپی کنیم. این قابلیت دقیقاً همان چیزی است که ما در نهایت با ساخت Qt برای Screenly OSE انجام دادیم.
مرحله 1: ARM
با تشکر از افراد خوب در Balena ، ما قادر به استفاده از Raspbian هستیم تصویر پایه در مرحله اول. ما می توانیم این مرحله را با استفاده از:
FROM --platform = linux / arm / v7 balenalib / rpi-raspbian: buster as builder
فراخوانی کنیم ] دستورات RUN ، مانند نصب بسته ها و غیره. توجه داشته باشید که اگر ساخت در سخت افزار ARMv7 اجرا نشود ، این ظرف با استفاده از QEMU شبیه سازی می شود. در مورد ما ، از دستور برای نصب وابستگی های ساخت Qt استفاده می کنیم. مرحله فوق همچنین به ما امکان می دهد تا به طور کامل نیاز به کپی کردن فایلها را از یک تصویر دیسک (آنچه Qt Wiki پیشنهاد می کند) یا rsync از یک Raspberry Pi فیزیکی کاملاً برطرف کنیم.
مرحله 2: x86
پس از نصب وابستگی های خود در مرحله ARM ، می توانیم به معماری x86 سازنده برویم تا از شبیه سازی جلوگیری کنیم و کامپایل متقابل را با خط زیر انجام دهیم:
FROM --platform = linux / amd64 debian: buster
اکنون ، ما وارد قسمت جالب هستیم. بعد از اینکه ما به x86 تغییر دادیم ، می توانیم فایل های مرحله قبل را کپی کنیم. این کار را برای ایجاد sysroot انجام می دهیم که بتوانیم از آن برای Qt استفاده کنیم. این مرحله را با اجرای دستورات زیر کامل می کنیم:
RUN mkdir -p / sysroot / usr / sysroot / opt / sysroot / lib
COPY - از = سازنده / lib / / sysroot / lib /
COPY - از = سازنده / usr / شامل / / sysroot / usr / شامل /
COPY - از = سازنده / usr / lib / / sysroot / usr / lib /
COPY - از = سازنده / opt / vc / sysroot / opt / vc /
اکنون ما بهترین های هر دو جهان را داریم. با بهره گیری از قابلیت های چند مرحله ای و چند پلتفرمی ، ما sysroot تولید می کنیم که می توانیم برای ساخت Qt از آن استفاده کنیم. از آنجا که ما در مرحله قبلی خود از یک تصویر Raspbian کاملاً کاربردی استفاده کرده ایم ، حتی می توانیم Qt را برای جمع آوری همه کتابخانه های موجود بدست آوریم.
./ configure
-sysroot / sysroot
همانطور که در مقدمه ذکر کردیم ، کامپایل Qt خیلی ساده نیست. مراحل زیادی برای تدوین موفقیت آمیز آن لازم است. برای کسب اطلاعات بیشتر در مورد مراحل دقیق ، می توانید Dockerfile کامل و اسکریپت build_qt5.sh را مشاهده کنید.
الگوبرداری یا تقلید نکردن …
توانایی تقلید از سکویی مانند ARM شگفت آور است و انعطاف پذیری زیادی را فراهم می کند. با این حال ، این هزینه دارد. مجازات عملکرد بزرگی وجود دارد. این مسئله دلیل آن است که ما در واقع Qt را با استفاده از شبیه سازی کامپایل نمی کنیم. در عوض ، ما از تلفیق متقابل استفاده می کنیم. اگر به جای تقلید توانایی کامپایل متقابل را دارید ، بدانید که تلفیق متقابل عملکرد بسیار بهتری را به شما ارائه می دهد.
About Screenly
Screenly محبوب ترین محصول علامت گذاری دیجیتال برای Raspberry Pi است. اگر می خواهید یک صفحه فیزیکی را به یک دستگاه ایمن و قابل کنترل از راه دور (از طریق رابط کاربر یا API علامت دیجیتال) تبدیل کنید که می تواند داشبورد ، تصاویر ، فیلم ها و صفحات وب را نمایش دهد ، Screenly باعث می شود تنظیمات نسبی باشد. نسخه منبع باز و نسخه تجاری Screenly در دو طعم در دسترس است.