למה להמציא גלגל מחדש זה לא תמיד עובד טוב

ב־12.11.2009, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏, ‏CMake‏; ‏8 תגובות

לאחרונה אני מנסה להגר ל־CMake מ־autotools בפרויקט CppCMS בעיקר כדי להבטיח תמיכה טובה יותר בסביבת Windows ובפרט ב־MSVC מתישהו בעתיד.

עשיתי כבר הרבה עובדה והענף הניסיוני עבר ל־CMake. אפילו לא מעט אנשים ברשימת התפוצה התלהבו מהעובדה שהמערכת תעבוד על CMake... רבים חוץ ממני. אחרי שהתחלתי לעבוד אתה בצורה יותר עניינית הבנתי: היא באמת יותר מוצלחת בפיתוח ל־Windows מאשר autotools בעיקר בגלל שהיא קצת יותר גמישה בנושא ה־exports וכמובן התמיכה ב־MSVC.

אבל פה בערך נגמר היתרון. עכשיו אני אתלונן על דברים שמעצבנים אותי:

המהירות שאנשי CMake מתלהבים ממנה זאת גם עקב אכילס שלה. יש לזה מספר נקודות:

  1. ב־autotools הייתה הפרדה ברורה בין automake שמגדיר את מבנה הפרויקט לבין autoconf שמגדיר את קונפיגורציית הפלטפורמה. מצד אחד זה היה קצת מפריע אבל מצד שני זה היה מאוד נוח: הוספת קובץ חדש לא פרויקט לא דרשה הרצת configure מחדש מצד אחד, מצד שני כל שינוי בצורת הקונפיגורציה ביצע הרצת configure שלמה.

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

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

  2. מנגנון מעקב אחרי התלויות של CMake לא בודק את הקובץ config.h משמע... אם עשיתי שינויים בקונפיגורציה הקוד לא ייבנה מחדש. צריך להריץ make clean ו־make שוב! העיקר שיש להם cache חזק.

הרבה מגנונים הקיימים לוקים בחסר או לא מתוכננים היבט. לדוגמה:

  1. משהו מאוד פופולרי כמו AC_SEARCH_LIBS שמאפשר לך לבדוק אם פוקנציה מסוימת קיימת, אם כו אז אל תעשה דבר, חפש אותה בספריות. דוגמה קלאסית. pthreads, iconv, dlopen, socket שלפעמים מהווים חלק מהספרייה הסטנדרטית ולפעמים דורשים ספריות חיצוניות. אין פונקציונליות כזו בכלל.
  2. בדיקת sizeof היא בכלל פנינת CMake. יש לה מספר בעיות:

    • היא נעשית ע"י הרצת קוד מה שאומר היא לא תעבוד בקרוס־קומפילציה. כאשר ב־autotools עושים טריק מאוד יפה המאפשר לבצע בדיקה כזו ללא הרצת קוד אלא קומפילציה בלבד.
    • היא לא מאפשרת להוסיף header כך שלא ניתן לבדוק sizeof של טיפוסים הנמצאים ב־includes לא סטנדרטיים.
  3. אין פונקציונליות דומה ל־AC_ARG_ENABLE המאפשרת להציג רשימת הפרמטרים לקונפיגורציה והערות לגביהם -- קרי אין כלי כמו ‎./configure --help שמאוד עוזר בהרבה מקרים.

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

אני מקווה שיום אחד autotools ידעו לתמוך גם ב־MSVC בסה"כ זה לא אמור להיות מי יודע מה מסובך... ICU משתמשים ב־autotools יחד עם MSVC בצורה מוצלחת למידי (למעשה הבעיה היא אפילו לא automake ו־autoconf הם דווקא איכשהו עובדים עם הקומפיילר, (הוא מסתבר כן תומך בהרבה דגלונים הרגילים כמו "‎-o -I" ועוד) הבעיה היא בעיקר libtool.

במילים אחרות... אם אתם לא מתכוונים לתמוך ב־MSVC תתרחקו מ־CMake, אבל ממש תתרחקו ממנו.

תגובות

ik_5, ב־12.11.2009, 14:19

אחד היתרונות שיש לי בזה שאני לא משתמש ב C ו ++C זה בדיוק המחסור הזה בכאב ראש. וזה בלי להיכנס איזו שפה וטכנולוגיה עדיפה (הרי התשובה ברורה :P).

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

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

