Ninja: خلط المسارات المطلقة depfile مع المسارات النسبية الواضحة فواصل إعادة البناء

تم إنشاؤها على ٢٤ فبراير ٢٠١٧  ·  70تعليقات  ·  مصدر: ninja-build/ninja

يحذر دليل النينجا من مثل هذا الخليط ، لكنه أصبح قيدًا خطيرًا.

المشكلة هي أن الناس يريدون أن تستدعي أنظمة البناء الخاصة بهم المترجم بمسار مطلق إلى الملف المصدر. ينتج عن هذا إخراج أفضل لـ IDEs لمطابقة رسائل الخطأ والرجوع إلى الملفات الأصلية. قد يؤثر أيضًا على المسارات المسجلة في معلومات التصحيح. ومع ذلك ، فإن هذا يتعارض مع تفضيل النينجا للمسارات النسبية في بيان البناء.

إليك نص برمجي يوضح المشكلة: ninja-bug.bash.txt

التعليق الأكثر فائدة

لا أعتقد حقًا أن الحل يجب أن يكون "الالتفاف حول هذا في جميع الأدوات الأخرى".

يوضح عام 1924 إصلاحًا كاملًا للعمل مع الاختبارات ، بناءً على نهج ninja_workdir . يمكن للمولد الذي يستخدم هذا حل جميع المشكلات المذكورة أعلاه.

ال 70 كومينتر

نسخة إلى: nicochaoren

في CMake ، هناك مناقشة ذات صلة في الإصدار 16675 ، الإصدار 13894 ، و MR 520 .

كحل بديل يمكنك تعيين دليل إخراج الكائن بشكل صريح ، حتى "." أو ".." ، لكن المسار المطلق يعمل أيضًا.
ninjatst.bash.txt

zlolik IIUC ، تقترح وضع المسارات المطلقة في بيان البناء ( build.ninja ) عقد الرسم البياني. بالتأكيد هذا يعمل (وهو ما يفعله CMake في البنيات خارج المصدر) ، لكن وجهة نظري هنا هي أن Ninja لا يشجع استخدام المسارات المطلقة ومع ذلك تتطلب IDEs في الإخراج.

من الممكن أيضًا افتراضيًا أن يقوم المترجم المعطى -c foo.c بإنشاء مسار مطلق في الملف على أي حال. إذا حدث ذلك ، فلن يتعرف Ninja على التبعية بسبب نفس المشكلة المبلغ عنها هنا.

سيتطلب إصلاح هذا الأمر من Ninja أن يكون قادرًا على التعرف على الوقت الذي يكون فيه المسار النسبي والمسار المطلق هما نفس الملف ولهما عقدة رسم بياني واحدة فقط داخليًا بدلاً من اثنين. قد يكون القيام بذلك فقط لمعالجة depfile كافيًا ، لأنه من المعقول أن تطلب من مولدات build.ninja تسمية المسارات بشكل متسق داخل بيان البناء.

bradking بادئ ذي بدء ، أنا أتفق معك على أن لدينا مشكلة مع النينجا وأقترح الحل البديل فقط.
أعتقد أن هناك 3 قضايا مرتبطة:

  1. المنطق بمسار الإدخال المطلق / النسبي ، مزيد من التفاصيل في # 1152.
  2. المنطق لإجبار إخراج المسار المطلق / النسبي. المشكلة مع المترجمين - الطريقة الوحيدة للقول للمترجم أنك تريد أن يكون لديك مسار مطلق في الإخراج هي استخدام المسار المطلق في سطر الأوامر. ليست قضية النينجا ولكن لدينا.
  3. المنطق لتحليل الملف المطلق / المسار النسبي. هذه المسألة.

أنا أستخدم حلين:

  1. استخدم البادئات $p و $o في مسار المولد build.ninja لحل أول مشكلتين. في حالتي ، $p و $o ليسوا مطلقين ولكن نسبيين من dir الحالي حيث تم تشغيل المولد build.ninja .
  2. استخدم بعض البرامج النصية لتحويل depfile إلى مسار متوافق مع النينجا. حتى أن بعض المترجمين يحتاجون إلى استدعاء منفصل لتوليد depfile. لكن لا توجد مشكلة مسار مطلق أثناء.

كمرجع ، لقد بدأت سلسلة رسائل في القائمة البريدية ninja-build مع حل مقترح.

هناك مشكلات أخرى ذات صلة حول معلومات التصحيح والتغطية: يؤدي استخدام الأوامر مع المسارات النسبية إلى إنشاء ملفات معلومات تصحيح الأخطاء ذات المسارات النسبية أيضًا. تكمن المشكلة في وضع ملفات التصحيح عادةً بجوار ملفات الكائن ، وليس ملفات المصدر ، لذا فإن المسارات النسبية هناك تشير إلى ملفات غير موجودة.

أي تحديث على هذا؟ لم تكن هناك أية ردود على سلسلة الرسائل البريدية ...

أهلا بالجميع،

من الممكن أيضًا افتراضيًا أن يقوم المترجم المعطى -c foo.c بإنشاء مسار مطلق في الملف على أي حال.

تحتوي ملفات التبعية الخاصة بـ IAR v8 على مسارات مطلقة فقط.

لقد واجهنا هذه المشكلة عند إجراء تصميمات خارج المصدر باستخدام CMake / Ninja / IAR: الملفات التي تم إنشاؤها والتي تنتهي في ملف CMake الثنائي هي نسبية في بيان Ninja ، ومخرجات deps بواسطة IAR مطلقة.

بالنسبة لي ، من الواضح أن هذه مشكلة نينجا: لا ينبغي أن تحتوي على عقدتين لنفس الملف ، بغض النظر عن السبب.

لقد قرأت اقتراح bradking ، لكنني لا أفهم حقًا الجزء المتعلق بالروابط الرمزية ولماذا لا يمكن استخدام getcwd() . هل تمانع في التفصيل؟

