Makefile 구문 이해: 일반적인 문제 및 해결 방법('연산자 누락' 및 '진입점을 찾을 수 없음' 포함)

Makefile Gumun Ihae Ilbanjeog In Munje Mich Haegyeol Bangbeob Yeonsanja Nulag Mich Jin Ibjeom Eul Chaj Eul Su Eobs Eum Poham



코드 파일에 가치 있는 콘텐츠로 하나 이상의 코드 줄이 포함되어 있는 것처럼 기본 makefile은 변수, 규칙 및 대상을 사용하여 구성됩니다. 그 외에도 문제 없이 완전한 메이크파일을 만드는 데 필요한 다른 요소도 있습니다. 이 가이드에서는 기본 메이크파일 구문과 메이크파일 작성 시 일반적인 문제에 대해 논의하고 이러한 문제를 해결하기 위한 솔루션을 제공합니다.

Makefile 기본 구문 이해

메이크파일 생성을 시작하기 위해 메이크파일 코드 예제를 통해 메이크파일의 기본 속성을 설명합니다. 실행 파일을 얻으려면 makefile 콘텐츠에 다음 구문 속성을 포함해야 합니다.







변하기 쉬운 s: makefile에서 사용하는데 필요한 기본 데이터를 저장하는 객체입니다. 이러한 변수는 컴파일러, 플래그, 소스 파일, 개체 파일 및 대상 파일을 지정하는 데 사용됩니다. 다음 샘플 메이크파일에는 CXX(C++ 컴파일러 설정), CXXFLAGSc(컴파일러 플래그), TARGET(대상 실행 파일 이름 설정), SRCS(소스 코드 파일 설정)의 총 5개 변수가 있습니다. , OBJS(소스 코드 파일을 통해 생성된 개체 파일을 포함).



대상: 소스에서 빌드할 예상 출력입니다. 이는 대상 파일 또는 임의의 기호 이름일 수 있습니다. 'all'은 'TARGET' 변수를 통해 빌드해야 하는 기본 대상이고, '$TARGET'은 'OBJS' 변수에 따라 달라지며 'clean' 대상은 대상을 제거하고 작업 디렉터리의 개체 파일입니다.



규칙 및 빌드 명령: 소스 파일이나 종속성에서 대상을 생성하기 위해 실행될 기본 명령 집합입니다. 예를 들어, '%.o: %.cpp' 규칙은 'cpp' 확장자를 가진 파일이 'o' 확장자를 가진 개체 파일을 생성하는 데 사용되며 두 파일 모두 동일한 이름을 포함한다는 것을 표시합니다. 반면에 빌드 명령은 $(CXX) $(CXXFLAGS) -o $(대상) $(OBJS) 목적 파일과 새로운 대상 파일을 함께 연결하는 데 사용됩니다. 마찬가지로 빌드 명령도 $(CXX) $(CXXFLAGS) -c $< -o $@ 소스 파일을 객체 파일로 컴파일합니다.





종속성: makefile을 만들 때 종속성은 항상 존재합니다. 예를 들어, 'all' 대상은 'TARGET' 변수에 따라 달라지고 'TARGET'은 'OBJS' 변수에 따라 달라집니다. 동시에 'OBJS' 변수는 'SRCS' 변수를 통해 소스 파일에 종속됩니다.

코멘트: 사람이 이해할 수 있는 지침은 일반적으로 오랫동안 파일을 사용하는 경우 코드 줄의 목적을 설명하는 데 사용됩니다. 다음 메이크파일에서는 '#' 기호로 시작하는 주석을 활용하여 각 줄을 설명합니다.



CXX = g++
CXXFLAGS = -표준 =c++ 열하나 -벽
타겟 = 신규
SRCS = main.cpp
객체 = $ ( SRCS:.cpp=.o )
모두: $ ( 표적 )
$ ( 표적 ) : $ ( 객체 )
$ ( CXX ) $ ( CXXFLAGS ) -영형 $ ( 표적 ) $ ( 객체 )
% .영형: % .cpp
$ ( CXX ) $ ( CXXFLAGS ) -씨 $ < -영형 $ @
깨끗한:
RM -에프 $ ( 표적 ) $ ( 객체 )

일반적인 문제 및 해결 방법

메이크파일을 작성하는 동안 마지막에 원하는 출력을 얻으려면 모든 사소한 세부 사항을 고려해야 합니다. 사용자가 makefile을 생성하는 동안 몇 가지 일반적인 문제가 자주 발생합니다. 이 섹션에서는 이러한 문제에 대해 논의하고 다음과 같이 가능한 솔루션을 제안합니다.

1: 변수를 사용하지 않음

메이크파일에서 변수를 사용하는 것은 컴파일러, 대상, 소스 파일 등을 설정하는 데 필요하므로 필수입니다. 발생할 수 있는 가장 일반적인 문제는 메이크파일에서 변수를 사용하지 않는 것입니다. 따라서 이전 샘플 makefile에서 CXX, CXXFLAGSc(컴파일러 플래그), TARGET, SRCS, OBJS와 같은 필수 변수를 활용하도록 하십시오.

