저는 Bash 프로그래밍이 처음입니다. Bash 파일에서 C++ 프로그램을 호출하고 싶습니다.
내 프로그램은 myProg.cpp
다음 과 같습니다
#include<iostream>
using namespace std;
int main()
{
cout<<"Salam! World"<<endl;
return 0;
}
그리고 내 bash 파일은 myBash.sh
. 위의 .cpp 프로그램을 파일에서 어떻게 호출할 수 있나요 myBash.sh
?
답변1
먼저 컴파일해야 합니다. 먼저 터미널의 현재 작업 디렉터리를 소스 파일의 경로로 변경합니다.
cd <path_to_cpp_file>/
그런 다음 소스 파일을 컴파일합니다.
g++ myProg.cpp -o myProg
그런 다음 다음과 같이 스크립트에서 컴파일된 실행 파일을 호출할 수 있습니다 bash
.
#!/bin/bash
# ...
<path_to_compiled_executable>/myProg
# ...
답변2
당신 이후로진짜 목표프로그램을 실행하는 데 필요한 모든 작업을 자동화하는 것 같지만 다른 접근 방식을 제안합니다.쉘 스크립트를 작성하는 대신 다음을 사용할 수 있습니다.메이크파일.원하는 경우 실행 파일이 빌드된 후 실행 파일을 실행하기 위한 규칙을 makefile에 작성할 수 있습니다. 그러면 C++ 소스 코드 파일과 makefile이라는 두 개의 파일이 생기고 다음과 같은 단일 명령을 효율적으로 실행할 수 있습니다.
- C++ 프로그램을 빌드하거나 다시 빌드합니다.필요한 경우에만.
- 프로그램을 실행합니다.
이 게시물의 다음 섹션에서는 .cpp
파일을 직접 호출할 수 없는 이유를 설명합니다(그러나 먼저 파일에서 실행 파일을 만들어야 합니다). 설치 방법 make
, 사용 방법 및 뒤에서 수행되는 작업 그리고 일반적인 함정을 피하는 방법. 하지만 자세히 알아보기 전에 이 접근 방식이 어떤지 느낌을 알고 싶다면 make run
다음을 입력한 후 실행하세요.0안에 Makefile
:
all: myProg
run: all
./myProg
나는 쉘 스크립트보다 이 목적을 더 좋아하며 당신도 그럴 것이라고 생각합니다.
배경
일부와 달리통역된 언어Python 및 Bash와 마찬가지로 C++는컴파일된 언어.1C++로 작성된 프로그램은 다음과 같아야 합니다.세워짐실행되기 전에. (건물이라고도 함컴파일, 그렇지만컴파일더 적절하게는 빌드 단계 중 하나를 나타냅니다.) C++를 실행할 수 없습니다소스 코드파일; 대신 다음으로 컴파일해야 합니다.객체 코드2, 이 경우기계어. 그런 다음 개체 파일을 서로 연결해야 하며, 하나만 있어도 여전히 모든 파일에 연결되어야 합니다.공유 라이브러리그것은 사용합니다. 연결하면실행 가능실행될 수 있습니다.
간단히 말해서, 프로그램을 실행하기 전에 프로그램을 작성해야 합니다.처음으로. 후속 실행 전에는 필요하지 않습니다.답장소스 코드를 변경하지 않은 경우 빌드됩니다. 이 경우 실행되는 프로그램에 변경 사항이 반영되도록 하려면 다시 빌드해야 합니다.유틸리티make
작업을 수행하려는 이러한 종류의 상황을 위해 특별히 설계되었습니다.조건부로이미 완료되었는지 여부와 시기에 따라 다릅니다.
구하는make
이미 make
명령이 설치되어 있을 수도 있습니다. 실행해서 알아보세요. 설치되어 있으면 다음과 같은 내용이 표시됩니다.
$ make
make: *** No targets specified and no makefile found. Stop.
make를 얻으려면 다음을 설치할 수 있습니다.만들다 패키지이지만 설치하는 것이 좋습니다.빌드 필수 이는 기타 여러 가지 편리한 도구를 제공합니다. (이미 설치했을 수도 있습니다.빌드 필수 을(를) 얻으려면 g++
이미 가지고 있을 수도 있습니다 make
.) 소프트웨어 센터를 사용하여 설치하거나 다음 명령을 실행할 수 있습니다.
sudo apt-get update && sudo apt-get install build-essential
make
메이크파일 없이
어떻게 작동하는지 확인하려면 make
먼저 makefile 없이 실행하고 소스 코드 파일의 기본 이름을 전달하는 것이 좋습니다.
$ make myProg
g++ myProg.cpp -o myProg
$ ./myProg
Salam! World
후속 실행에서는 make
수정 타임스탬프(시간s) 입력 및 출력 파일에 적용되며 불필요하게 프로그램을 다시 빌드하지 않습니다.
$ make myProg
make: 'myProg' is up to date.
을 변경하면 myProg.cpp
수정 타임스탬프가 업데이트되므로 make
다시 빌드해야 한다는 것을 알 수 있습니다. (또한 다음을 사용하여 파일의 타임스탬프를 업데이트할 수도 있습니다.touch
명령에 의존하는 출력 파일을 강제로 다시 빌드해야 하거나 원하는 경우. 물론 출력 파일을 삭제하면 실행 시 해당 파일이 다시 빌드됩니다 make
. 단, 잘못된 파일을 삭제하지 마세요!)
$ touch myProg.cpp
$ make myProg
g++ myProg.cpp -o myProg
make
달릴 때 무엇을 해야 할지 어떻게 알 수 있나요 make myProg
?
- 인수
myProg
를make
a라고 합니다.표적. - 대상은 항상 그런 것은 아니지만 생성될 파일의 이름인 경우가 많습니다. 타겟은 makefile에 명시적으로 정의될 수 있습니다.
- 타겟이 메이크파일에 정의되어 있지 않거나 (이 경우와 같이) 메이크파일이 없는 경우,
make
타겟 빌드용임을 암시하는 방식으로 이름이 지정된 입력(예: 소스 코드) 파일을 찾습니다. make
접미사(이 경우.cpp
)에서 파일을 빌드하는 데 사용할 유틸리티와 구문을 유추합니다.
이 모든 것을 사용자 정의할 수 있지만 이와 같은 간단한 경우에는 그럴 필요가 없는 경우가 많습니다.
프로그램 빌드 및 실행을 자동화하기 위한 Makefile 만들기
단일 소스 코드 파일에서 프로그램을 구축하는 것보다 더 복잡한 작업을 자동화하려면(예: 여러 개의 입력 파일이 있거나 (즉시 필요한 경우에 더 적합하게) 컴파일러 실행 외에 수행하려는 작업이 있는 경우 makefile을 생성하여 대상을 정의할 수 있습니다. make
다른 대상에 의존하는 방법을 지정하고 지정합니다 .
makefile에 정의된 첫 번째 대상은 기본 대상입니다. 이는 make
명령줄 인수 없이 실행될 때(즉 make
, 와 같은 것이 아닌 그냥 실행하는 경우 make myProg
) 빌드를 시도하는 대상입니다.
makefile을 사용하는 일반적인 방법은 프로그램을 빌드하는 데 사용되는 모든 소스 코드 파일(및 기타 파일)과 일반적으로 Makefile
. 그 이름으로 make
자동으로 찾아드립니다.
실행하는 데 사용할 수 있는 메이크파일을 생성하려면 myProg
필요할 때 자동으로 먼저 빌드하고 myProg.cpp
새 디렉토리에 넣거나 그렇지 않으면 빈 디렉토리에 넣으십시오. 해당 디렉토리에 Makefile
.
이를 위해 모든 텍스트 편집기를 사용할 수 있지만 규칙에 대한 레시피(대상을 만들기 위해 실행될 명령 아래에 나열됨)는 다음과 같이 들여쓰기되어야 합니다.탭오히려공백.삼따라서 현재 텍스트 편집기가 를 누를 때 공백으로 들여쓰기되도록 구성되어 있다면 Tab이를 변경해야 합니다.
예를 들어 Gedit 또는 Pluma에서는 다음으로 이동합니다.편집 > 환경설정,편집자탭을 누르고 확인하세요.탭 대신 공백 삽입선택 취소됨:
많은 편집기에서는 공백이 아닌 탭을 사용하여 들여쓰기를 기본으로 하므로 이전에 이 설정을 변경하지 않았다면 makefile에 대해 이미 올바르게 설정되어 있을 수 있습니다.
편집기에 있고 (필요한 경우) 탭으로 들여쓰기하도록 구성한 후 다음을 입력하세요.
all: myProg
run: all
./myProg
복사해서 붙여넣으면 틀려요를 누를 때 텍스트 편집기가 공백을 만들지 않더라도 공백이 처리되기 때문입니다 Tab. (이것은 Ask Ubuntu가 코드를 표시하는 방식과 관련이 있습니다.) 그러나 앞의 공백 네 개를 제거 ./myProg
하고 Tab해당 위치에 탭을 만들려면 누르기만 하면 됩니다.
일부 텍스트 편집기에서는 기본적으로 탭을 공백 8개 또는 다른 숫자로 표시합니다. 괜찮아.
Makefile의 기능과 사용 방법
다음 명령을 사용하십시오.
make
, 프로그램이 이미 빌드되어 있고 실행 파일이 소스 코드에 최신인 경우를 제외하고 프로그램을 빌드합니다.또는,make run
, 프로그램을 실행하려면,필요한 경우 먼저 구축(즉, 현재 실행 파일이 없는 경우)
이 makefile은 두 개의 대상을 정의합니다: all
및 run
.
대상
all
에는 자체 레시피가 없지만myProg
대상에 따라 다릅니다. 이 대상은 명시적으로 정의되지 않으므로 현재 디렉터리에서 사용할 수 있는 모든 소스 코드 파일에서make
빌드를 시도하도록 암시적으로 지시합니다.myProg
(참조make
메이크파일 없이자세한 내용은 위 섹션을 참조하세요.)all
은 에서 명시적으로 정의된 첫 번째 대상이므로 상주 하는 디렉터리에서 실행될Makefile
때 빌드됩니다 . 따라서 우리는 실행 자체가 실행과 동일하도록 설정했습니다 .make
Makefile
make
make all
대상
run
이 프로그램을 실행합니다. 해당 레시피는 이를 수행하는 명령으로 구성됩니다./myProg
. 대상을 종속성으로run
선언합니다 .all
이렇게 하면 을 실행할 때 현재 실행 파일이 최신이 아닌 경우(또는 아직 존재하지 않는 경우) 가make run
다시myProg
빌드됩니다myProg
.on 대신에
run
의존 하도록 만들 수도 있지만 기본 대상이 되는 것을 방지하려면 여전히 명시적인 대상(또는 다른 이름의 동등한 대상)이 필요했을 것입니다 . 물론, 프로그램을 만들고 싶다면myProg
all
all
run
그리고 달리다혼자서 달릴 때도make
이렇게 할 수 있습니다.대상 에 따른 또 다른 이점은
all
나중에 프로그램을 실행하기 전에 수행해야 하는 작업이 더 많을 경우에 대비한다는 것입니다. 그런 다음 에 대한 규칙에 레시피를 추가할 수 있습니다all
.
프로그램을 빌드해야 하는 경우 makefile을 사용하여 프로그램을 실행하는 방법은 다음과 같습니다.
$ cd myProg/
$ make run
g++ myProg.cpp -o myProg
./myProg
Salam! World
또는 빌드할 필요가 없는 경우 다음과 같이 하세요.
$ make run
./myProg
Salam! World
그리고 프로그램이 빌드되었는지 확인하려는 경우(소스 코드 파일이 마지막으로 수정되었으므로)프로그램을 실행하지 않고, make
인수 없이 간단히 실행합니다.
$ make # Here, I run make and myProg isn't current.
g++ myProg.cpp -o myProg
$ make # Running "make" again after "make" or "make run" does nothing.
make: Nothing to be done for 'all'.
( make myProg
여전히 작동합니다.)
개선: 사용자 정의 컴파일러 플래그
make
는 매우 강력한 도구로, 이와 같은 간단한 목적에 편리하지만 대규모의 복잡한 프로젝트에도 적합합니다. 당신이 할 수 있는 모든 일을 자세히 설명하려고 하면 make
책 전체가 될 것입니다(구체적으로,이 하나).
하지만 뭔가가 빌드 완료를 방해하지는 않지만 여전히 잠재적인 오류인 경우 컴파일러에서 경고를 보고 싶을 수도 있다는 생각이 들었습니다. 이것들은 여러분이 작성한 프로그램의 모든 버그를 잡아낼 수는 없지만 많은 버그를 잡을 수는 있습니다.
GCC를 사용할 때(명령과 마찬가지로 g++
) 적어도 -Wall
컴파일러에 전달하는 것이 좋습니다. 실제로는 활성화되지 않습니다.모두경고가 표시되지만 나머지 대부분은 -Wextra
. 때로는 원할 수도 있습니다 -pedantic
. (보다man gcc
그리고3.8경고를 요청하거나 억제하는 옵션에서GCC 참조 매뉴얼.)
이러한 플래그를 사용하여 수동으로 호출하려면 g++
다음을 실행합니다.
g++ -Wall -Wextra -pedantic -o myProg myProg.cpp
, 및 플래그를 사용하여 make
C++ 컴파일러( g++
)를 호출 하려면 해당 플래그가 포함된 행을 의 맨 위에 추가합니다 .-Wall
-Wextra
-pedantic
CXXFLAGS=
Makefile
CXXFLAGS=-Wall -Wextra -pedantic
all: myProg
run: all
./myProg
myProg
여전히 존재하고 가 보다 최신인 경우에도 myProg.cpp
실행 make
하거나 make run
편집한 후에는 Makefile
여전히 프로그램을 다시 빌드합니다. 왜냐하면 Makefile
은 이제 보다 최신이기 때문입니다 myProg
. 이는 좋은 일입니다. 그 이유는 다음과 같습니다.
- 이 경우 실행 파일을 다시 빌드하면 경고가 있으면 표시됩니다(특정 프로그램의 경우 경고가 없어야 함).
- 더 일반적으로 말하면 메이크파일을 편집할 때 다른 파일을 생성하거나 다른 내용으로 생성하기를 원하기 때문인 경우가 있습니다. (예를 들어,
-O3
과도한 최적화를 위해 플래그를 추가했거나-g
컴파일러가 디버그 기호를 생성하도록 한 경우 결과myProg
실행 파일은 달라집니다.)
추가 자료
- 연습 2: 이제 Python을 여러분의 Python으로 만드세요~에C를 어렵게 배우세요~에 의해제드 쇼.
- 그만큼GNU 메이크 매뉴얼, 특히2.1규칙의 모습.
- 간단한 Makefile 튜토리얼~에 의해브루스 A. 맥스웰를 참조하여 다른 사용 방법에 대한 정보를 확인하세요
make
. - "Makefile 사용"(p. 15) 및 "Makefile과 셸 스크립트 비교"(p. 62)21세기 C~에 의해벤 클레멘스. 페이지 번호는 초판용입니다. (아마도 두 번째 버전이 더 나을 것 같지만, 저는 첫 번째 버전만 가지고 있습니다.)
노트
0: 이 작업을 수행하는 방법을 보려면 더 자세히 읽어 보는 것이 좋습니다. 하지만 직접 시도해보고 싶다면 공백이 아닌 탭을 사용하여 줄을 들여쓰기해야 합니다.
1: 엄밀히 말하면 거의 모든 프로그래밍 언어는 무엇에 따라 해석되거나 컴파일될 수 있습니다.구현왜냐하면 그것은 기록되었기 때문이다. 일부 언어의 경우 인터프리터와 컴파일러가 모두 존재합니다. 그러나 해석된 C++는 흔하지 않습니다.들어본 적이 없는.
2: 건물을 분할하다컴파일그리고연결, C++ 소스 코드 파일(.cc/.cpp/.cxx/.C)을 개체 코드로 변환 호출컴파일, 이것이 전부가 아닙니다. C 및 C++(그리고 일부 다른 언어)로 된 프로그램이 먼저입니다.전처리된. 귀하의 프로그램에서C 전처리기실제 컴파일이 시작되기 전에 헤더 파일 #include<iostream>
의 내용으로 대체됩니다 . <iostream>
그리고 가장 좁은 의미에서 컴파일은 소스 코드를 다음으로 변환합니다.어셈블리어객체 코드보다는 많은 컴파일러(예: GCC/ g++
)는 컴파일과 어셈블리를 단일 단계로 결합할 수 있으며 요청하지 않는 한 어셈블리 코드를 생성하지 않습니다.
전처리는 별도의 단계이지만 GCC 및 기타 컴파일러는 자동으로 전처리기를 실행합니다. 마찬가지로 링커를 자동으로 실행할 수 있으므로 전체 시퀀스가전처리,편집,집회, 그리고결합"빌딩"이라기보다는 "컴파일링"이라고도 합니다. (또한 건물에는 이러한 단계보다 더 많은 단계가 포함될 수 있습니다. 예를 들어 리소스 파일 생성, 실행 등이 포함될 수 있습니다.사물이 어떻게 구축될지 구성하는 스크립트, 등.)
삼: makefile 자체에서는 탭으로 들여쓰기만 하면 됩니다. makefile을 사용한다고 해서 C++ 소스 코드 파일 자체를 작성하는 방식에 대한 요구 사항은 없습니다. 다른 파일에서 작업할 때 들여쓰기를 탭에서 공백으로 다시 전환할 수 있습니다. (만약 너라면정말makefile에서 탭으로 들여쓰기를 좋아하지 않는다면.RECIPEPREFIX
특수 변수.)
답변3
예는 다음과 같습니다. myBash.sh에서
#!/bin/sh
g++ myProg.cpp -o myProg
./myProg