لا أفهم حقًا الجزء المتعلق بالروابط الرمزية ولماذا لا يمكن استخدام getcwd()

sebknzl المشكلة هي أن المسارات المطلقة المكتوبة إلى build.ninja بواسطة المولد قد تحتوي على روابط رمزية لم يتم حلها عن قصد لسبب أو لآخر. عادةً ما يقوم getcwd() بإرجاع مسار مع حل الارتباطات الرمزية. إذا قام Ninja بتفسير مسار نسبي في بيان البناء أو ملف depfile المرتبط بـ getcwd() ، فإن المسار المطلق الذي ينشئه قد لا يتطابق مع ما استخدمه منشئ بيان البناء وما زلنا ننتهي مع عقدتين.

إن ninja_workdir الذي أقترحه في الخيط الذي قمت بربطه هو إخبار Ninja بشكل أساسي بما استخدمه المولد كأساس للمسارات النسبية. من الناحية العملية ، يجب أن يكون realpath(ninja_workdir) == realpath(getcwd()) صحيحًا دائمًا ، لكن هذا لا يعني ninja_workdir == getcwd() . قد يكون البديل الآخر لـ Ninja هو الحصول على realpath كل شيء قبل إنشاء العقد ، لكن هذا يعني أن $in لن يتوسع إلى ما قصده المولد.

jhasse يرجى الاطلاع على هذه المشكلة واقتراحي لمعالجتها.

لماذا لا تنشئ _build.ninja_ بمسارات مطلقة يتحكم فيها CMAKE_NINJA_GENERATOR_OPTION_ ؟

أي مثل هذا ، والذي يعمل:

Claus-MBP:build clausklein$ cat build.ninja 

# project dir
p = /Users/clausklein/Downloads
# object dir
o = /Users/clausklein/Downloads/.ninjatst.build

rule cp
  command = cp $in $out

rule cc
  depfile = $out.d
  deps = gcc
  command = cc -I$o -c $in -o $out -MD -MT $out -MF $out.d

# All absolute paths works
build all: phony $o/foo.o

# All absolute paths works
build $o/foo.h: cp $p/foo.h.in
  IN = $p/foo.h.in

# All absolute paths works
build $o/foo.o: cc $p/foo.c || $o/foo.h
  IN = "$p/foo.c"

default all

Claus-MBP:build clausklein$ 

تم إنشاؤه باستخدام ninjatst.bash.txt

ClausKlein حاولنا تعليم CMake لاستخدام المسارات المطلقة. اطلع على المناقشات التي ربطتها في https://github.com/ninja-build/ninja/issues/1251#issuecomment -282322776. أفضل عدم إضافة خيار يقول "قم بالأشياء بطريقة مختلفة تصلح بعض الحالات وتعطل البعض الآخر".

نحتاج حقًا إلى ميزة Ninja في الاقتراح الذي ربطته في https://github.com/ninja-build/ninja/issues/1251#issuecomment -487618865 لإصلاح ذلك بشكل صحيح.

حسنا جيد

ثم هل سيكون هذا الإصلاح لنظام mesonbuild متاحًا أيضًا ؛-)

صباحا 12.03.2020 أم 12:56 سكريب براد كينج [email protected] :

ClausKlein https://github.com/ClausKlein حاولنا تعليم CMake لاستخدام المسارات المطلقة. اطلع على المناقشات التي ربطتها في # 1251 (تعليق) https://github.com/ninja-build/ninja/issues/1251#issuecomment-282322776 . أفضل عدم إضافة خيار يقول "قم بالأشياء بطريقة مختلفة تصلح بعض الحالات وتعطل البعض الآخر".

نحتاج حقًا إلى ميزة Ninja في الاقتراح الذي ربطته في # 1251 (تعليق) https://github.com/ninja-build/ninja/issues/1251#issuecomment-487618865 لإصلاح ذلك بشكل صحيح.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو قم بعرضها على GitHub https://github.com/ninja-build/ninja/issues/1251#issuecomment-598146822 ، أو قم بإلغاء الاشتراك https://github.com/notifications/unsubscribe-auth/AAN7QWWEDHMDA45DQVPLOUDRHDEVDANCN6GAM4DQVPLOUDRHDEVDANCN6GA

لنفترض أن Ninja سيستخدم ninja_workdir لمطابقة معلومات depfile ولدينا الحالة التي يكون فيها ninja_workdir != getcwd() بسبب ارتباط رمزي. ماذا لو قام المترجم بطباعة المسارات المطلقة باستخدام getcwd() ؟

يجب ألا يستخدم المترجم getcwd() لأي شيء ما لم يتم تمرير هذه الأشياء كمسارات نسبية ، وفي هذه الحالة من المحتمل أن يحتاج منشئ نظام البناء إلى تحمل المسؤولية.

أو يمكننا التفكير في محاولة تطبيع كل من ninja_workdir و getcwd() .

حسنًا ، يجب ألا يقوم المترجم بإرجاع مسار مطلق في الملف عند إعطاء مسارات نسبية ؛)

ClausKlein حاولنا تعليم CMake لاستخدام المسارات المطلقة. اطلع على المناقشات التي ربطتها في # 1251 (تعليق). أفضل عدم إضافة خيار يقول "قم بالأشياء بطريقة مختلفة تصلح بعض الحالات وتعطل البعض الآخر".

ما الذي حدث بالضبط عندما استخدمت المسارات المطلقة كما اقترحهClausKlein؟

