دول مجلس التعاون الخليجي / ز ++ الخيار لوضع جميع الملفات الكائن في دليل منفصل

StackOverflow https://stackoverflow.com/questions/1814270

  •  06-07-2019
  •  | 
  •  

سؤال

وأنا أتساءل لماذا دول مجلس التعاون الخليجي / ز ++ لم يكن لديك الخيار لوضع الملفات الكائن ولدت في الدليل المحدد.

وعلى سبيل المثال:

mkdir builddir
mkdir builddir/objdir
cd srcdir

gcc -c file1.c file2.c file3.c **--outdir=**../builddir/objdir

وأنا أعلم أنه من الممكن و لتحقيق هذا مع خيارات -o منفصلة نظرا إلى مترجم، منها مثلا:

gcc -c file1.c -o ../builddir/objdir/file1.o
gcc -c file2.c -o ../builddir/objdir/file2.o
gcc -c file3.c -o ../builddir/objdir/file3.o

... وأنا أعلم أنني يمكن أن يكتب Makefiles عبر VPATH وvpath توجيهات لتبسيط هذا.

ولكن هذا الكثير من العمل في بيئة البناء المعقدة.

وأنا أيضا استخدام

gcc -c file1.c file2.c file3.c

ولكن عند استخدام هذه وجهة نظري srcdir مليء. س القمامة بعد ذلك.

لذلك أعتقد أن خيار مع دلالات --outdir سيكون مفيدا للغاية.

ما هو رأيك؟

تعديل : لمكتوبة Makefiles لدينا في مثل هذه الطريقة التي .O الملفات وضعت فعلا في builddir / الكائنات. لكنني ببساطة أتساءل عما اذا كان قد يكون هناك طريقة أفضل.

تعديل : لوهناك العديد من الطرق التي تضع عبئا على تحقيق السلوك المطلوب لبناء نظام (جعل الملقب، CMake الخ). ولكنني أرى كل منهم بأنها <م> الحلول لضعف دول مجلس التعاون الخليجي (وغيرها من جامعي أيضا).

هل كانت مفيدة؟

المحلول

وهذا هو قطعوا MAKEFILE لأحد مشاريعي، الذي يجمع مصادر في "SRC" ويضع الملفات .O في الدليل "الكائنات". بت الرئيسي هو استخدام وظيفة patsubst () - انظر GNU جعل اليدوي (الذي هو في الواقع قراءة جيدة) لمزيد من التفاصيل:

OUT = lib/alib.a
CC = g++
ODIR = obj
SDIR = src
INC = -Iinc

_OBJS = a_chsrc.o a_csv.o a_enc.o a_env.o a_except.o \
        a_date.o a_range.o a_opsys.o
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))


$(ODIR)/%.o: $(SDIR)/%.cpp 
    $(CC) -c $(INC) -o $@ $< $(CFLAGS) 

$(OUT): $(OBJS) 
    ar rvs $(OUT) $^

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o $(OUT)

نصائح أخرى

وماذا عن تغيير إلى الدليل وتشغيل الترجمة من هناك:

cd builddir/objdir
gcc ../../srcdir/file1.c ../../srcdir/file2.c ../../srcdir/file3.c

وهذا كل شيء. دول مجلس التعاون الخليجي وتفسير ويشمل النموذج #include "path/to/header.h" كما تبدأ في الدليل موجود الملف بحيث لا تحتاج إلى تعديل أي شيء.

وللمشكلة تافهة ولكنها فعالة لإضافة ما يلي مباشرة بعد دعوة دول مجلس التعاون الخليجي في ماكيفيلي الخاص بك:

mv *.o ../builddir/objdir

وأو حتى لينة نظيفة (ربما العودية) بعد الانتهاء من تجميع، مثل

rm -f *.o

أو

find . -name \*.o -exec rm {} \;

ويمكنك استخدام مجمع بسيط حول gcc من شأنها أن تولد الخيارات -o اللازمة وgcc المكالمة:

$ ./gcc-wrap -c file1.c file2.c file3.c --outdir=obj 
gcc -o obj/file1.o -c file1.c
gcc -o obj/file2.o -c file2.c
gcc -o obj/file3.o -c file3.c

وهنا مثل هذا السيناريو gcc_wrap في أبسط أشكالها:

#!/usr/bin/perl -w

use File::Spec;
use File::Basename;
use Getopt::Long;
Getopt::Long::Configure(pass_through);

my $GCC = "gcc";
my $outdir = ".";
GetOptions("outdir=s" => \$outdir)
    or die("Options error");

my @c_files;
while(-f $ARGV[-1]){
    push @c_files, pop @ARGV;
}
die("No input files") if(scalar @c_files == 0);

foreach my $c_file (reverse @c_files){
    my($filename, $c_path, $suffix) = fileparse($c_file, ".c");
    my $o_file = File::Spec->catfile($outdir, "$filename.o");
    my $cmd = "$GCC -o $o_file @ARGV $c_file";
    print STDERR "$cmd\n";
    system($cmd) == 0 or die("Could not execute $cmd: $!");
}

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

وأعتقد أنك حصلت على مفهوم الوراء ...؟!

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

والمثال الخاص بك:

gcc -c file1.c file2.c file3.c **--outdir=**../builddir/objdir

