문제

나는 이유를 궁금 gcc/g++없는 옵션이 생성된 오브젝트 파일로 지정한 디렉토리에 있습니다.

예를 들어:

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

...나는 내가 쓸 수 있는 메이크를 통해 VPATH 및 vpath 지시어를 단순화하다.

그러나 그 많은 일이에 복잡합니다.

할 수도 있습 사용

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

그러나 사용할 때 이 방법을 내 srcdir 체.o 쓰레기습니다.

그래서 내가 생각하는 옵션으로의 의미를--outdir 것은 매우 유용합니다.

당신의 의견은 무엇입니까?

편집:우리의 메이크 파일에 기록되는 방식으로.o 파일이 실제로 배치로 builddir/obj.하지만 나는 단순히 궁금해 있는 경우에 더 나은 방법이 될 수 있음을 시사한다.

편집:방법은 여러 가지가 있는 장소 부담을 달성하기 원하는 동작을 빌드 시스템(만드,CMake etc.).하지만 난 그들을 고려 모든 것으로 해결 방법 대한의 약점 gcc(및 다른 컴파일러는 너무).

도움이 되었습니까?

해결책

이것은 내 프로젝트 중 하나의 다진 Makefile이며, 'SRC'에서 소스를 컴파일하고 .o 파일을 디렉토리 "OBJ"에 배치합니다. 키 비트는 Patsubst () 함수의 사용입니다. 자세한 내용은 GNU Make Manual (실제로 꽤 좋은 읽기)을 참조하십시오.

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

그게 다야. GCC는 양식의 포함을 해석합니다 #include "path/to/header.h" 디렉토리에서 시작하여 파일이 존재하므로 아무것도 수정할 필요가 없습니다.

사소하지만 효과적인 해결 방법은 MakeFile에서 GCC 호출 직후 다음을 추가하는 것입니다.

mv *.o ../builddir/objdir

또는 a 소프트 클레닝 (아마도 재귀 적) 편집이 완료된 후

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 새로운 옵션을 포함하는 출처이지만 어려울 수 있습니다.

나는 당신을 믿어라는 개념을 뒤...?!

아이디어 뒤에 파일은 그들만을 처리하는 파일 업데이트되었습한 후,구축을 줄일(재)컴파일하다.는 경우에 당신은 무리가 여러 파일을 하나에 함께 컴파일러가 실행,당신은 기본적으로 패배는 목적이 있다.

귀하의 예:

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

당신이를 주지 않았는지'확인'규칙으로가는 이 명령 라인;그러나는 경우 세 개의 파일을 업데이트되었습니다,당신은 당신이 라인,그리고 다시 컴파일 파일을 수있는,필요하지 않다.그것은 또한 유지'확인'산란에서 별도의 컴파일 과정에 대한 각 소스 파일,그것을 할 것에 대한 별도의 컴파일(이용할 때는'j'옵션으로 난 것이 좋).

Makefile 튜토리얼 다른 곳에는 몇 가지 여분의 세부 사항(예:자동차 검출 소스 파일을 대신 그들의 하드 코딩에는 메이크,자동 결함을 종속성,인라인 테스트).

모든 작업을 수행해야 합니다 귀하의 별도체 directory 을 추가하는 것이 적절한 정보를 디렉토리 OBJFILES := 라인과 %.o: %.c Makefile 규칙에서는 튜토리얼입니다.닐 버스의 대답은 예의는 방법을 디렉토리를 추가 정보입니다.

(를 사용하려면 DEPFILES 나 수도 있으로 튜토리얼에서 설명하는,당신을 적응시켜야 DEPFILES :=TSTFILES := 라인플러스 %.t: %.c Makefile pdclib.a 규칙,too.)

Pass GCC에게 말하는 것은 이미 객체 파일을 넣을 위치를 말할 수있는 별도의 옵션이 없다고 생각합니다. "-c"입니다 - 객체를 넣을 디렉토리에 어떤 디렉토리에 표시되어 있습니다.

디렉토리에 대한 추가 플래그가 있으면 "-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 ider/a1/a2/a3를 넣을 수 없습니다. 따라서 "-c"는 이름 객체 파일로만 변경해야합니다.

나는 당신에게 makefile의 교체를 고려하는 것이 좋습니다. cmake, 스콘 및 기타. 이를 통해 간단한 프로젝트뿐만 아니라 더 큰 프로젝트도 구현 시스템을 구현할 수 있습니다.

예를 들어 CMAKE 예제를 사용하여 컴파일하기 쉬운 방법을 참조하십시오. srcdir/에서 파일 cmakelist.txt 만 만들기 만하면됩니다.

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 아래에 있습니다.

나는 cmake를 사용하고 매우 편한 것을 찾습니다. 자동으로 종속성을 생성하고 다른 제품이 있습니다.

한편 -컴퓨터 옵션을 사용하여 "반쯤"솔루션을 찾았습니다.

예시:

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