إذا تم إعطاء المترجم مسارات مطلقة ، فإن الملف الذي ينشئه له مسارات مطلقة ، ولا يتم التوفيق بينها مع المسارات النسبية للعناوين في بيان البناء ، على سبيل المثال للعناوين التي تم إنشاؤها. شاهد الرابط ninja-bug.bash.txt في أول مشاركة لي أعلى هذه المشكلة. إنه يعرض مثالًا خطوة بخطوة لما يحدث ويتم التعبير عنه تمامًا من حيث النينجا وليس CMake.

لقد قرأت ذلك ، ولكن لماذا لا تستخدم https://github.com/ninja-build/ninja/issues/1251#issuecomment -284533599؟ ببساطة لأن النينجا "يثبط" المسارات المطلقة؟ إذا كان الأمر كذلك ، فهذا يتعلق بتغيير الوثائق؟

ملفات build.ninja أصغر بكثير بدون تكرار المسارات المطلقة في كل مكان ، وهذا يجعلها أسرع. كما أنها تبدو أجمل وأسهل في تصحيح الأخطاء وتكون أكثر ملاءمة لإكمال علامات الجدولة لأسماء أهداف الإنشاء في القذائف. IMO إنها توصية جيدة لنينجا. يحتاج Ninja فقط إلى مزيد من المعلومات لتسوية هذه الحالة ، وهذا ما أقترحه.

قد لا تكون المسارات النسبية لـbradking قصيرة دائمًا:

build jsoncpp@sha/src_lib_json_json_reader.cpp.o: cpp_COMPILER ../../../../../Users/clausklein/Workspace/cpp/jsoncpp/src/lib_json/json_reader.cpp
 DEPFILE = jsoncpp@sha/src_lib_json_json_reader.cpp.o.d
 ARGS = -Ijsoncpp<strong i="7">@sha</strong> -I. -I../../../../../Users/clausklein/Workspace/cpp/jsoncpp -I../../../../../Users/clausklein/Workspace/cpp/jsoncpp/include -I../../../../../Users/clausklein/Workspace/cpp/jsoncpp/dir1 -I../../../../../Users/clausklein/Workspace/cpp/jsoncpp/dir2 -fdiagnostics-color=always -pipe -Wall -Winvalid-pch -Wnon-virtual-dtor -std=c++17 -O3

يبدو المثال الخاص بي https://github.com/ninja-build/ninja/issues/1251#issuecomment -597877775 أجمل!

مولدات CMake لديها قاعدة حول عدم استخدام ../ التسلسلات التي تترك شجرة البناء. في البنيات خارج المصدر بالكامل ، نستخدم مسارات مطلقة لشجرة المصدر والمسارات النسبية داخل شجرة البناء. لم يبدأ الأخير في ../ لأنهم يقعون تحت شجرة الإنشاء.

أعلم أنه تم إنشاؤه باستخدام _mesonbuild_ . ؛-)

ولكن لماذا لا نحرم الجيل في مصدر شجرة؟

يمكننا مناقشة مزايا المسارات النسبية مقابل المطلقة إلى الأبد. النينجا لا ينبغي أن يكون رأيه في ذلك. تكمن المشكلة هنا في تسوية الحالات حيث يتم استخدام كليهما في بنية واحدة. لا يستطيع منشئ نظام البناء التحكم دائمًا في ما ستفعله الأدوات بالمسارات. يجب أن يدعم Ninja المسارات المطلقة / النسبية المختلطة لنفس الملف ويمكنه القيام بذلك باستخدام نهج بسيط أشرت إليه في اقتراحي. بالنسبة لحالة الاستخدام المحفزة ، يتم عزل التغييرات لتحليل Depfile.

يجب أن يدعم Ninja المسارات المطلقة / النسبية المختلطة لنفس الملف

أنا موافق!

شكرا لجميع التفسيرات ، لقد بدأت أفهم.

ماذا لو كان Ninja (عند مواجهته مسارًا مطلقًا في ملف depfile) هو المسار الحقيقي لكل من cwd والمسار الذي وجده؟ ثم يقوم بإزالة cwd الممارس الحقيقي من مسار depfile الحقيقي للحصول على المسار النسبي لمطابقة الرأس الذي تم إنشاؤه. هل هذا العمل؟

دائمًا ما يكون getcwd() مسارًا حقيقيًا بالفعل ، لذا فإن هذه الخطوة ليست ضرورية. إذا كان Ninja سيقوم بـ realpath() المسار المطلق المقدم من depfile وتحقق من بادئة cwd التي يمكن أن تعمل. ومع ذلك ، فإن realpath() عبارة عن مكالمة نظام ربما تكون باهظة الثمن بينما يمكن لـ ninja_workdir المقترح أن يوفق بين المسارات الموجودة في الذاكرة تمامًا عبر معالجة السلسلة.

يجب أيضًا السماح بالاختلاط في الاتجاه الآخر: مسار مطلق في بيان البناء ولكن مسار نسبي في الملف. لا أعتقد أنه يجب على Ninja أن يقوم بـ realpath() لكل مسار مطلق أثناء تحليل build.ninja . من المحتمل أن يكون ذلك بطيئًا.

يمكننا استخدام النتيجة لتحديد مكان العمل. على سبيل المثال:

getcwd (): /var/xyz/build
إدخال depfile: /home/foo/build/bar.h
realpath (إدخال depfile): /var/xyz/build/bar.h
المسار الحقيقي النسبي: bar.h
إزالة ذلك من إدخال depfile: /home/foo/build -> ninja_workdir

بهذه الطريقة نحتاج فقط إلى استدعاء المسار الحقيقي مرة واحدة.

لا أعتقد أن اشتقاق ninja_workdir ممكن بشكل عام. كيف نعرف عدد المكونات المنطقية للمسار المنطقي الأصلي المحتوي على ارتباط رمزي التي تتوافق مع دليل العمل؟ قد نكون قادرين على القيام بذلك عن طريق أخذ مكون واحد في كل مرة حتى يتطابق مساره الحقيقي مع cwd ، لكن هذا يشعر بالتطفل وعرضة للخطأ. من الخطورة الوثوق بأول ارتباط رمزي يحدث ليبدو هكذا. كما سيتعين علينا تشغيل المسار realpath () على كل مسار مطلق نواجهه حتى يتم حل هذه المشكلة بهذه الطريقة.