2: 구분 기호 누락 문제

makefile을 작성하는 동안 탭 대신 공백을 사용하면 'make' 명령 실행 중에 '구분 기호 누락' 문제가 발생하므로 들여쓰기 규칙을 매우 주의 깊게 고려해야 합니다. 예를 들어, 13행의 규칙 시작 부분에 공백을 추가하고 탭을 제거합니다.

$ ( 표적 ) : $ ( 객체 )
$ ( CXX ) $ ( CXXFLAGS ) -영형 $ ( 표적 ) $ ( 객체 )

'make' 쿼리를 실행하면 13행에서 'Missing Separator' 오류가 발생하고 파일 실행이 중지됩니다. 이 문제를 방지하려면 공백 대신 '탭'을 사용하십시오.

만들다

이 문제를 방지하려면 다음 이미지에 표시된 대로 공백 대신 '탭'을 사용해야 합니다.

$ ( 표적 ) : $ ( 객체 )
$ ( CXX ) $ ( CXXFLAGS ) -영형 $ ( 표적 ) $ ( 객체 )

3: '진입점을 찾을 수 없음' 문제

이 오류는 소스 코드 파일에서 “main()” 함수 사용을 놓친 경우처럼 makefile 때문에 발생하는 것이 아니라 소스 파일 때문에 주로 발생합니다. 예를 들어, main() 함수 정의를 간단한 사용자 정의 함수 선언으로 대체합니다.

#include
int 쇼 ( ) {
문자 v;
표준::cout << '값을 입력하세요: ' ;
표준::cin >> 안에;
표준::cout << ~에 << 표준::endl;
반품 0 ;
}

Windows 명령 프롬프트에서 'make' 명령을 실행하면 ''WinMain'에 대한 정의되지 않은 참조'가 발생합니다. 이는 컴파일러가 C++ 파일 실행을 시작할 진입점을 찾지 못하기 때문입니다. 이 문제를 해결하려면 'show'를 'main'으로 바꾸세요.

4: 잘못된 확장자의 사용

때때로 사용자가 메이크파일에서 사용할 소스 파일에 대해 실수로 잘못된 확장자를 사용할 수 있습니다. 잘못된 확장을 사용하면 런타임 오류가 발생합니다. 즉, 대상을 만드는 규칙이 없습니다. C++ 파일의 실행 파일과 개체 파일을 빌드하기 위해 makefile을 만듭니다. 일곱 번째 줄에서는 'c' 확장자를 가진 소스 파일을 제공합니다.

CXX := g++
CXXFLAGS := -표준 =c++ 열하나 -벽
타겟 = 신규
SRCS = main.c
객체 = $ ( SRCS:.cpp=.o )
모두: $ ( 표적 )
$ ( 표적 ) : $ ( 객체 )

'make' 명령을 실행하면 '대상 'main.c'를 만드는 규칙 없음' 오류가 발생합니다. 이 문제를 방지하려면 올바른 소스 파일 확장자를 사용해야 합니다.

만들다

5: 누락된 종속성

makefile을 작성하는 동안 원하는 출력을 얻으려면 소스 파일에 대한 모든 종속성을 포함해야 합니다. 예를 들어 C++ 코드 파일은 'myheader.h' 파일을 종속성으로 사용합니다. 따라서 C++ 코드 파일에서는 다음과 같이 언급합니다.

#include
#include “myheader.h”
int 쇼 ( ) {
문자 v;
표준::cout << '값을 입력하세요: ' ;
표준::cin >> 안에;
표준::cout << ~에 << 표준::endl;
반품 0 ;
}

makefile 내에서 9행에 작성된 빌드 규칙 내에서 'myheader.h' 파일의 사용을 의도적으로 무시합니다.

% .영형: % .cpp
$ ( CXX ) $ ( CXXFLAGS ) -씨 $ < -영형 $ @

이제 “make” 명령어를 사용하는 동안 “Nothing to be done for ‘all’” 오류가 발생합니다.

만들다

% .영형: % .cpp 마이헤더.h
$ ( CXX ) $ ( CXXFLAGS ) -씨 $ < -영형 $ @

해당 문제를 방지하고 소스 코드를 성공적으로 실행하려면 다음과 같이 makefile의 9번째 줄에 'myheader.h' 파일 이름을 언급하십시오.

결론

이 가이드에서는 변수, 빌드 명령, 규칙 등과 같은 필수 콘텐츠를 사용하여 makefile의 구문을 철저하게 설명했습니다. 구문을 보다 명확하게 설명하기 위해 코드 예제가 포함되었습니다. 마지막에는 사용자가 makefile을 생성하는 동안 발생할 수 있는 몇 가지 일반적인 문제와 해결 방법에 대해 논의했습니다.