לקמפל על Linux להריץ על Windows.

ב־8.2.2009, מאת ארתיום; פורסם תחת: תכנה חופשית, לינוקס, פיתוח, תכנה ומחשבים; ‏13 תגובות

לעתים, אנחנו נרשים לתמוך בפלטפורמה הלא ידידותית הזו. הבעיה העיקרית שלפעמים זה די מעצבן לוותר על הסביבה הנוחה שלך להיכנס ל"חלונות" רק כדי לבנות את כל מה שצריך.

הכל התחיל מזה שרציתי לבדוק --- עד כמה זה מסובך לבנות cppcms על mingw וכמה מאמץ צריך להשקיע להסבה. הסיפור היה נראה די מסובך --- איזה פונקציות המערכת שאני משתמש בהן לא נתמכות בחלונות ואילו כן. אז היה ברור שצריך לנסות לבנות את כל היישום. בהתחלה זה היה נראה די מסובך להתחיל לבנות את כל הסביבה במכונת windows וירטואלית חסרת כלי פיתוח בסיסיים.

אבל autotools נותן תמיכה מצוינת ב־cross compilation עבור Windows. כל מה שצריך זה להתקין mingw ולהריץ:

 ./configure --host=i586-mingw32msvc --prefix=/place/to/install

זהו פחות או יותר! הוא יבנה לך ספריות סטטיות ודינמיות, יבנה dllים איפה שצריך, יתקין. לעשה, ייתן לך סביבה שקופה לבניית יישומים תחת mingw. כמובן מדובר ב־debian/ubuntu ב־RH שם הקומפיילר יכול להיות קצת שונה.

ובכן, קמפלתי cgicc --- (היו כמה בעיות מינוריות, אבל הסתדרתי), הורדתי pthreads עבור windows. הכל היה די מבטיח.

לאחר מכן, בא הסיוט --- לבנות boost. הם לא משתמשים ב־autotools וגם bjam לא ממש תומך בצורה סבירה ב־cross compiling... אחרי הרבה מאמץ... ויתרתי ובניתי אותו על חלונות.

אחרי שבניתי boost הרצתי קונפיגורציה עבור cppcms והכל עבד מצוין --- הצלחתי למפות בצורה יפה את כל הפונקציות הלא נתמכות: בהן gettimeofday, readdir_r, clock_realtime, pthreads_sigmask ועוד ועוד ועוד (זה מעבר לדברים שידעתי שלא ייתמכו כמו fork ו־dlopen)...

מסקנות:

  1. ככל שעובר הזמן אני מבין יותר ויותר שבמציאות אין תחליף ל־autotools הישן והטוב ולא כל־כך ידידותי. לכל הילדים כמו bjam, cmake, scons ואחרים יש עוד דרך מאוד ארוכה.
  2. צריך לעבור ל־autotools גם עבור biditex ולחסוך לעצמי מאמץ של תחזוקה של שני קובצי makefile עבור שתי פלטפורמות שונות.
  3. לא נראה לי ש־CppCMS יתמוך ב־windows בקרוב.
  4. אם qt4 היה עובד עם autotools זה היה חוסך לי המון זמן, אתחולי Virtual Box רבים כדי לשחרר גרסאות של יישום קטן עבור חלונות/לינוקס.

תגובות

ik_5, ב־8.2.2009, 15:08

מזל שעם FPC אין לי צורך בכל כך הרבה טכנולוגיות בשביל לבנות דברים מלינוקס ל Windows או כל פלטפורמה אחרת.

כלומר כל הרעיון של AutoTools לא נחוץ

ארתיום, ב־8.2.2009, 15:21

ידעתי שתגיד משהו בסגנון ;)

אם אין לך צורך ב־autotools אשמח אם תספר כיצד אתה עושה conditional builds?

נגיד יש לי ספריה libabc שאפשר לבנות יישום אתה או בלעדיה? כיצד אתה בודק אם היא קיימת וכיצד אתה עושה conditional build בצורה אוטומטית?

כנ"ל כיצד אתה בודק פיצ'רים של מערכת למשל האם pthread_mutex תומך ב־pshared? שזה יכול להשפיע על המימוש שלך?

  • האם יש ל־FPC מנגנון שבונה אוטומטית מילוני gettext?
  • האם יש ל־FPC מנגנון שמאפשר להפיץ קוד מקור בחבילות מוכנות?
  • האם יש ל־FPC מנגנון שמאפשר להריץ בדיקות באופן אוטומטי כחלק מתהליך בניה?
  • האם יש ל־FPC מנגנון שמאפשר לעשות cross-compile מ־Linux ל־Windows?
  • האם יש מנגנון שמאפשר לעשות התקנה של תכנה והסרה שלה?