يعرف مُنشئ buildsystem تمامًا المسار المنطقي إلى مساحة العمل التي يستخدمها عند إنشاء مسارات مطلقة في عبارات الإنشاء وأسطر الأوامر في build.ninja . لذلك فهو المصدر الأكثر موثوقية للمعلومات لمسار العمل. نحتاج فقط إلى طريقة لإيصال هذه المعلومات إلى Ninja ، ومن هنا اقترحت ربط ninja_workdir .

أنا لست متأكدًا من فهمي ، آسف. هل يمكنك إعطاء مثال حيث لا يعمل منطق الاكتشاف الخاص بي؟

يمكن أن ينكسر إذا وضع منشئ نظام البناء رابطًا رمزيًا داخل شجرة البناء (مشيرًا إلى مكان آخر في شجرة البناء أو بالخارج تمامًا):

getcwd (): /var/xyz/build
إدخال depfile: /home/foo/build/subdir-link/bar.h
realpath (إدخال depfile): /var/xyz/build/subdir-real/bar.h
المسار الحقيقي النسبي: subdir-real/bar.h
إزالة ذلك من إدخال depfile: ؟؟؟

CMake لا يفعل هذا ولكن بشكل عام يمكن لمولد بناء النظام.

حتى لو كنا على استعداد لقول هذا غير مدعوم ، فقد يظل الاكتشاف يواجه:

getcwd (): /var/xyz/build
1000 إدخال depfile: /home/foo/ext-lib/bar{1,2,...}.h
1000 مسار حقيقي (إدخالات Depfile): /var/xyz/ext-lib/bar{1,2,...}.h
1000 مسار حقيقي نسبي: لا شيء تحت cwd

تخيل الآن أن هذا يظهر في 1000 مصدر من depfiles ولا توجد إصابة أبدًا. هذا هو 1 مليون مكالمة realpath () مع عدم وجود تطابق لهذا الكشف عن مجريات الأمور. وهذا يتكرر في كل مرة يعاد بناء المصدر ويعاد تحليل ملفه.

رابط رمزي داخل شجرة البناء -> نعم ، لا يمكننا دعم ذلك حقًا ، سينتج عنه جميع أنواع المشكلات الأخرى على أي حال (بدون المسار الحقيقي في كل مكان).

المثال الثاني يبدو مصطنعًا إلى حد ما. تبدأ عادةً depfiles بالتبعية المحلية ، وليس برؤوس النظام.

إذا اتضح أنها مشكلة في الأداء حقًا ، فيمكننا تخزين مساحة العمل مؤقتًا في .ninja_deps ؟

في بناء خارج المصدر ، سيشير عدد قليل جدًا من إدخالات depfile إلى شجرة البناء. سيكون هذا شائعًا جدًا:

getcwd (): /var/xyz/build
1000 إدخال depfile: /home/foo/project-source/bar{1،2،...}.h
1000 مسار حقيقي (إدخالات depfile): /var/xyz/project-source/bar{1،2،...}.h
1000 مسار حقيقي نسبي: لا شيء تحت cwd

سيتعين على Ninja الاتصال بـ realpath() على كل هذه الحالات فقط ، أو الاحتفاظ بنوع من جدول النتائج لتجنب عمليات التسجيل الفعلية. لا يمكنه أن يعرف مسبقًا متى سيواجه مسار ارتباط رمزي يتحول إلى cwd ، ولا يعرف حتى ما إذا كان سيجد واحدًا أم لا.

بالنظر إلى أن الخلط بين المسارات المطلقة والواقعية في ملف depfile لا يعمل حاليًا ، لا أرى كيف سيكون ذلك "شائعًا جدًا" ؟؟

إن depfiles من النموذج الموجود في المثال الخاص بي شائع جدًا بالفعل حتى عند عدم استخدام الروابط الرمزية أو المسارات المختلطة. لديّهم في معظم أشجار البناء الخاصة بي. لا يستطيع Ninja معرفة ما إذا كانت هناك حاجة إلى الكشف عن مجريات الأمور في وقت مبكر ، لذلك سيتعين عليه حظر عمليات syscalls realpath() في حالة حدوث ذلك.

ربما أسأت فهم مثالك. هل تقصد ملفًا واحدًا يحتوي على 3000 إدخال أم أن هذه الأمثلة الثلاثة المنفصلة عن depfiles مع 1000 إدخال لكل منها؟

قصدت 1000 إدخال depfile منتشرة عبر أي عدد من depfiles. يمكن أن تكون واحدة. يمكن أن يكون كثير. يمكن أن يكون هناك 10000 إدخال عبر المشروع. يمكن أن تشير مساراتهم إلى أي مكان على نظام الملفات وقد تشير أو لا تشير فعليًا إلى شجرة البناء.

هل يمكنك إعطاء مثال CMakeLists.txt ينتج عنه مزيج من المسارات (ليس بالضرورة أن يكون 1000 ، واحد فقط من كل منهما)؟

من الصعب أن تظهر في ملف CMakeLists.txt لأن CMake حريص حاليًا على تجنب اختلاط المسارات في معظم الحالات. ومع ذلك ، هناك مشكلات في أداة تعقب مشكلات CMake حول المشكلات التي لا يمكن حلها دون إصلاح Ninja هذا أولاً. انظر على سبيل المثال إصدار CMake 13894 . يريد المستخدمون أن يكونوا قادرين على إعطاء مسارات مطلقة للمترجم حتى بالنسبة للمصادر (وربما تضمين الدلائل) في شجرة البناء ، أو عند القيام بالبنيات داخل المصدر. هذا يعمل بشكل جيد مع مولد Makefile الخاص بـ CMake. إذا فعلنا ذلك مع Ninja ، فعندئذٍ يعود depfiles بمسارات مطلقة ولا يتطابقون مع المسارات النسبية في build.ninja . ربما يمكننا التبديل إلى المسارات المطلقة لكل شيء ، ولكن كما تمت مناقشته أعلاه هنا لا ينبغي علينا القيام بذلك.

