كيف يمكنني تحديد في نص makefile.am أنني أريد فقط تجميع ملفات .o الكائن؟
سؤال
انا املك Makefile.am
التي ستكون مسؤولة عن بناء تطبيق ثنائي نهائي:
project/src/Makefile.am
أيضا في دليل SRC هو دليل فرعي يسمى ctrnn
الذي يحتوي على إضافية Makefile.am
:
project/src/ctrnn/Makefile.am
حاليا، ctrnn/Makefile.am
يجب أن يولد الكائن فقط .o
ملفات مع الفكرة هي أن المستوى الأعلى Makefile.am
يجب استخدام ملفات الكائنات التي تم إنشاؤها في الدليل الفرعي ctrnn
لبناء الثنائي.
هذا ال ctrnn/Makefile.am
:
SOURCES = network.cpp\
neuron.cpp
AM_CPPFLAGS= @CXXFLAGS@
بناء على هذا Makefile.am
ملف ، أريد أن ينتهي مع network.o و neuron.o. أنا أنشأ حسب Makefile
باستخدام Automake وما إلى ذلك ، ولكن عندما أحاول ثم تنفيذ ملف Make ، فإنه لا يفعل أي شيء ويقول فقط:
make: Nothing to be done for `all'
أعرف لماذا هذا ، أحتاج إلى تحديد هدف البناء. لكن كيف أفعل هذا في ctrnn/Makefile.am
بالنظر إلى أنني لا أريد بناء ثنائي يتطلب bin_PROGRAMS
لكن ملفات الكائن الفعلية network.o
و neuron.o
?
(لاحظ إذا قمت بتحديد اسم Bin_programs ، فإنه ينتهي بحق في شكوى من مرجع غير محدد إلى الرئيسي).
ماذا أفعل خطأ؟
المحلول
لا يمكن لـ Automake إنشاء كائنات بدون هدف صريح (البرنامج ، المكتبة) التي ستستخدم هذه الكائنات. أحد الأسباب هو أن خيارات التجميع محددة لكل هدف. إذا كان هناك هدفين ، على سبيل المثال ، يستخدم ثنائيان نفس الكائن ولكن لديهما خيار تجميع مختلف ، فقد يتعين تجميع نفس الكائن مرتين.
لديك ثلاث طرق للقيام بما تريد ، فهي تنطوي على ربط ملفاتك المصدر إلى بعض الهدف.
لا تستخدم أ
src/ctrnn/Makefile.am
, ، ما عليك سوى الإشارة إلى ملفات مصدر الدليل الفرعي منsrc/Makefile.am
:bin_PROGRAMS = foo foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
لاحظ أن هذا سيبنيnetwork.o
وneuron.o
في نفس الدليلmain.o
. إذا كنت تريد كائنات في الدلالات الفرعية ، فاستخدمAUTOMAKE_OPTIONS = subdir-objects
.استخدم مكتبة الراحة. في
src/crtnn/Makefile.am
اصنع مكتبة لكائتك:noinst_LIBRARIES = libcrtnn.a libcrtnn_a_SOURCES = network.cpp neuron.cpp
و فيsrc/Makefile.am
, ، قم بربط المكتبة القابلة للتنفيذ:bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = crtnn/libcrtnn.a SUBDIRS = crtnn
يطلق عليه "الراحة" عندما لا يتم تثبيته (يمكنك معرفة ذلك بسببnoinst_
بادئة): يتم استخدامه فقط أثناء البناء. وهذه مكتبة ثابتة ، وبالتالي فإن النتيجة هي نفسها كما لو كنت قد استبدلتcrtnn/libcrtnn.a
بواسطةcrtnn/network.o
وcrtn/neuro.o
عند الارتباطfoo
.استخدم مكتبة Libtool الراحة. هذا يتطلب المزيد من الإعداد إذا كنت لا تستخدم libtool بالفعل. يجب عليك إضافة مكالمة
LT_INIT
فيconfigure.ac
وإعادة تشغيلautoreconf
لتثبيت ملفات libtool. ثم يمكنك التحديثsrc/crtnn/Makefile.am
لتكوين مكتبة من كائديك على النحو التالي:noinst_LTLIBRARIES = libcrtnn.la libcrtnn_la_SOURCES = network.cpp neuron.cpp
وsrc/Makefile.am
كالآتي:bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = crtnn/libcrtnn.la SUBDIRS = crtnn
ماهو الفرق؟ قد تسأل ، لا شيء تقريبا. تتمثل إحدى ميزة استخدام مكتبات Libtool في أنه يمكن التداخل: يمكن أن تضم مكتبة Libtool مكتبة Libtool أخرى (هذا مناسب عندما يكون لديك تسلسل هرمي عميق للرمز المصدري وأنت تقوم ببناء مكتبة في كل مستوى). كما يمكن استخدام مكتبات Libtool لإنشاء مكتبة مشتركة إذا كنت تريد. لا يمكن لمكتبات Automake الثابتة.
نصائح أخرى
يمكنك ببساطة تحديد ملفات المصدر في Project/SRC/Makefile.am وليس لديك makefile.am في ctrnn:
maude_SOURCES = ctrnn/network.cpp ctrnn/neuron.cpp
أو يمكنك استخدام مكتبة Libtool الراحة. في ctrnn/makefile.am ، وضع:
noinst_LTLIBRARIES = libctrnn.la libctrnn_la_SOURCES = network.cpp neuron.cpp
وفي src/makefile.am ، ضع
LDADD = ctrnn/libmylib.la
إذا كنت لا تستخدم بالفعل libtool ، فستحتاج أيضًا إلى إضافة LT_INIT إلى Config.AC.
والأفضل من ذلك ، يمكنك فرض استخدام هدف أقل من المصدر عن طريق القيام بذلك:
SUBDIRS = sub1 sub2 …
lib_LTLIBRARIES = libtop.la
libtop_la_SOURCES =
# Dummy C++ source to cause C++ linking.
nodist_EXTRA_libtop_la_SOURCES = dummy.cxx
libtop_la_LIBADD = \
sub1/libsub1.la \
sub2/libsub2.la \
...
المرق السري هو nodist_EXTRA_xxxx_la_SOURCES
.
مزيد من التفاصيل هنا: https://www.gnu.org/software/automake/manual/html_node/libtool-convenience-libraries.html