בנוסף, אם אני בוחר בשיטה של בורלנד (ולזרוס), אני אשתמש ב"חבילה" (package) אשר זה בסה"כ קובץ xml (ויש ממשק גרפי לעבוד עליו) שיודע להתמודד עם כמה תוכנות ותכונות וכן לתת תלויות, מיקומי קבצים, דגלים למהדר וכו'. בנוסף לFPC יש מנהל חבילות אשר יודע להוריד לי תלויות ממש כמו cpan או ruby gems ואני יכול להגיד לו לארוז לי את הקוד כמו שאני רוצה בהתאם, וזה לא תלוי (אלא אם לא אעבוד לפי הכללים) בסביבה או מערכת הפעלה מסויימת.

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

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

ארתיום, ב־12.11.2009, 14:57

בפסקל...

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

זה כמו להגיד אם תכתוב ב־Java לא תהיו לך בעיות כאלה. נכון שלא יהיו כי יש לך קומפיילר אחד שמריץ הכל על פלטפורמה אחת.

...אלא לנסות להצביע על הבעיה אמיתית...

הבעיה האמתית שאין אחידות בין מערכות הפעלה/קומפיילרים או תקן כלשהו למה שקומפיילר אמור לעשות לעבר למסמך הגדרת השפה. כך קל לכתוב רק עבור Java של Sun...

עכשיו בואו נעשה תרגיל:

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

  • FPC‏
  • Delphi‏
  • gpc‏
  • וכנקודת בונוס גם Turbo Pascal 7

אני רוצה לראות אותך עושה את בכלי כלים חיצוניים (לך כנראה אין כלים לעשות את זה בכלל).

תמיד Vendor Lock In זה קל יותר. כך שמקומות עבודה אף אחד לא כותב לך כלי בניה עם cmake אלא פותחים פרויקט ב־Visual Studio או כותבים Makefile פשוט.

מקסים ווקסלר, ב־12.11.2009, 16:25

אנחנו בחברה משתמשים ב SCons. אנחנו אמנם מקפלים רק ללינוקס אבל מחליפים בין קומפיילרים.

אחד הפרוייקטים היפים ביותר שיצא לי לראות לקימפול קוד, מתעלה על ant, cmake ובטח ובטח ש autotools.

מומלץ.

ik_5, ב־12.11.2009, 16:50

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

כמו שאמרתי, השפה מכניסה פנימה את השליטה לקוד שלי ולא החוצה. ואם אתה לא יודע על מה אני מדבר, הנה קוד שעובד (בדוק) FPC ו GPC: http://libhdate.svn.sourceforge.net/viewvc/libhdate/trunk/libhdate/bindings/pascal/hdate.pp?revision=242&view=markup

אם אני אשנה שם שורה אחת של IFDEF זה יעבוד בכמעט כל מהדר פסקל מודרני שקיים כיום בלי לכתוב Makefile !

ארתיום, ב־12.11.2009, 18:22

עידו, אתה מתבלבל בין לקמפל קוד לבין לנהל פרויקט. שוב, כמו שאמרתי תעשה תרגיל:

program calc;
    var x,y:real;
begin
    writeln('Enter x and y:');
    readln(x,y);
    writeln(x,'+',y,'=',x+y);
end.

תבנה בבקשה פרויקט ש:

א. יעבוד עם delpi, ‏FPC וגם-gpc ללא יוצא מן הכלל.
ב. ידע לבחור קומפיילר ברירת מחדל או זה שמציע המשתמש
ג. ידע לבצע התקנת התכנה במערכת (או אולי גם לבנות חבילה).
ד. תתמוך בלינוקס חלונות, סולריס ומק.
ה. תתמוך בקרוס־קומפילציה כך שאול לבנות גרסת ARM על לינוקס.
ו. תכיל מערכת טסטים אוטומטיים שתבדוק שהמחשבון אכן עובד (קרי 1+3 זה 4).

כשתסיים, דבר אתי. אחרת אתה לא משכנע.

ארתיום, ב־12.11.2009, 18:22

אנחנו בחברה משתמשים ב SCons.

ראיתי, לא התרשמתי, אפילו יותר גרוע מ־CMake.

ik_5, ב־12.11.2009, 19:09

ארתיום. מערכת של autotools עם כל הכבוד בודקת אם הספרייה שאתה צריך קיימת, אח"כ מחליטה בשבילך איך זה יקושר, ואיזה קובץ יהיה ההתחלה של shared library ומייצר לך Makefile שעושה את הדברים האלו.

אני לא צריך את זה ! אם עכשיו אני לא צריך את זה, כבר הורדתי לי 3/4 מהכאב ראש !

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

ואם אני חייב cmake אותו הדבר, עדיין הקוד שאני צריך פשוט יותר ממה שאתה צריך.

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

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

ארתיום, ב־12.11.2009, 22:11

לצערי יש לנו שיחת חירש עם עילם.

עזוב. אם אתה לא מוכן להתייחס לטענות שלי אין לי מה יותר לומר.

הוסף תגובה:

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

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

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

דפים

נושאים