ربما يمكنك تجربة هذا للاختبارات https://github.com/ClausKlein/build-performance/commit/8013836486e3a459474eb374f6c3da5e20983443

تعتمد المشكلة الموضحة هنا على https://github.com/ninja-build/ninja/issues/1251#issue -210080507
إنه يولد أكبر قدر من الهدف كما تريد. على سبيل المثال 2 subduers مع 2 ملف المصدر:

PWD=/Users/clausklein/Workspace/build-performance/build

rule cp
  command = cp $in $out

rule cc
  depfile = $out.d
  deps = gcc
  command = gcc -c -I$PWD $IN -o $out $FLAGS -MMD -MT $out -MF $out.d

rule link
  command = gcc -o $out $in $LINK_PATH $LINK_LIBRARIES

build foo: phony foo.h
build foo.h: cp foo.h.in

build bin/main0.o: cc /Users/clausklein/Workspace/build-performance/build/subdir0/main.c || foo.h
  IN = /Users/clausklein/Workspace/build-performance/build/subdir0/main.c
build /Users/clausklein/Workspace/build-performance/build/subdir0/file0.o: cc /Users/clausklein/Workspace/build-performance/build/subdir0/file0.c || foo.h
  IN = /Users/clausklein/Workspace/build-performance/build/subdir0/file0.c

build bin/main1.o: cc /Users/clausklein/Workspace/build-performance/build/subdir1/main.c || foo.h
  IN = /Users/clausklein/Workspace/build-performance/build/subdir1/main.c
build /Users/clausklein/Workspace/build-performance/build/subdir1/file0.o: cc /Users/clausklein/Workspace/build-performance/build/subdir1/file0.c || foo.h
  IN = /Users/clausklein/Workspace/build-performance/build/subdir1/file0.c

build bin/main0: link bin/main0.o /Users/clausklein/Workspace/build-performance/build/subdir0/file0.o 
build bin/main1: link bin/main1.o /Users/clausklein/Workspace/build-performance/build/subdir1/file0.o 

build all: phony foo bin/main0 bin/main1 
default all

هذا يعمل بشكل جيد مع مولد Makefile الخاص بـ CMake.

كيف يتم التعامل مع مشكلة الارتباط الرمزي؟

كيف يتم التعامل مع مشكلة الارتباط الرمزي؟

لا يستخدم منشئ Makefile حاليًا depfiles ويقوم بمسح تقريبي خاص به. من المحتمل أن يتم تحديث ذلك كجزء من إضافة دعم وحدات C ++ 20 لمولد Makefile ، وعند هذه النقطة سيتعين التوفيق بين تفسير مسارات depfile بشكل مشابه لما هو مقترح هنا.

أحد الخيارات هو تخطي ninja_workdir في الوقت الحالي وتعليم Ninja على الأقل التوفيق بين المسارات المختلطة بافتراض أن getcwd() هو الأعلى. بهذه الطريقة ستعمل المسارات المختلطة على الأقل في حالة عدم وجود ارتباط رمزي. ثم يمكن إضافة ninja_workdir لدعم الحالات الأكثر تعقيدًا لاحقًا.

مناشدات شخص ما إصلاح هذا. أنا منزعج للغاية بسبب هذا.

أنا أستخدم ARM-GCC مع CMake و VSCode. عندما أستخدم بنية داخل المصدر ، تكون المسارات مرتبطة بدليل "الإنشاء" (بدلاً من الدليل الجذر) ، مما يتسبب في عدم تمكن VSCode من حل المسارات ، مما يعني أنه لا يمكنك النقر فوق الزر مسارات في نافذة سطر الأوامر ، بدلاً من ذلك ، عليك تحديد موقع كل ملف بنفسك. عندما أستخدم بناء خارج الشجرة CMake ، فإنه يكسر "التحسس الذكي" من Eclipse ويحدث مشاكل مع المشاريع الفرعية CMake. الحل الآن هو استخدام MakeFiles ، لأنه يستخدم مسارات مطلقة لكل افتراضي. لكن Ninja أفضل ، فهو ينتج ملفات قابلة للقراءة بشكل أفضل (rules.ninja ...) وإخراج البناء في سطر الأوامر أفضل. جعل لديه مشاكل مع إخراج التحذيرات على سطر الأوامر في سياق متعدد مؤشرات الترابط ، يعني ، تحذيرات متعددة معشق. وهو ما يجعلني أقوم ببناء خيوط مفردة ، وهو أمر مزعج للغاية مرة أخرى.

مناشدات شخص ما إصلاح هذا. أنا منزعج للغاية بسبب هذا.

أنا أستخدم ARM-GCC مع CMake و VSCode. عندما أستخدم بنية من داخل المصدر ، تكون المسارات مرتبطة بدليل "الإنشاء" ...

يوجد حل بديل: اختر مسار البناء خارج شجرة المصدر! على سبيل المثال _ $ TMPDIR /..._

شكرًا لك ClausKlein ، لكن الحل البديل هو بناء خارج المصدر ، لكنني بحاجة إلى الملفات داخل شجرتى ، لأنه تمت الإشارة إليها بواسطة نصوص أخرى. كما أنه شرط بناء غير قياسي.