elcuco@kde.org, ב־8.2.2009, 20:39

מה הבעייה לכתוב auto* עבור QT4? הרי עשו את זה בשביל KDE3?

נו יאללה :)

ארתיום, ב־8.2.2009, 21:16

נכון... אבל, יש אבל גדול... תמצא לי מדריך סביר לעבודה של auto*‎ עם Qt4?

ik_5, ב־8.2.2009, 21:45

ארתיום אתה מוזמן לקרוא את הקישורים הבאים:
http://wiki.freepascal.org/Cross_compiling
http://wiki.freepascal.org/Cross_compiling_for_Win32_under_Linux
http://wiki.freepascal.org/FPMake
http://wiki.freepascal.org/fppkg

כתבתי בעבר על מערכת ליצירת מילונים מFPC ללא קשר ל gettext אלא שניתן לתרגם גם לgettext אצלי בבלוג:

http://idkn.wordpress.com/2008/06/09/תרגום-תוכנה-באמצעות-gnu-gettext/

לגבי בנייה מותנת, בשביל זה המציאו את DEFINE ו IF או IFDEF.

הרעיון של פסקל (בלי קשר כרגע לFPC) שאתה שולט מתוך הקוד שלך במהדר כמה שרק ניתן, ורק במקומות שזה לא אפשרי (נתיבי חיפוש למשל, או דברים שצריך להגדיר חיצונית) אז יוצרים משהו מבחוץ.

כלומר בשביל לספק תמיכה ב3/4 מהדברים שאתה צריך בשבילהם autotools שאני אפילו לא מתקרב ל Makefile אלא המהדר מספיק חכם (בתוספת הוראות שלי) בשביל לדעת מה לעשות ואיך להגיב.

אני מקווה שלא שחכתי משהו מבחינת הנקודות שלך, אם כן אתה מוזמן להעיר/האיר (מה שאתה חושב שלא נכון/מתאים/חסר) ואנסה לענות.

ארתיום, ב־8.2.2009, 22:36

כלומר בשביל לספק תמיכה ב3/4 מהדברים שאתה צריך בשבילהם autotools שאני אפילו לא מתקרב ל Makefile

זאת בדיוק הנקודה: כל הכלים כמו CMake, scons, bjam עושים 3/4 דברים, כל השאר --- תשבור את הראש בעצמך

לגבי בנייה מותנת, בשביל זה המציאו את DEFINE ו IF או IFDEF.

הבעיה היא לא ifdef הבעיה כיצד לבנות defines. נגיד, כיצד אתה תבדוק אם יש תמיכה ב־pshared ב־pthread_mutex?

התשובה --- דרך צלחה לך לכתוב את כל ה־ifdefים. כי ב־linux 2.4 אין תמיכה, אבל ב־2.4 עם NPTL יש. ב־2.6 יש, ב־freebsd אין, ב־solaris יש (החל מאיזו גרסה?) ב־cygwin אין.

מה שנקרה לך תחפש את החברים. עם autoconf אני בודק את זה בכמה שורות.

בנוסף, כיצד תזהה עם יש ספריה מותקנת ותעשה בנייה מותנית (אני זוכר את הפוסט שלך על חיפוש ה־symbol בספריה).

למשל, לבניה מינימלית של cppcms אתה צריך רק cgicc ו־boost 1.33.1, כל השאר אופציונלי (ויש מספיק ספריות נוספות שאני משתמש בהן).

הבעיה זה לא ifdef אלא כיצד למצוא את ה־defineים הנכונים.

אורון, ב־9.2.2009, 0:51

הערונת לגבי dlopen -- יחד עם libtool מסופקת ספרייה קטנה בשם libltdl. ספרייה זו מספקת מעטפת פורטבילית לכמה מערכות הפעלה (כולל חלונות). הממשק כמעט זהה לממשק dlopen -- לדוגמא:

lt_dlinit

lt_dlopen

lt_dlsym

lt_dlclose

lt_dlexit

ik_5, ב־9.2.2009, 10:03