وأنت لم تعط القاعدة 'جعل' أن يذهب مع سطر الأوامر هذا. ولكن إذا <م> أي من تم تحديث الملفات الثلاثة، لديك لتشغيل هذا الخط، وإعادة ترجمة <م> جميع الملفات الثلاثة، والتي قد لا تكون ضرورية على الإطلاق. كما أنه يبقي 'جعل' من وضع البيض عملية تجميع منفصلة لكل ملف المصدر، كما أنها ستفعل لتجميع منفصلة (عند استخدام خيار "-j، كما أود أن أقترح بشدة).

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

وكل ما يجب أن تفعله للحصول على دليل كائن منفصل بك سيكون لإضافة معلومات الدليل المناسبة لخط OBJFILES := وسيادة %.o: %.c Makefile من أن البرنامج التعليمي. الجواب نيل بتروورث لديها مثال جيد لكيفية إضافة معلومات الدليل.

و(إذا كنت ترغب في استخدام DEPFILES أو TESTFILES كما هو موضح في البرنامج التعليمي، وكنت قد لتكييف DEPFILES := وTSTFILES := خطوط بالإضافة إلى حكم %.t: %.c Makefile pdclib.a ، أيضا.)

وأعتقد أن نقول مرور دول مجلس التعاون الخليجي لم يكن لديك خيار مستقل ليقول أين يضع ملف الكائن، لأنه بالفعل. انها "-c" - تقول في ما الدليل إلى وضع الكائن.

وبعد أن علم إضافي للدليل فقط يجب تغيير meening من "-c". على سبيل المثال:

gcc -c file.c -o /a/b/c/file.o --put-object-in-dir-non-existing-option /a1/a2/a3

وأنت لا تستطيع أن تضع /a/b/c/file.o تحت / A1 / A2 / A3، لأن كلا مسارات مطلقة. وهكذا "-c" ينبغي تغييرها إلى ملف الكائن الاسم فقط.

وأنصحك أن تنظر في استبدال MAKEFILE، مثل cmake و <لأ href = "HTTP: / /www.scons.org/ "يختلط =" نوفولو noreferrer "> scons وغيرها. وسيمكن هذا النظام لتنفيذ بناء كما عن مشروع بسيط فضلا عن أكبر واحد أيضا.

وانظر على سبيل المثال كيف أنه من السهل تجميع باستخدام cmake المثال الخاص بك. مجرد خلق CMakeList.txt الملف في srcdir /:

cmake_minimum_required(VERSION 2.6)
project(test) 

add_library(test file1.c file2c file3.c) 

واكتب الآن:

mkdir -p builddir/objdir
cd builddir/objdir
cmake ../../srcdir
make

وهذا كل شيء، سوف الملفات الكائن يقيم في مكان ما تحت builddir / objdir.

وأنا personaly استخدام cmake وتجد CONVINIENT جدا. فهو يولد تلقائيا التبعيات وغيرها من الأشياء الجيدة لها.

وفي الوقت نفسه وجدت "منتصف الطريق" الحل باستخدام خيار الجمع بين المواد.

مثال:

mkdir builddir
mkdir builddir/objdir
cd srcdir

gcc -combine -c file1.c file2.c file3.c -o ../builddir/objdir/all-in-one.o

وهذا "يجمع بين" مصدر جميع الملفات في ملف واحد من وجوه واحد.

ولكن، هذا لا يزال "منتصف الطريق" لأنه يحتاج إلى إعادة ترجمة كل شيء عندما تتغير ملف مصدر واحد فقط.

وهذا هو من بين المشاكل autoconf يحل.

إذا كنت قد فعلت من أي وقت مضى ./configure && make كنت تعرف ما هو autoconf: انها الأداة التي تولد تلك النصوص تكوين لطيفة. ما لا يعلم الجميع هو أنه يمكنك بدلا من ذلك القيام mkdir mybuild && cd mybuild && ../configure && make والتي ستعمل بطريقة سحرية، لأن autoconf رائع بهذه الطريقة.

والسيناريو configure يولد Makefiles في الدليل بناء . ثم تحدث عملية الإنشاء كلها هناك. لذلك كل ملفات البناء بشكل طبيعي تظهر هناك، وليس في شجرة المصدر.

إذا كان لديك ملفات مصدر القيام #include "../banana/peel.h" وأنت لا يمكن تغييرها، ثم انها الألم لجعل الحق في العمل هذا (لديك لنسخ أو الرمزي كافة الملفات رأس إلى الدليل بناء). إذا كنت تستطيع تغيير الملفات المصدر إلى القول #include "libfood/comedy/banana/peel.h" بدلا من ذلك، ثم كنت كل مجموعة.

وautoconf ليس بالضبط <م> من السهل ، وخاصة بالنسبة للمشروع القائم واسع. ولكن مزاياه.

واني اسعى الى معرفة الشيء نفسه. بالنسبة لي هذا العمل

CC = g++
CFLAGS = -g -Wall -Iinclude
CV4LIBS = `pkg-config --libs opencv4`
CV4FLAGS = `pkg-config --cflags opencv4`

default: track

track:  main.o
    $(CC) -o track $(CV4LIBS) ./obj/main.o

ALLFLAGS = $(CFLAGS) $(CV4FLAGS)
main.o: ./src/main.cpp ./include/main.hpp
    $(CC) $(ALLFLAGS) -c ./src/main.cpp $(CV4LIBS) -o ./obj/main.o
``
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top