source

C의 여러 소스 파일은 정확히 어떻게 파일을 작동합니까?

manysource 2023. 9. 27. 18:01

C의 여러 소스 파일은 정확히 어떻게 파일을 작동합니까?

저는 C의 상대적인 초보자인데 파일을 만드는 방법을 배워야 하는데 C 파일의 조합이 어떻게 되는지 조금 혼란스럽습니다.메인, 축구장, 바가 있다고 치자main.c가 다른 파일의 기능을 인식할 수 있도록 코드를 어떻게 작성해야 합니까?또한, fo.c와 bar.c에서 메인 기능에 코드가 모두 작성되어 있습니까? 아니면 필요한 작업을 위해 다른 기능을 작성해야 합니까?make file이 어떻게 작성되는지에 대한 튜토리얼을 읽었고, 대부분의 경우 이해가 되지만, 그것의 기본적인 물류에 대해서는 아직 조금 혼란스럽습니다.

일반적으로 발생하는 일은 헤더 파일에 다른 파일에 대한 함수를 정의하는 것이며, 이 파일은 main.c에 포함될 수 있습니다.예를 들어 다음과 같은 토막글을 생각해 보겠습니다.

main.c:

#include "foo.h"

int main(int argc, char *argv[]) {
    do_foo();
    return 0;
}

fo.h:

void do_foo();

축구:

#include <stdio.h>
#include "foo.h"

void do_foo() {
    printf("foo was done\n");
}

(main.o)로, fo.c는 객체 파일main.c 는(main.o) 로됩니다, fo.c 는(foo.o) 로 됩니다.가 이 두e입니다.do_foo()는 fo.c의 함수의 .o은 함수과 관'다의 함수와 '.

GCC 명령 예제: gcc -o my program main.c foo.c

예제 makefile

myprogam: main.o foo.o
    gcc -o myprogram main.o foo.o

main.o: main.c foo.h
    gcc -c main.c

foo.o: foo.c foo.h
    gcc -c foo.c

C/C++ 컴파일 정보

파일 집합이 있을 때 보통 다음 두 가지 작업을 수행합니다.

  • 각 소스 파일(.c)을 개체 파일(.o)로 컴파일합니다.
  • 모든 개체 파일을 실행 파일에 연결합니다.

소스 파일은 독립적입니다. 다른 모듈에서 함수를 사용하려면 주어진 모듈의 함수에 대한 "정보"(선언)를 제공할 수 있는 헤더 파일이 필요합니다.헤더 파일은 자체적으로 컴파일되지 않습니다.#include소스 파일의 일부로 d.

과 에서 .make.


파일 만들기 정보

Makefile은 이들을 구축하기 위한 대상과 규칙의 집합입니다.대상은 "주어진 파일을 만들어 낼 수 있는 것"입니다. (파일을 만들어 내지 않고 명령을 실행하기 위해 존재하는 "가짜" 대상도 있습니다. 일반적인 것을 가리킵니다.clean편집 결과를 제거합니다.

각 대상에는 두 부분이 있습니다.

  • 종속성 목록, "민감성 목록"(이 대상에 필요한 다른 파일 및 대상)(이후 쉼표로 구분),
  • 이 대상을 빌드하기 위해 실행되는 셸 명령 목록(위의 below, 들여쓰기)

예를 들어 다음과 같습니다.

main: main.o module1.o module2.o
    g++ main.o module1.o module2.o -o main

즉, "파일을 빌드하려면 먼저 대상이 최신인지 확인하고 다음 명령을 호출해야 합니다..".

다음과 같이 다시 쓸 수도 있습니다.

main: main.o module1.o module2.o
    gcc $^ -o $@

것이 ( )로)$는 변수입니다)가 예상하는 대로 종속성 목록 및 대상 이름으로 확장됩니다.

다음과 같이 변수를 직접 정의하고 확장할 수 있습니다.

OBJS = main.o module1.o module2.o

main: $(OBJS)
    # code goes here

다음과 같이 개별 번역 단위를 컴파일합니다.