יש לי בדיוק מעטפת כזו בFPC בספרייה בשם dynlib.

ארתיום, העניין של ספריה משותפת היא שב C אתה תמיד תהיה צריך בכל הידור לבדוק באיזו ספרייה משותפת הסימול שלך, בפסקל אלא אם אני לא יודע לתכנת, אין סיבה לזה.

יותר מזה, איך אם אתה מסתכל רק על קוד C אתה יכול לדעת מתי פונקציה היא מיוצאת או אולי היא בכלל פנימית ? איך אתה בכלל יודע שהקוד C שלך הולך להיות ספרייה משותפת רק ממבט על הקוד C ? [אני כמובן יודע את התשובה, שאתה לא יכול]

אם תסתכל על הקוד (http://ik.homelinux.org/index.rhtml/projects/bash/find_function) bash שלי לחיפוש אחרי סמלים (הוא השתנה מאוד אחרי הפעם האחרונה שהתסכלת עליו) אתה תראה שהוא מאוד מדוייק והוא משמש אותי לזמן פיתוח ולא לזמן הידור. כלומר רק פעם אחת אני אריץ אותו כשאני כותב binding. אחרי שיש לי binding אין לי צורך בסקריפט שלי. זה בדיוק ההבדל בין autotools לבין חוסר הצורך להשתמש בו.

העניין של פיתוח קוד שהוא תלוי פלטפורמה הוא תמיד כאב ראש. בגלל זה אני משתדל לכתוב warppers לפקודות. בפסקל בכלל וב FPC בפרט יש לך כמה צורות ממש נחמדות לעשות את זה. יש לך מנהל thread יש לך מנהל זיכרון, יש לך מנהל exception וכו' כל אחד מהם מכיל wrapper עם API זהה בשביל לנהל את מה שהוא צריך ובתוך היחידות שמממשות את זה ומשכתבות את המנהל אתה מתעסק בקוד האמיתי שהוא תלוי פלטפורמה וכו'.

זו הסיבה שאם אני רוצה להשתמש ב malloc של C כל מה שאני צריך לדאוג זה שהיחיסה cmem תהיה הראשונה משמאל ביחידה/ות שאני רוצה שזה ינוהל עם cmem, אם מחר אני לא רוצה יותר להשתמש ב cmem, אני מסיר את היחידה, אני לא משנה בכל הקוד שלי דברים.

ראה את המדריך הבא בתור דוגמא לגישה שונה ממה שאתה מציג: http://wiki.freepascal.org/Multithreaded_Application_Tutorial

בוא אני אתרגם רגע את הדברים שלך, ובוא רגע נתעלם מהשפה המדוברת. אתה אומר "איזה יופי, יש לי שפת סקריפט שלמה שעוזרת לי להדר את התוכנית שלי, אז מה אם זה עקום, זה עושה את העבודה ונותן לי הרבה יכולות". אני בא ואומר: "יש לי שפה, היא מספקת לי מספיק כלים בשביל שאני לא אהיה צריך לכתוב תוכנית שלמה בשפת סקריפט בשביל להדר את התוכנית שלי".

אם אתה מתעלם מהשפה כרגע, מה עדיף לכתוב תוכניות שלמות עם שפת סקריפט בשביל שיהיה אפשר להדר את התוכנית שלך, או אולי לקבל יכולות נחמדות לשפה שאתה משתמש בה בשביל להתמקד בפיתוח התוכנה שלך ולא בכלים בשביל ליצור אותה ?

ארתיום, ב־9.2.2009, 11:06

יותר מזה, איך אם אתה מסתכל רק על קוד C אתה יכול לדעת מתי פונקציה היא מיוצאת או אולי היא בכלל פנימית ? איך אתה בכלל יודע שהקוד C שלך הולך להיות ספרייה משותפת רק ממבט על הקוד C ? [אני כמובן יודע את התשובה, שאתה לא יכול]

ממש לא נכון. כל פונקציה שהיא לא סטטית ב־C היא מייוצאת, פונקציות סטטיות לא.

אני לא מדבר על סביבות דפוקות כמו dll של windows בו צריך ציין במפורש מה מיוצא ומה לא.

כנ"ל ב־C++‎. פונקציות ב־namespace אנונימי אינן מיוצאות, שאר הפונקציות כן.

תראה שהוא מאוד מדוייק והוא משמש אותי לזמן פיתוח ולא לזמן הידור

תשמע, הסקריפט הזה בכלל עקום לזמן פיתוח. המיקום של פונקציה בספריה צריך להופיע בתיעוד! אתה לא צריך לבנות סקריפטים בשביל למצוא את זה.

ואם התיעוד דפוק, כנראה גם הספריה דפוקה!

הבעיה היחידה היא שונות בין מערכות שונות, כמו למשל ב־solaris אתה צריך לעשות link עם nls כדי לקבל gethostbyname ובלינוקס אתה צריך rt כדי לקבל clock_gettime.

ש לי שפה, היא מספקת לי מספיק כלים בשביל שאני לא אהיה צריך לכתוב תוכנית שלמה בשפת סקריפט בשביל להדר את התוכנית שלי

שוב, עידו --- תשים לב אתה משתמש במערכת של מעטפת. אני רוצה לראות אותך מבצע את כל הנקודות שציינתי לעיל בעזרת FPC בלבד.

אתה מתבלבל בין שפה לבין מערכת בניה/הפצה/הבדיקה/קונפיגורציה.

שוב --- תגיד לי איך אתה עושה קימפול מותנה ב־FPC בהתאם אם למשל ספריית hdate מותקנת במערכת או לא!

שהכל ייעשה אוטומטית מבחינת משתמש בקוד המקור שלך.

איך אתה מבצע התקנה של תכנה? ועוד ועוד

ik_5, ב־9.2.2009, 14:17

ארתיום, למה אני צריך לכתוב משהו שיבדוק את זה ? אם הספרייה לא קיימת אני אקבל שגיאה שהספרייה לא נמצאה. אם הפונקציה לא קיימת, אז אני אקבל מידע שהסימול לא נמצא, ואם המבנה של הסימול השתנה אני אקבל גם על זה שגיאה. אני לא מבין למה אני צריך לבנות משהו משל עצמי כל פעם ?

בדיקות אוטומטית למה אתה רוצה לבנות בדיוק ? תפרט עם לזרוס אני יכול ליצור test case לדברים שאני כותב, זה לא תלוי מהדר זה תלוי כלי, האם זו הכוונה שלך ?

אתה רוצה לכתוב תוכנית שאם ספרייה מסויימת קיימת היא תשתמש בה ואם לא אז מה בדיוק לעשות ? להשתמש בספרייה אחרת ? לא להדר בכלל ? אין תשובה קסם.

האם בדקת את הקישורים ששמתי לך למעלה ? האם ראית מערכת בנייה מבוססת פסקל ? האם ראית מערכת שיודעת להיות מנהל חבילות לכל דבר ועניין ?

אני לא רואה הבדל בין בנייה והפצה לבין כתיבת קוד. מצטער ההפרדה הזו היא מלאכותית. למה לעזאזל לכתוב כלים שלמים לנהל את זה כל פעם מחדש ?! למה אני צריך לחפש כל בנייה האם ספרייה מסויימת מכילה את הפונקציה שאני רוצה להשתמש בה, ואז לקשר אותה ? למה לא לעשות את העבודה הזו פעם אחת ?!

בקשר לתיעוד ספריות, מוזר שספריות מעפניות כדוגמת xcb xlib ועוד כמה שמאוד נפוצות אשר מספקות קבוצה מאוד גדולה של פנקציות שאנשים משתמשים בהם לא כותבת איפה כל פונקציה נמצאת (כלומר באיזו ספרייה).

בקשר לפונקציות סטטיות וספריות, נראה לך שזו הדרך ? אתה הצגת דוגמא אצלי בפוסט שפונקציה שנמצאת בשימוש אבל היא לא מוכרזת בספרייה נכנסת לרשימה (עזוב כרגע שיש דרך לדעת את זה מהספרייה עצמה), במידה ואין לך שליטה מה נכנס, ואיך הקוד שלך יתנהג (כלומר הוא ספרייה, אפליקציה, או כל דבר אחר) בתוך הקוד אז זה מתכון לבעיות. אני לא הולך לקרוא עכשיו Makefile וקובץ configure בשביל להבין אם הקוד יהיה ספרייה משותפת, אם כן מה השם ואיך הסבתא שלו תגור. אני מסתכל על הקוד, אני רואה שהוא מוכרז תחת חלק שנקרא library (עם השם של הספרייה) אבל לא נכנס לחלק ה exports ואז אני יודע שהוא פרטי. אני לא צריך לנחש, אני לא צריך להבין אם זו פונקציה סטטית, או אם לסבתא היו גלגלים. הקוד אומר לי ומגדיר לי איך דברים יתנהגו ובמקום להתחיל ללכת לכל הקבצים שהספרייה שלי תהיה, אני הולך למקום אחד בקובץ אחד בשביל לדעת את זה, וזה עדין חלק מהקוד !

תדע לך שהשיטה של מיקרוסופט ל dll היא שיטה מצויינת, אני יכול להגיד מה הולך ליצוא, מה הסדר של הפונקציות (כלומר אני לא חייב לפנות בשם אני יכול לפי מספר), ועוד הרבה דברים אחרים.

ארתיום זה שאתה עובד עקום, זה לא אומר שכל צורה אחרת לא טובה, זה אומר שאתה עובד עקום. אם אני יכול להוציא כמה שיותר דברים מהצורך לבנייה ומעביר את השליטה אלי (רגע אני בתור מתכנת לא יודע מה הדבר הכי טוב עבור הקוד שכתבתי ? אני לא יודע איך המהדר צריך לעבוד בשביל שהקוד שלי יהודר ? אם התשובות הם שכן צריכה להיות לי שליטה ויש לי ידע, למה להפריד את זה למערכת אחרת ? בשביל שגורם צד 5 יגיע ולא יבין משהו וידפוק הכל ?) זה לא אומר שהבנייה תהיה טובה ובנויה לעשות פעולות בצורה טובה יותר ?

ארתיום, ב־9.2.2009, 16:54

אם הספרייה לא קיימת אני אקבל שגיאה שהספרייה לא נמצאה

אתה רוצה לכתוב תוכנית שאם ספרייה מסויימת קיימת היא תשתמש בה ואם לא אז מה בדיוק לעשות ? להשתמש בספרייה אחרת ? לא להדר בכלל ? אין תשובה קסם.

זאת בדיוק הנקודה. אם אין לי ספריה ספציפית --- אני לא אבטל את כל התכנה, אני אבטל איזשהו פיצ'ר בה.

ראה את ה־Makefile.am הזה

אם אין לי ספריה libmm אני אני אבטל EN_FORK_CACHE ואז הספריה תעבוד ללא תכונה ספצפיפית. אם גרסת boost ישנה מידי אני לא אבנה רכיב תקשורת מסוים שעוזר ל־scaling אבל עדיין אבנה תכנה.

אם אין לי process shared mutex מהיר, אני אעשה fallback ל־fcnlt היותר איטי, אבל הוא עדיין יעבוד!

אם אין לי ספריית fastcgi אז היישום לא יוכל לעבוד בפרוטורול הזה, אבל מימוש של scgi עדיין יישאר.

תבין, זאת פונקציונליות הכרחית לפרויקט בסדר גודל כזה. אני רוצה שיהיה אפשר לבנות יישום בצורה מינימלית וגם בצורה מירבית.

למה אני צריך לחפש כל בנייה האם ספרייה מסויימת מכילה את הפונקציה שאני רוצה להשתמש בה, ואז לקשר אותה? למה לא לעשות את העבודה הזו פעם אחת ?!

כי ב־FreeBSD<>Linux<>Solaris<>Cygwin. לפעמים דברים זהים מפוזרים בספריות שונות

תדע לך שהשיטה של מיקרוסופט ל dll היא שיטה מצויינת,

באמת? אז למה כל העולם דווקא עובד לשימוש ב־ELF? ולא ב־dllים הדפוקים? עזוב, נראה לי שאתה ממש לא מבין על מה אתה מדבר.

א, ב־9.2.2009, 19:26

חבר'ה - בלי מכות!!! דוקא הדברים מאוד מעניינים, אבל הטונים צורמים מדי. אנא אם אפשר - להמנע מטונים גבוהים, זה לא נעים באזניים...

ארתיום, ב־9.2.2009, 22:46

חבר'ה - בלי מכות!!!

צודק.

עידו, אני מתנצל על דיבור בטונים גבוהיים ;)

הוסף תגובה:

 
 כתובת דוא"ל לא תוצג
 

ניתן לכתוב תגובות עם שימוש בתחביר Markdown.

חובה לאפשר JavaScript כדי להגיב.

דפים

נושאים