الحل الآن هو تغيير CMake لاستخدام المسارات المطلقة دائمًا. لا أفهم لماذا لا يوجد خيار لهذا. ومع ذلك ، إذا احتاج شخص آخر إلى هذا ، فإليك تصحيح CMake v3.18.1:

@@ -241,7 +241,7 @@ void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
   // Add include directory flags.
   std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
     includes, this->GeneratorTarget, language,
-    language == "RC", // full include paths for RC needed by cmcldeps
+    true, // full include paths for RC needed by cmcldeps
     false, config);
   if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
     std::replace(includeFlags.begin(), includeFlags.end(), '\\', '/');
@@ -1133,8 +1133,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   const std::string& fileConfig, bool firstForConfig)
 {
   std::string const language = source->GetLanguage();
-  std::string const sourceFileName =
-    language == "RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
+  std::string const sourceFileName = source->GetFullPath();
   std::string const objectDir = this->ConvertToNinjaPath(
     cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
              this->GetGlobalGenerator()->ConfigDirectory(config)));

انتبه ، كان هناك تصحيح لـ cmake ، لكن انظر https://github.com/ninja-build/ninja/issues/1251

نحن بحاجة إلى رقعة النينجا!

في تعليقي الأخير ، عرضت تصحيحًا لـ CMake لاستخدام المسارات المطلقة بدلاً من المسارات النسبية. تبين أن هذه فكرة سيئة ، لأنها تكسر اعتمادات رأس CMake المخصصة مع Ninja (على سبيل المثال ، يعتمد ملف الرأس الذي تم إنشاؤه على ملف .json). أعتقد أن هذه المشكلة تنبع من هذه القضية هنا ، والتي كنت غبيًا جدًا لفهمها.

إذا كان شخص ما مهتمًا بها ، فأنا الآن أستخدم Ninja مع المسارات النسبية. لقد أنشأت امتدادًا لـ VSCode لتتمكن من النقر فوق المسارات النسبية داخل الجهاز الطرفي المتكامل. إطالة

تضمين التغريدة هل توجد أي فرصة لتشغيله في علامة التبويب Output أيضًا؟

weliveindetail لا تتردد في إنشاء إصدار جديد على https://github.com/GrandChris/TerminalRelativePath/issues ووصف حالة الاستخدام الخاصة بك بالتفصيل. لكن علامة تبويب الإخراج في VSCode تتصرف بشكل مختلف عن المحطة المتكاملة ولا أعتقد أن هناك واجهة برمجة تطبيقات لتوسيع السلوك في هذا الصدد.

حسنا، شكرا. في النهاية ، من المحتمل أن يتم حل المسارات النسبية القابلة للنقر في VSCode أو امتداد CMake. سوف ping على جانبهم.

للإشارة ، ظهر هذا مرة أخرى في CMake Issue 21865 . إنه مثال آخر لحالة ليس فيها من السهل (ممكن؟) جعل التبعيات المكتشفة تستخدم نفس تمثيل المسار تمامًا مثل build.ninja .

يضيف 1917 الربط ninja_workdir المقترح أعلاه كميزة مفيدة بحد ذاتها. بمجرد دمج ذلك ، يمكنني المتابعة بإصلاح هذه المشكلة.

jhasse ، أود أن أتوصل إلى حل مقبول لإصلاح هذا في المنبع. ninja_workdir يحل المشكلة. لقد جادلت حالتي أعلاه. ما البديل الآخر الذي تقترحه؟

كما أشرت إلى المشكلة (خلط المسارات المطلقة لـ depfile مع المسارات النسبية الواضحة فواصل إعادة البناء) هي حسب التصميم. أعتقد أننا يجب أن نخلق المزيد من القضايا المحددة ، لأننا تطرقنا إلى العديد من القضايا في المناقشة (مثل ربط مسار البناء).

بالنسبة لحالتي الاستخدام في التعليق الأولي ستكون بدائلي:

ينتج عن هذا إخراج أفضل لـ IDEs لمطابقة رسائل الخطأ والرجوع إلى الملفات الأصلية.

إما أن تقوم بإصلاح IDE ، أو تمرير /FC أو -fabs-path-diagnostics إلى المترجم.

قد يؤثر أيضًا على المسارات المسجلة في معلومات التصحيح.

يجب أن يتم إصلاح هذا أيضًا بواسطة المترجم. أود أن أقترح النظر إلى -fdebug-prefix-map ، لكنني لست متأكدًا من المشكلة بالضبط.

إليك نص برمجي يوضح المشكلة: ninja-bug.bash.txt

ليس في الحقيقة ، إنه يوضح سلوك النينجا الحالي. المسألتان

  1. "لا يمكن أن يتطابق IDE الخاص بي مع إخراج المترجم مع الملف الصحيح"
  2. "أحتاج إلى مسارات مطلقة في معلومات التصحيح"

بحاجة الى مزيد من الشرح. بخلاف ذلك ، تبدو هذه مشكلة XY بالنسبة لي (X هي "خلط المسارات المطلقة والنسبية" و Y هي إما 1. أو 2.).

لا أعتقد حقًا أن الحل يجب أن يكون "الالتفاف حول هذا في جميع الأدوات الأخرى".

يوضح عام 1924 إصلاحًا كاملًا للعمل مع الاختبارات ، بناءً على نهج ninja_workdir . يمكن للمولد الذي يستخدم هذا حل جميع المشكلات المذكورة أعلاه.

وأنا كذلك ، لأنني لا أرى هذه كحلول بديلة.

هذه ليست خيارات جنو دول مجلس التعاون الخليجي!

Am 05.03.2021 um 16:58 schrieb Jan Niklas Hasse [email protected] :

إما إصلاح IDE ، أو تمرير / FC https://docs.microsoft.com/de-de/cpp/build/reference/fc-full-path-of-source-code-file-in-diagnostics أو -fabs- تشخيص المسار https://reviews.llvm.org/D23816 للمترجم.