main.o: main.c
    gcc -c $< -o $@
    # note the -c option, which means: "compile, but don't link"
    # $< will expand to the first source file

main.c 또는 해당 헤더 중 하나가 변경될 때 main.o를 rebuild하기 위해 헤더 종속성을 추가할 수 있습니다.

main.o: main.c module1.h module2.h
    gcc -c $< -o $@

같은 명령을 반복해서 쓰지 않으려면 일반 규칙을 정의하고 종속성만 제공하면 됩니다(필요한 경우).

%.o: %.c
    gcc -c $< -o $@

main.o: main.c module1.h module2.h
module1.o: module1.c module1.h module2.h

종속성을 자동으로 생성하는 마법도 있습니다(링크 참조).Make를 사용하는 것의 단점 중 하나는 C/C++에 선호하는 SCon과 같이 일부 빌딩 시스템처럼 Make 자체적으로 사용하지 않는다는 것입니다.

기본적으로 makefile은 다음과 같은 형태의 규칙으로 구성됩니다.

<this file> : <needs these files>
    <and is created by this command>

일반적으로 상위 수준의 대상이 하나 이상 있는 경우 종속성이 없는 경우 해당 파일을 대상으로 하는 규칙을 찾습니다.최상위 명령을 실행하기 전에 최상위 명령의 모든 종속성을 해결할 때까지 재귀적으로 이 작업을 수행합니다(하나의 종속성이 있는 경우 - 종속성과 명령 모두 규칙의 선택 필드입니다).

메이크 파일은 패턴에 따라 '기본 규칙'을 가질 수 있으며, 다양한 파일 매칭 시나리오를 위한 매크로가 내장되어 있으며, 사용자 정의 매크로와 중첩된 메이크 파일을 포함합니다.

위 규칙 양식을 가장 일반적인 경우로 단순화했습니다.실제로 명령어는 대상을 전혀 생성할 필요가 없으며, 종속성에 있는 모든 파일이 존재하면 실행되는 명령어일 뿐입니다.또한 대상이 파일일 필요도 없습니다.종종 최상위 레벨의 타겟은 "모두" 또는 유사한 "더미" 타겟입니다.

물론 만들 수 있는 섬세함과 뉘앙스가 많이 있으며, 모든 것이 설명서에 자세히 나와 있습니다(GNU made 구체적으로, 다른 make 유틸리티도 있습니다).

에서의 함수foo.c는 해야 할 것 foo.c다에 이 있어야 .foo.h 그 은 .#include "foo.h".foo.c그리고.bar.c다도 안 main()합니다와 같은 합니다.main.c.

파일로 대상을 정의합니다.단순한 프로그램의 경우 전체를 컴파일하는 단일 대상을 가질 수 있습니다.더 읽기: 에는 중간 : 수 한기:큰)가상예: foo.o)을다하게 .make불필요한 재집필을 피합니다. 길은.make지정된 대상을 다시 컴파일해야 하는지 여부를 결정합니다. 모든 필수 구성 요소(콜론 뒤의 항목)의 수정 시간을 확인하고, 대상 파일 자체의 마지막 변경 시간 이후에 해당 구성 요소가 나타나면 다시 작성됩니다.

아주 간단한 예는 다음과 같습니다.

main.c:

#include "foo.h"

int main()
{
    fooprint(12);
    return 0;
}

축구:

#include "stdio.h"
#include "foo.h"

void fooprint(int val)
{
    printf("A value: %d\n", val);
}

fo.h:

void fooprint(int val);

파일 만들기:

main: main.c foo.o
    gcc -o main main.c foo.o

foo.o: foo.c
    gcc -c foo.c

그럼 달리시면 됩니다.make main그리고 그것은 컴파일 할 것입니다.foo.c안으로foo.o.c합니다 foo.o해서와 합니다.하면.main.c .main.c합니다.foo.o.

Make는 C 프로그램의 구조와 거의 관련이 없습니다.종속성 트리를 정의하고 종속성이 잘못된 것을 발견하면 명령을 실행하는 것이 전부입니다.내 말은, makefile로:

