کامپایلهای اتمی کیوت
-
p{direction:rtl; text-align:right}. مقدمه
بالأخره تونستم کیوت پنج رو بهشکل اتمی روی ویندوز کامپایل کنم :) خودم ازش خیلی خوشم اومده. ماکزیمم بهینهسازی ممکن رو اعمال کردم. تستها نشون میده در بعضی موارد حدود چهار برابر بهینهتر شده. زمان اجرای الگوریتمها (مخصوصاً در مورد پردازش متن و عبارات منظم) تا حد باورنکردنی بهبود پیدا کرده. همچنین تمام ابزار مورد استفاده در کامپایل رو از صفر ساختم. MinGW رو برای کامپایل استفاده کردم که کد بهینهٔ متناظر با سختافزار رو میتونه تولید بکنه. همهٔ کتابخانههای پایهای رو از جمله OpenSSL و DBus و کتابخانهٔ خیلی مهم ICU رو با نهایت بهینهسازی برای ۶۴ بیتیهای ویندوز ساختم.
چند قاعدهٔ کلی برای این کار اعمال شده:
۱- تا حد ممکن از ابزارهای مایکروسافت استفاده نشه. مثلاً سیستم پردازش همزمان (لایهٔ زیرین Qt Concurency) Pthread هست. همچنین مکانیسم IPC در اینجا بهجای WMI مبتنیبر POSIX و ابزار Dbus هست. برای SSL از کتابخانهٔ بسیار عالی OpenSSL استفاده کردم و همچنین برای گرافیک از OpenGL بهجای DirectX استفاده شده. به غیر از مورد آخر تمام همارزهای متنباز به مراتب امنتر و کاراتر از نمونههای مایکروسافتی هستند.
۲- تاحد ممکن از کتابخانههای 3rd party استفاده نشده. هر کجا امکانش وجود داشت از پیادهسازیهای داخلی کیوت استفاده کردم. اینطوری خیلی قابلیت حمل بالا میره. اصلا اعتمادی به API های مایکروسافت نیست. مثلاً هیچ تضمینی وجود نداره که کتابخانههای PNG و JPEG و یا ZIP که داخل ویندوز وجود دارن درست و حسابی کار کنن. برای همهٔ اینها از پیادهسازیهای خود کیوت استفاده کردم.
۳- کامپایل پلاگینهای پایگاه داده کار فوقالعاده طاقتفرسا و سختی هست. همچنین نمیشه Oracle رو با MinGW لینک کرد. غیر از اوراکل بقیه رو میشه استفاده کرد. در حال حاضر MySQL – SQLite – SQLite2 -ODBC کامپایل شدن و کار میکنن. همین مقدار برای توسعه نرمافزار کافی هست. در آینده قصد دارم InterBase و IBM DB2 رو هم وارد سیستم کنم.p{direction:rtl; text-align:right}. کارهای در دست انجام
پکیجهایی که میخوام کامپایل کنم به دو دسته تقسیم میشه. یکی متنباز و دیگری مایکروسافت. برای متنباز باز دو دسته داریم. یکی با استفاده از ANGLE و دیگری استفاده از OpenGL. در بقیهٔ موارد کانفیگها یکی هستن. برای کامپایلهای مایکروسافتی از MSVC 2012 استفاده میکنم که فکر کنم مفهومی نداره OpenGL رو واردش کنم. صرفاً با DirectX کامپایلش میکنم.p{direction:rtl; text-align:right}. همهٔ اینها یک بار برای ۳۲ بیتی و یکبار برای ۶۴ بیتی تکرار خواهد شد. پس در کل شش پکیج کیوت خواهیم داشت.
p{direction:rtl; text-align:right}. موارد استفاده
شخصاً فکر میکنم پکیجهای مایکروسافتی به درد بخور نیستن. اصولاً کامپایلر MSVC نمیتونه کد بهدردبخور تولید کنه. کارایی فوقالعاده پایین و حجم باینریها خیلی بالا خواهد بود. پکیجهای متنباز کیوت که با MinGW کامپایل شده باشن خیلی فوقالعاده هستن. منتهی مشکلی که داره اینه که باید تمام DLL هایی که در سیستمهای ویندوز وجود ندارن، اضافه بشن. (قسمت بعدی رو ببینید) این پکیجها میتونن برای توسعهٔ نرمافزارهایی با کارایی بسیار بالا استفاده بشن. خصوصاً کاربردهای تجاریای که پردازشهای سنگین و یا حجیم اطلاعات رو نیاز داشته باشن. خودم میخوام ازش برای توسعهٔ چند تا پروژهٔ تجاری طی سه سال آینده استفاده کنم. همچنین یکی دو تا پروژهٔ دانشگاهی و یه دونه هم دولتی هست که مورد استفادهٔ فوقالعادهای خواهد بود. -
p{direction:rtl; text-align:right}. توزیع
برای حل مشکل توزیع یک سری ایدههایی دارم. مثلاً تولید اینستالرها که کتابخانههای کیوت و MinGW رو داخل مسیرهای سیستمی نصب کنن. و یا داخل یک مسیر اختصاصی کپی کنن و اون مسیر رو به متغیر PATH ویندوز اضافه کنن. همچنین با اضافه کردن پسوندهای مناسب و استفاده از namespace ها میشه کار کرد که بیشتر از یک نسخه از کیوت روی یک سیستم بدون هیچ مشکلی نصب بشه. مثلاً کیوت چهار و کیوت پنج هر دو به شکل ۶۴ بیتی و ۳۲ بیتی. (چهار تا!) این کار رو میشه موقع کامپایل با تعریف یک پسوند برای DLL ها و همچنین یک namespace برای کتابخانهها انجام داد. در این صورت DLL هامون مثلاً این شکلی میشن: Qt4Core_x86_64_4.dll , QtCore_x86_5.dll و غیره...p{direction:rtl; text-align:right}. میمونه مسألهٔ پکیج کردن نسخههایی که برای توسعهدهندهها باید توزیع بشه. راستش رو بخواین اصلاً دلم نمیخواد این کار رو انجام بدم. چون سخته. اندازهٔ درست کردن یک SDK قابل نصب سخته. برای همین یه سری فایل tar.gz ازشون میسازم اونم فقط برای استفادهٔ خودم. (کی میتونه با این اینترنت مسخره ۴ گیگابایت اطلاعات رو آپلود کنه؟ تازه جایی هم ندارم آپلود کنم). اط طرف دیگه کامپایل هر پکیج روی کامپیوتر من حدود ۲۰ تا ۲۵ ساعت زمان میبره....
p{direction:rtl; text-align:right}. اگه نظر و یا سؤالی فقط در مورد مسائل تکنیکی و کارهای انجام شده دارید مایلم بشنوم.
-
p{direction:rtl;text-align:right}. چرا میخوای کار خودت رو سخت کنی؟ همین که زحمت کشیدی و اینهارو کامپایل کردی برای توزیع کافیه. در مورد اسم فایل ها فکر نکنم LGPL اجازه بده که تغییرشون بدی. ولی میتونی دایرکتوری های مختلف برای هر build بسازی و به برنامه نویس ها فایل qtconfig.ini ارائه بدی که بذارن کنار برنامه شون. در کل ارزش کار به installer هست. من هر موقع وقت خالی پیدا کنم توی ساختش کمک میکنم. همچنین برای build ها رو من میتونی حساب کنی. فقط ریفرنس ها و فرمان کانفیگمون باید با هم سینک باشه.
-
[quote author="Mohsen" date="1356956936"]p{direction:rtl;text-align:right}. چرا میخوای کار خودت رو سخت کنی؟ همین که زحمت کشیدی و اینهارو کامپایل کردی برای توزیع کافیه. در مورد اسم فایل ها فکر نکنم LGPL اجازه بده که تغییرشون بدی. ولی میتونی دایرکتوری های مختلف برای هر build بسازی و به برنامه نویس ها فایل qtconfig.ini ارائه بدی که بذارن کنار برنامه شون. در کل ارزش کار به installer هست. من هر موقع وقت خالی پیدا کنم توی ساختش کمک میکنم. همچنین برای build ها رو من میتونی حساب کنی. فقط ریفرنس ها و فرمان کانفیگمون باید با هم سینک باشه.[/quote]
p{direction:rtl;text-align:right}. محسن دهنم سرویس شد تا اینو کامپایلش کنم! حدود سی تا پچ اعمال کردم برای وبکیت تا تونست کامپایل بشه. در مورد پرل و رابی و پایتون و مسیرهای ویندوز هم خیلی خیلی مشکلات زیاد بود! یه باگ مزخرف هم پیدا کردم این وسط. سه تا باگ هم قبلش شناسایی شده بود توسط دیگران که هرکدوم دردسر خودشو داره. بعد کتابخانههای پایه هر کدوم ادابازی خاص خودشونو داشتن. الان دارم اینستالر رو درست میکنم. اما چون پاسکال بلد نیستم نمیتونم گزینههایی اضافه کنم که موقع نصب کاربر انتخاب کنه که کدوم ماژولها نصب بشه. (از Inno Setup استفاده میکنم)
-
p{direction:rtl;text-align:right}. اشکالی نداره در عوض کلی تجربه بدست آوردی. گزینه نصب نمیخواد. همون حالت installer ساده بساز که فقط نصب کنه.
یه ایده ای برای آیندش از ministro در necessitas گرفتم که اگه پیاده بشه خوبه.
اینکه یه آبجکت به برنامه نویس بدی که یک manifest تنظیم کنه برای پروژه و همراه برنامه کامپایل بشه. بعد برنامه که میخواد اجرا بشه تو چک کنی ببینی که لایببری اون ورژن روی سیستم موجود هست یا نه. اگر نبود دانلود بشه.
در آینده فکر کنم بدرد بخور بشه. -
[quote author="Mohsen" date="1356973261"]p{direction:rtl;text-align:right}. اشکالی نداره در عوض کلی تجربه بدست آوردی. گزینه نصب نمیخواد. همون حالت installer ساده بساز که فقط نصب کنه.
در آینده فکر کنم بدرد بخور بشه.[/quote]p{direction:rtl;text-align:right}. حجم تمام باینریها خیلی خیلی زیاده! شاید بهتر باشه این امکان رو به کاربر بدیم که خودش انتخاب کنه دقیقاً کدوم کتابخونهها رو میخواد. یه مقدار هم واسه خودم میخوام. چون وقتی برنامهای رو میخوام تحویل بدم خودم دوست دارم کیوت روی سیستم موقع نصب بریزم. واسهٔ همهٔ کامپیوترهای یه سازمان هم نیازی نیست مثلاً OpenGL و QtQuick و مخصولاً QtWebkit نصب بشه. یک بیستم این سایز برای اجرای برنامهها کافی خواهد بود. چند تا گزینه میذارم که بهشکل دستهای گزینههای دیگه رو انتخاب میکنه. مثلاً سه نوع نصب (مثل ویژوال استودیو) الان وارد فاز دوم کامپایل شدم. با ویژوال استودیو ۲۰۱۲ و کتابخانهٔ ANGLE به همین شکل میخوام کامپایل کنم. اما نمیدونم سویچهای بهینهسازی MSVC چطوریان.
[quote author="Mohsen" date="1356973261"]p{direction:rtl;text-align:right}. یه ایده ای برای آیندش از ministro در necessitas گرفتم که اگه پیاده بشه خوبه.
اینکه یه آبجکت به برنامه نویس بدی که یک manifest تنظیم کنه برای پروژه و همراه برنامه کامپایل بشه. بعد برنامه که میخواد اجرا بشه تو چک کنی ببینی که لایببری اون ورژن روی سیستم موجود هست یا نه. اگر نبود دانلود بشه.
در آینده فکر کنم بدرد بخور بشه.[/quote]p{direction:rtl;text-align:right}. چطور؟ یه چیزی مثل build key ؟ الان مگه نیست؟
-
p{direction:rtl;text-align:right}. فکر کنم چیزی که تو ذهن منه با کاری که تو داری انجام میدی متفاوته. انگار من اشتباه برداشت کردم از برنامت.
چیزی که من فکر میکردم این بود که تو میخوای یه redistributable package درست کنی و این پکیج popular بشه و برنامه نویس ها برنامشون رو مطابق اون deploy کنن و اگر رو یه سیستم نصب بود، دیگه نیازی به دانلود مجدد اونا نباشه. خوب مسلما برای اینکار نیاز هست که تمام باینری ها نصب بشن. اون ایده ای هم که گفتم بر اساس این نظریه بود. (البته برای سیستم 32 بیتی باینری های 64 بیت لازم نیست. به عبارتی پکیج در 2 نسخه 32 و 64 برای هر سیستم عامل ارائه میشه)
منظورم build key نیست. این یه کنترلیه که توسط برنامه تو که رو سیستم نصب شده انجام میشه. فقط یه آبجکت رو سورس attach میشه که برنامه کنترل کننده تو رو صدا میکنه و اطلاعات مانیفست رو بهش پاس میده. کنترل کننده مانیفست رو بررسی میکنه میبینه که مثلا لایببرری های 5.1 نیاز هست. میگه اینا رو سیستم نصب نیست میخواهید دانلود بشه؟ کاربر میگه بله یا خیر. یا اینکه میبینه لایبرری های 5 نیازه، مسیر لایبرری های مورد نیاز رو میده و پروژه لاببرری هارو از اونجا میخونه.
@
QApplication::setLibraryPaths();
@
یا
qtconfig.ini -
p{direction:rtl;text-align:right}. برای اینکه نیازی نباشه هر برنامه ای با خودش 20mb اضافه حمل کنه. با اینکه portable بودن کیوت خودش یک مزیته ولی برنامه های کوچیک کمی با حجم فایل ها مشکل دارن. وگرنه خوب همونطور که برنامه رو تولید کرده، همون فایل هارو هم کنار برنامه میفرسته دیگه! کاری که الان انجام میشه.
از طرفی برنامه های بزرگتر این rp رو با خودشون به کامپیوتر ها میبرن. -
[quote author="Mohsen" date="1356982980"]p{direction:rtl;text-align:right}. برای اینکه نیازی نباشه هر برنامه ای با خودش 20mb اضافه حمل کنه. با اینکه portable بودن کیوت خودش یک مزیته ولی برنامه های کوچیک کمی با حجم فایل ها مشکل دارن. وگرنه خوب همونطور که برنامه رو تولید کرده، همون فایل هارو هم کنار برنامه میفرسته دیگه! کاری که الان انجام میشه.
از طرفی برنامه های بزرگتر این rp رو با خودشون به کامپیوتر ها میبرن.[/quote]p{direction:rtl;text-align:right}. آقاجان خوب اصلا DLL فلسفهش همین بوده دیگه. اون واسط اضافی که برای مانیفست رو بررسی میکنه رو نفهمیدم. چه نیازی هست به اون؟. چرا لینک مستفیم نکنن برنامهها؟
-
p{direction:rtl;text-align:right}. ببین فرض کن که تو یه برنامه میذاری واسه دانلود که فقط یه exe هست.
من میام دانلودش میکنم اجراش میکنم. یه پیغام میاد که این برنامه به rp نیاز داره از لینک زیر دانلودش کنید. من میرم اونو دانلود میکنم نصب میکنم برنامه کار میکنه.
فردا یه برنامه دیگه دانلود میکنم. اجراش میکنم. حالا دیگه rp نصبه ولی اون ورژن از dll هایی که این برنامه باهاش کامپایل شده رو نداره (اینا تو مانیفست مشخص شده: ورژن dll ها، dll هایی که استفاده شده + مشخصات اضافی.. کامپایلر و اینا)
پیغام میاد که این برنامه به چند فایل اضافی نیاز داره. دانلود بشه؟ میگم yes. فقط core و gui دانلود میشه.
دوباره فرداش یه برنامه دیگه میگیرم که webkit توش استفاده شده. پیغام میاد این برنامه به فایل اضافی نیاز داره دانلود شه؟ میگم yes. وبکیت دانلود میشه در کنار core و gui قرار میگیره و پکیج کاملتر میشه. تو بعضی موارد حتی برنامه واسط هم update میشه اگه نسخه جدیدترش باشه. (مثلا میخوایم سرور دانلود رو عوض کنیم) -
p{direction:rtl;text-align:right}. نه! اشتباه متوجه شدی. ببین برنامه واسط اون گوشه هست. تو به برنامه نویس یه lib یا یه snippet میدی که تو برنامش میچسبونه. برنامش رو مثل همیشه کامپایل میکنه. وقتی که برنامه اجرا میشه اون کدی که تو بهش دادی اول از همه اجرا میشه و با برنامه واسط تو ارتباط برقرار میکنه. متوجه شدی؟ این یه مدل هست که خیلی جاها پیاده سازی شده. اگه با necessitas کار کرده باشی متوجه میشی که چی میگم.
-
[quote author="Mohsen" date="1357036399"] وقتی که برنامه اجرا میشه اون کدی که تو بهش دادی اول از همه اجرا میشه[/quote]
p{direction:rtl;text-align:right}. نمیتونه. چون زمان لینک مشخص کردی که به باینریهای کیوت و چیزای دیگه لینک کنه. قبل از اجرای هر کدی تمام پیشنیازها توسط لودر سیستمعامل بارگذاری میشه. اگر موفق بود تازه شروع میکنه به اجرای کد برنامه. در غیر این حالت باید کتابونهها لود و آنلود بشن. که در حالت کلی اصلاً ایدهٔ خوبی نیست.