C 프로그램을 실행하려고 하면 Makefile이 실패합니다.

C 프로그램을 실행하려고 하면 Makefile이 실패합니다.

Makefile을 만드는 작업이 많이 있는데 다음 파일이 있습니다.

https://raw.githubusercontent.com/systems-cs-pub-ro/uso/master/tema1/boo.c
https://github.com/systems-cs-pub-ro/uso/raw/master/tema1/light.o
https://raw.githubusercontent.com/systems-cs-pub-ro/uso/master/tema1/sound.c 
https://raw.githubusercontent.com/systems-cs-pub-ro/uso/master/tema1/sound.h

Makefile을 만들어야 합니다. "실행 파일을 생성 exec하고 light.o이전 구현의 sound.o컴파일 타임에 생성합니다 sound.c. 명령을 수신하거나 make파일 make build을 생성해야 합니다. 필요한 경우 exec전체 프로그램을 준수하는 Makefile에 규칙을 추가하고 그런 다음 생성한 개체 파일을 삭제하는 규칙을 run추가하여 실행합니다 . 또한 컴파일 후 중간 파일( , )을 생성하는 규칙을 추가합니다.cleantemplatesboo.sboo.oboo.c

이건 내 메이크파일이야

build: light.o sound.o
        gcc light.o sound.o -o exec
sound.o: sound.c
        gcc -c sound.c
templates: boo.c
        gcc -c boo.c
        gcc -S boo.c
run: exec
     ./exec
clean:
      rm -f sound.o boo.o boo.s exec

하지만 "올바른" 실행 파일을 만들지 않았다는 메시지가 표시됩니다. 제가 뭘 잘못하고 있는 걸까요? 나는 boo.oexec 파일에 추가해야 한다고 생각하는데, 그렇게 하려고 하면 다음과 같은 결과가 나타납니다 boo.c multiple definition of main light.o:light.c:first defined here.

답변1

(숙제처럼 들리네요.)

먼저 오류 메시지:

boo.c multiple definition of main
light.o:light.c:first defined here.

이는 함께 연결하려는 파일에 이름이 지정된 함수의 복사본이 여러 개 있다는 것을 의미하는데 main(), 이는 분명히 잘못된 것입니다.

을 재사용하려고 light.o하지만 이는 가 아닌 다른 기능이 있는 경우에만 실제로 작동합니다 main(). 그냥 그렇게 부르자 light(). 또한 컴파일러가 소스 코드를 보지 않고도 함수의 속성(기본적으로 매개변수 유형과 반환 값 유형)을 알 수 있도록 .h파일 #included가 필요합니다.boo.clight()

제가 보기엔 귀하의 파일이 과제에서 예상했던 것과 약간 다르게 구성되어 있는 것 같습니다. 교수님이 일련의 상호 연결된 과제를 만들었을 수 있습니다. 시리즈의 이전 과제에서 지름길을 택하면 이전 과제의 코드를 재사용하는 후속 과제가 제대로 작동하지 않습니다.

교수님은 재사용이 가능하도록 코드를 배열하는 방법과 그렇지 않으면 어떻게 되는지 가르치려고 하십니다.

Makefile 규칙의 기본 형식은 다음과 같습니다.

<name of target>: <names of files the creation process depends on>
        <command(s) to create the target file>

파일 생성은 .c파일 자체뿐만 아니라 .h파일에 포함된 파일에 따라 달라집니다. 일반적으로 시스템에는 파일이 포함되어 있다고 가정할 수 있습니다(포함한 파일은 #include <filename>변경되지 않으므로 Makefile 규칙에 추가할 필요가 없습니다). 그러나 .h프로젝트의 일부인 모든 파일도 포함되어야 합니다. .

실제로 파일이 아닌 "가상 대상"이 있을 수도 있습니다. 비슷한 일을 할 수 있게 해줍니다 make clean. 가상 대상을 다른 대상의 종속성으로 사용할 수도 있습니다. 가상 대상에는 연결된 실제 파일이 없기 때문에 가상 대상이 무언가에 대한 종속성으로 나열될 때마다 가상 대상을 "생성"하는 명령이 실행됩니다. 다른 것을 구축해야 합니다.

또한 명령을 포함하지 않지만 하나 이상의 Makefile 대상을 종속성으로 나열하는 Makefile 규칙이 있을 수 있습니다. 종속성이 하나만 있는 경우 명령이 없는 대상은 종속성으로 나열된 대상의 다른 이름으로 작동합니다. 종속성이 여러 개인 경우 명령 없는 대상은 단일 명령을 사용하여 여러 Makefile 대상을 빌드하는 방법이 됩니다.

build:교수님께서는 자신의 지시 없이 대상을 만들고 싶어하시는 것 같습니다 . 이는 두 가지 목표에만 의존해야 합니다.

  • 실제 실행 파일을 빌드하는 별도의 대상
  • templates목표

light.o소스 코드를 보지 않고 이것이 무엇인지 어떻게 알 수 있는지 궁금할 것입니다. 쉬움 - 나는 당신의 것을 다운로드 light.o하고 다음 명령을 사용했습니다.

$ readelf -s light.o

Symbol table '.symtab' contains 12 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS light.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1 
     3: 00000000     0 SECTION LOCAL  DEFAULT    3 
     4: 00000000     0 SECTION LOCAL  DEFAULT    4 
     5: 00000000     0 SECTION LOCAL  DEFAULT    5 
     6: 00000000     0 SECTION LOCAL  DEFAULT    7 
     7: 00000000     0 SECTION LOCAL  DEFAULT    8 
     8: 00000000     0 SECTION LOCAL  DEFAULT    6 
     9: 00000000    51 FUNC    GLOBAL DEFAULT    1 main
    10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND puts
    11: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND sound

light.o이는 이라는 소스 파일에서 light.c이라는 함수가 정의되고 여기에 정의되지 않은 이라는 함수를 main()사용한다는 것을 알려줍니다 . 표준 라이브러리에서 제공되지만 완전한 실행 파일을 형성하려면 이 파일과 연결된 다른 파일에서 정의되어야 합니다.puts()sound()puts()sound()

관련 정보