foo.exe : foo.c bar.c baz.c

simply sez: foo.exe는 foo.c, bar.c, baz.c에 의존합니다.는 make의 기본 규칙 집합을 사용하여 다음과 같이 확장됩니다.

foo.exe : foo.obj bar.obj baz.obj

foo.obj : foo.c

bar.obj : bar.c

baz.obj : baz.c

의존성 트리의 루트에서 시작하는 Walking(이 경우 foo.exe)을 수행합니다.대상이 존재하지 않거나 대상에 의존하는 개체 중 하나가 대상보다 최신인 경우 관련 명령이 실행됩니다.의존성을 바로잡기 위해서입니다.

Make from O'Reilly로 프로젝트 관리를 참조하십시오.

당신의 질문의 두번째 부분에 관한 한, 답은 단지 K와 R 두 글자입니다.그들의 The C 프로그래밍 언어는 거의 틀림없이 지금까지 쓰여진 최고의 컴퓨터 프로그래밍 책 중 하나입니다.

alt text

Makefile 작동 방식?

=> 단말기에서 make command를 실행하면 현재 디렉토리에서 makefile 또는 makefile이라는 파일을 찾아 종속성 트리를 구성합니다.

여러 개의 Makefiles가 있는 경우 다음 명령으로 특정 파일을 실행할 수 있습니다.

                           make -f MyMakefile

=> makefile에 지정된 make target을 기준으로 해당 target의 dependency file이 존재하는지 확인합니다.파일 타임스탬프를 비교하여 대상 자체보다 최신 버전인지 여부를 확인할 수 있습니다.

Here our first and default target is “all” which looks for main.o and function.o file dependencies. Second and third target is main.o and function.o respectively which have dependencies of main.c and function.c respectively.

=> 해당 대상의 명령을 실행하기 전에 해당 종속성을 충족해야 하며, 해당 종속성이 충족되지 않으면 해당 종속성의 대상을 주어진 make target보다 먼저 실행하여 누락된 종속성을 제공합니다.

=> target이 file-name일 경우 target file의 time-stamps과 종속 파일을 비교합니다.종속성 파일이 대상 파일보다 최신이면 대상 실행이 실행되지 않습니다.

In our case, when first target “all” start executing it looks for main.o file dependency, if its not met. Then it goes to second target main.o which check for its dependency main.c and compare time-stamp with it. If target found main.c dependency is updated, then target execute else not. Same process is follow for next target function.o.

=> 그러면 종속성 트리에서 소스 코드 파일까지 재귀적으로 확인하게 됩니다.이 프로세스를 통해 (종속성으로 나열된) 소스 파일 중 어떤 것을 업데이트했는지에 따라 실행해야 하는 명령만 실행하여 시간을 절약하고 대상보다 더 새로운 타임스탬프를 가집니다.

=> 이제 대상이 파일 이름이 아닌 경우('특수 대상'이라고 함), stamps을 비교하여 대상의 의존성이 더 새로운 것인지 확인할 수 없습니다.따라서 이러한 타겟은 항상 실행됩니다.

In our Makefile, special targets are “all” and “clean”. As we discussed target “all” earlier, but we not discuss target clean. Target clean removes the all object files created during compilation and binary executable files according to command.

각 대상을 실행할 때는 실행하는 동안 작업을 인쇄합니다.각 명령은 안전한 실행으로 인해 별도의 하위 셸 환경에서 실행되므로 다른 대상 실행에 영향을 미칠 수 있는 현재 셸 환경을 변경할 수 없습니다.예를 들어, 한 명령에 cd newdir가 포함되어 있으면 해당 line 명령에 대해서만 현재 디렉토리가 변경되고 다음 line 명령에 대해서는 현재 디렉토리가 변경되지 않습니다.

출처 : - http://www.firmcodes.com/linux/write-first-makefile-c-source-code-linux-tutorial/

언급URL : https://stackoverflow.com/questions/4349553/multiple-source-files-in-c-how-exactly-do-makefiles-work