قد يؤثر أيضًا على المسارات المسجلة في معلومات التصحيح.

إليك نص برمجي يوضح المشكلة: ninja-bug.bash.txt

ليس في الحقيقة ، إنه يوضح سلوك النينجا الحالي.

تدوّن رسالتي التي نقلت عنها أن هذا هو السلوك الموثق حاليًا.
الغرض من هذه المشكلة هو التشكيك في التصميم
إظهار فئة من حالات الاستخدام التي لا تخدمها.

المسألتان ... (1) ... (2) ... بحاجة إلى مزيد من الشرح.

هذان مثالان فقط على المشاكل التي يسهل حلها
تمرير المسارات المطلقة للأدوات. المسارات المطلقة ليست غير معقولة
فقط لأن الحلول الأخرى متوفرة في حالات محددة من هذا القبيل
المشاكل (باستخدام ميزات محددة للأدوات المتاحة من بعض البائعين).
تساعد المسارات المطلقة في حل فئة كبيرة من هذه المشكلات بدون تحديثات
لبقية النظام البيئي. كما نشرت سابقًا :

يمكننا مناقشة مزايا المسارات النسبية مقابل المطلقة إلى الأبد. يجب على النينجا
لا يكون رأي في ذلك. المشكلة هنا هي التوفيق بين الحالات
كلاهما يستخدم في بناء واحد. لا يمكن لمنشئ نظام البناء دائمًا
التحكم في ما ستفعله الأدوات بالمسارات.

في أنظمة البناء المعقدة في العالم الحقيقي ، يمكن أن يكون هناك عدد عشوائي من الطبقات
من البرامج النصية ، والغلافات ، والأدوات ، وما إلى ذلك ، (من جميع أنواع البائعين) بين
المسارات المكتوبة بـ build.ninja بواسطة منشئ ملف البناء والمسارات الفعلية
واجهه النينجا في ملف. في بعض الأحيان يمكن الرجوع إلى ملف معين بواسطة
ملف depfile من أداة لم يتم إعطاء مسار مباشر لها من build.ninja .
لكي يعمل depfiles تحت التصميم الحالي لـ Ninja ، فإن الأدوات بأكملها
يجب إخبار المكدس بالضبط كيف يختار المولد build.ninja التعبير
تلك المسارات في عبارات البناء ، ولها ميزات تحافظ عليها أو تحولها
لهم بنفس الطريقة. هذا لا يمكن تتبعه بشكل عام.

يمكن لـ Ninja حل هذه المشكلة بتغيير بسيط في التصميم: التوفيق بين ملف
المسار المطلق في ملف مع مسار نسبي في build.ninja (والعكس
بالعكس). أنا لا أطلب التوفيق بين المسارات التعسفية لنفس الملف ، فقط ل
تعرف على أن /path/to/some/file في ملف depfile هو نفسه some/file في
ملف البناء /path/to/build.ninja .

هناك سابقة لمثل هذه التحديثات التصميمية. عندما بدأ Ninja لأول مرة ، كان الأمل
هو أن المسارات ستواجه دائمًا ninja بنفس الطريقة تمامًا
تمثيل بايت مقابل بايت كتب فيه منشئ ملف الإنشاء
build.ninja . قم بتشغيل git blame -M -C -w -- src/util.cc وانظر إلى السجل
من CanonicalizePath لمشاهدة سلسلة من الحالات التي تمت مواجهتها فيها
كان لابد من الاسترخاء في فلسفة التصميم. هذه فئة أخرى من مثل هذه الحالات.

الشيء الذي أختلف معه

النينجا لا ينبغي أن يكون رأيه في ذلك.

في المقام الأول.

هذا لا يمكن تتبعه بشكل عام.

إذن ما هي القضية المحددة؟ آسف أنا مرتبك بعض الشيء.

أنا أختلف مع "النينجا لا يجب أن يكون رأيها في ذلك" في المقام الأول .... فما هي القضية بالتحديد؟

لا يتعلق الأمر بأي قضية محددة ، بل يتعلق بفئة كاملة من المشكلات التي يسهل حلها باستخدام المسارات المطلقة. لا يهم سبب رغبة المطورين في تمرير المسارات المطلقة إلى أدواتهم ، فقط أنهم يريدون استخدام المسارات المطلقة لأي أسباب تنطبق على حالتهم الخاصة. أنظمة البناء موجودة لخدمة مستخدميها ، وليس لإملاء السياسة. من المفترض أن تكون Ninja لغة تجميع لأنظمة البناء ، ومع ذلك لا توجد طريقة للتعبير عن أنظمة البناء باستخدام مسارات مختلطة الأنماط.

تتمثل سياسة Ninja في التغييرات الأولية في أنه يجب حل المشكلات عن طريق إنشاء مولدات ملفات ، وليس Ninja upstream ، إذا كان من الممكن حلها دون فقدان الكفاءة . في هذه الحالة ، الطريقة الوحيدة لتوفير مصالحة عامة للأغراض ninja_workdir -style لمسارات depfile من منشئ ملف البناء هي الحقن بعد كل أمر يولد depfile أمرًا إضافيًا لمراجعة المسارات في الملف لمطابقة ملف البناء قبل أن يقوم النينجا بتحميله. سيكون لهذا الأمر الإضافي تكلفة وقت التشغيل الخاصة به والتي هي أعلى بكثير مما يفعله # 1924 (عدد صغير من عمليات البحث الإضافية في الذاكرة داخل عملية ninja ). لذلك ، تعد تسوية الأغراض العامة أكثر فاعلية لتوفيرها في Ninja upstream ، وكذلك مرشح للتضمين.

حتى إذا كنت تستخدم مسارات مطلقة لكل شيء ، بدلاً من خلط المسارات المطلقة والنسبية ، فهناك مشكلة مزعجة تتعلق ببيئة العمل. إذا طلب المستخدم من ninja إعادة إنشاء ملف إخراج معين بدلاً من هدف زائف ، على سبيل المثال ، ninja out/my_executable أو ninja out/foo/bar.o ، فعليهم أن يتذكروا اجتياز المسار المطلق ، أو النينجا ستفشل بخطأ مربك "هدف غير معروف". المشكلة المعاكسة موجودة أيضًا: قد يطلب المستخدم من النينجا إعادة بناء مسار مطلق عندما يستخدم ملف build.ninja مسارات نسبية.

في إحدى أدوات منشئ Ninja التي أحتفظ بها ، أعمل على حل هذه المشكلة من خلال تضمين كل عبارة build كلاً من المسار النسبي والمسار المطلق المقابل كمخرجات. إنه يعمل ، لكنه يبدو حقًا وكأنه اختراق للتغلب على قيود في Ninja. (تحرير: أيضًا ، إذا كان build.ninja يستخدم المسارات النسبية فقط وبالتالي لا يزال بإمكانه العمل بعد نقله إلى مسار مطلق مختلف ، فإن إضافة أسماء مستعارة للمسار المطلق ستؤدي إلى كسر هذه القدرة.)

من المسلم به أن هذه ليست بالضبط نفس المشكلة مثل depfiles ، لكنها تشير إلى أن Ninja يجب أن يكون أكثر وعياً بمعادلات المسار المطلق مقابل معادلات المسار النسبي بشكل عام.

comex شكرًا ، هذا مصدر قلق صالح. هل يمكنك فتح عدد جديد لذلك؟

لا يهم سبب رغبة المطورين في تمرير مسارات مطلقة إلى أدواتهم [...]

أنا أعترض.

في هذه الحالة ، الطريقة الوحيدة لتوفير تسوية عامة للأغراض ninja_workdir -style لمسارات depfile [...]

لماذا تحتاج إلى تسوية على طراز ninja_workdir في المقام الأول؟

لماذا تحتاج إلى المصالحة على غرار ninja_workdir في المقام الأول؟

يسمح للمطورين باستخدام المسارات النسبية في build.ninja مع الاستمرار في التعامل مع المسارات المطلقة التي تم إنشاؤها في depfiles عن طريق الأدوات التي لا يتحكمون فيها. خلاف ذلك ، قد يضطرون إلى استخدام المسارات المطلقة في build.ninja من أجل استيعاب مثل هذه الأدوات جنبًا إلى جنب مع قيود النينجا حسب التصميم. اقتراحي لا يمنع استخدام المسارات النسبية. يتيح المزيد من استخدامها.

لقد فتحت # 1925 لتنفيذ نفس التسوية مثل # 1924 ، لكن بدون ربط ninja_workdir . يفصل ذلك بين قرار التوفيق بين مسارات depfile وقرار دعم مسارات العمل المنطقية ذات الروابط الرمزية.

[...] المسارات المطلقة التي تم إنشاؤها في depfiles بواسطة الأدوات التي لا يتحكمون فيها.

هل هناك مثال لمثل هذه الأدوات؟

لا يمكننا توقع سلوك جميع الأدوات التي يستخدمها الجميع في العالم. حتى بالنسبة للأدوات التي نتحكم فيها ، فقد ناقشنا بالفعل العديد من الحالات المذكورة أعلاه والتي يسهل حلها باستخدام مسارات مطلقة ، ولكنها تتطلب خيارات خاصة بالأداة وقدرًا كبيرًا من العناية لحلها باستخدام المسارات النسبية. يفضل CMake المسارات المطلقة في عدة حالات لأسباب مماثلة. لدي العديد من تقارير الأخطاء حول منشئ Ninja الذي لا يفعل ذلك بينما تفعل جميع المولدات الأخرى. لقد أمضيت عدة مرات ساعات في تعقب مشكلة التبعيات فقط لأجد أن هذا هو مثال آخر على عدم تسوية مسارات depfile مع إنشاء مسارات واضحة. توفر الأدوات المعلومات التي يحتاجها Ninja لالتقاط التبعيات ، لكن Ninja يتجاهلها.

يأتي موقفك كرأي مفاده أن المسارات النسبية أفضل عالميًا. لدى البعض الآخر رأي مختلف في أن المسارات المطلقة أفضل في بعض الحالات. لا أعتقد أنه مكان أداة البناء لتبشير المسارات النسبية.

يضيف اقتراحي قدرًا صغيرًا من البنية التحتية إلى Ninja. ماذا يؤلم؟ عدم وجودها يؤدي إلى تكلفة أكبر بكثير.

نعم هذا صحيح!

وباستخدام المسارات المطلقة ، يكون cmake قادرًا على التخلص من مسارات تضمين المحول البرمجي المكررة.
هذا يقلل من وقت البناء مرة أخرى.

صباحا 09.03.2021 أم 19:20 schrieb Brad King [email protected] :

لا أعتقد أنه مكان أداة البناء لتبشير المسارات النسبية.

لقد قمت بإعداد مشكلة CMake فيما يتعلق بمشكلة نواجهها مع برنامج التحويل البرمجي السريع لـ Qt الذي أنشأ ملفات cpp وتمكين بناء الوحدة. أظهرت تحقيقاتي المحلية أن النينجا هو أسرع نظام بناء ، لكن في هذه الكوكبة لا يمكن الاعتماد عليه. أواجه الآن مشكلة كيف يمكنني إيجاد حل بديل أو تبرير زيادة وقت الإنشاء.

واجه CMake للتو مشكلة في التبعيات الدائرية التي كانت ، حتى وقت قريب ، ملثمة بمشكلة Ninja هذه. إذا تم إصلاح هذه المشكلة ، لكنا اكتشفنا مشكلة CMake في وقت أقرب.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات