본문 바로가기

LANGUAGE/C C++

[c/c++] 빌드(build)란? + Visual C++

728x90

Visual Studio나 VS code를 이용한지 좀 되었지만, 

기계적으로 "코드작성 -> 빌드 -> 디버깅없이 시작" (+ 끝없는 오류 고치기)를 했을 뿐 무슨파일이 생성되고 어떻게 진행되는지 제대로 알지는 못했다.

이번에 CMake라는 프로그램을 사용하게 되면서 그동안 외면하고 있던 

내 소스코드는 어떻게 실행파일이 되는가?! 에 대해서 알아볼 필요성을 느끼게 되어 한번 공부해봤다.

또한, 가장 대중화 되어있는 Visual Studio로는 어떤 식으로 진행되는지도 함께 알아보았다.

 

 

 

C프로그램의 개발 과정

"소스코드 작성 → 전처리기 → 컴파일 →  링크  실행 → 디버깅" 이다.

그림으로 표현하면 다음과 같다

 

이 단계에 대해 하나하나 알아보자

* () 안에 써있는 파일은 해당 단계의 결과로 나오는 파일이다

 

1. 소스코드 작성 (file_name.c)

C언어를 이용하여 소스코드를 작성하는 단계이다. 

모든 텍스트 편집기류 프로그램(Notepad, textEditor, 등등)을 이용하여 C프로그램 소스코드를 작성할 수 있다.

사실 C프로그램 소스코드는 .c의 확장자를 가지는 일종의 텍스트 파일이다.

어떤 프로그램을 이용하여 파일을 만들던 C의 문법에 맞추어 작성하기만 하면 된다. 

 

 

2. 전처리기preprocessor (file_name.i)

프로그래머가 작성한 소스 파일을 컴파일하기 위한 소스파일로 변환하는 단계.

주석을 제거하고 다른 파일을 포함(#include)하거나, 소스 파일 내의 특정 문자열을 다른 문자열로 대치하는 일(#define)을 한다

전처리 문장은 '#'으로 시작하므로 쉽게 구별이 가능하다.

 

#include는 주로 header file을 포함시키는 경우가 가장 많은데, 

C언어에서는 항상 사용하는 <stdio.h>가 헤더파일의 예이다.

 

더보기
  • 헤더 파일(header file)

헤더파일은 서로 다른 소스 파일 사이에서 필요한 정보를 공유할 수 있게 만들어 주는 파일이며, .h라는 확장자를 사용한다.

 

  • 헤더파일의 필요성 (분할 컴파일)

C프로그램의 규모가 커지면, 여러개의 소스파일로 나누어 개발하는 것이 좋다.

그럴 경우 관련 함수나 변수들 끼리 한 파일로 모아서 작성하는데, 이는 관련된 코드를 한곳에 모아두면 유지보수가 쉬워지기 때문이다.

여러가지 소스 파일을 작성하면, 한 소스파일에서 작성한 함수나 변수등을 다른 소스파일에서 참조하여 사용해야할 일이 생기는데, 이때 헤더파일을 사용한다. 

위와같이 헤더파일에 사용할 변수나 함수를 적어놓고 #include 로 c파일에 헤더파일을 넣어주면, 함수나 변수를 사용할 수 있게 된다 

 

 

 참고로 헤더파일을 쓰는 방식에는

#include "헤더파일.h" : 헤더파일을 소스 파일이 있는 디렉토리에서 찾게됨 

#include <헤더파일.h>

두가지 방식이 있는데, 주로 ""는 사용자 정의 헤더고, <>는 표준 라이브러리 헤더이다 

 

 

3. 컴파일compile (file_name.obj)

컴파일러는 고급언어로 작성된 프로그램을 번역하여 기계어(binary)로된 프로그램을 만들어주는 번역기와 같은 역할을 한다.

컴파일하는 과정에서 C언어 문법에 맞지 않는 소스코드는 컴파일 에러가 발생되며, 결과적으로 오브젝트 파일이 생성된다.

또한 여러개의 소스파일을 사용하는 경우는 파일을 개별적으로 하나하나 컴파일 하므로, 소스파일마다 오브젝트 파일이 따로 생성된다.

 

 

4. 링크Link (file_name.exe / file_name.out ) 

링커(Linker)는 컴파일 단계에서 생성된 오브젝트 파일을 하나로 합쳐 하나의 실행파일을 생성한다.

또한, 링크 단계에서는 프로그램에 사용된 라이브러리(Static Library)를 실행파일에 연결하기도 한다.

여러 오브젝트 파일을 하나로 합치고 라이브러리를 연결할 때 잘못된 부분이 있으면 링크에러가 발생한다.

 

여기서 라이브러리에 대해 조금 더 알아볼 필요가 있다.

더보기
  • 라이브러리(Library)

소프트웨어를 개발할 때 컴퓨터 프로그램이 사용하는 비휘발성 자원의 모임.

(미리 작성된 코드, 클래스, 등등 여러가지)

 

라이브러리는 정적(Static)라이브러리동적(Dynamic / Shared) 라이브러리 두 종류가 존재한다.

 

  • 정적 라이브러리(Static Library)

"라이브러리명.lib (or .a //Linux version)"의 확장자를 가진 라이브러리 이다.

Link단계에서 실행파일 코드(binary)에 라이브러리 자체가 포함된다. -> 별도의 추가작업 없이 독립적으로 라이브러리 사용가능

 

하지만 실행파일의 크기가 커지며, 동일한 라이브러리를 각각의 프로세스가 메모리에 올리므로 메모리의 낭비가 발생한다.

 

 

  • 동적 라이브러리 (Shared Library / Dynamic Library)

.dll(or .so //Linux version)의 확장자를 가진 라이브러리다.

정적 라이브러리와 다르게 실행파일 코드에 포함되지 않고, 위치를 mapping되는 방식을 사용한다.

라이브러리가 호출되는 부분에 라이브러리 루틴 "위치"를 찾기위한 stub라는 작은 코드를 두어 사용하며, 라이브러리가 이미 메로에 있으면 그 루틴에 주소로 가고 없으면 디스크에서 읽어온다 (운영체제의 도움이 필요함) 

라이브러리가 실행시 (run time)에 연결된다.  -> 그렇기 때문에 실행파일(.exe/.out)과 .dll파일이 함께 존재해야함

 

라이브러리를 코드 자체에 포함시키지 않으므로 메모리 낭비가 적고 실행속도가 빠르다는 장점이 있다. 

 

 

 

 

5. 실행(Run)

문법적인 에러가 없으면 실행파일이 만들어지고, 이 실행파일을 작동시키므로서 원하는 결과가 얻어지는 지 확인한다.

원하는 결과가 얻어지지 않거나, 실행 중 프로글매이 죽는 문제가 발생할 수 있다.

이를 실행 에러라고 한다.

 

 

6. 디버깅(Debugging)

실행에러를 찾기 위해 수행하는 단계로

프로그램의 논리(logic)이 잘못되어 발생하는 에러를 찾아내는 과정이다.

프로그램 내에서 사용된 수식이나 변수의 값이 맞는지 흐름을 살펴보고 잘못된 부분을 찾아서 수정한다.

 

 

 

전체를 다시한번 정리해보면 다음과같다.

 

 

 

Visual C++

이제 위의 단계를 Visual c++을 통해 알아보면, 다음과 같다.

Visual studio에서는 전처리/컴파일/링크 과정을 빌드라는 하나의 과정으로 수행해준다.

 

일단 비쥬얼 스튜디오를 켜면 가장 먼저 빈프로젝트를 생성한다. 

더보기
  • 프로젝트(project)

위에서 언급했듯 여러가지의 소스파일로 하나의 프로그램을 작성하는경우, 정보를 관리할 필요가 있으므로 프로젝트(project)단위로 관리한다.

여러개의 소스 파일로 프로그램을 작성하면 각각 소스파일을 독립적으로 컴파일하고 링크단계에서 라이브러리와 오브젝트 파일을 합쳐 하나의 실행파일을 생성하는데, 

어떤 소스파일들을 컴파일해서 어떤 오브젝트 파일을 생성하는지, 어떤 라이브러리를 링크하는지에 대한 정보를 관리하기 용이하다 

이때, 프로젝트 폴더와 솔루션 폴더가 생성되며, 

프로젝트 폴더에는 .vcxproj / .vcxproj.filters / vcsproj.user  파일이 생성되고,

솔루션 폴더에는 .sln 이라는 솔루션 파일이 생성된다.

 

우측에 소스폴더에 소스파일을 추가하면 .c파일이 프로젝트 폴더에 생성되며, 그 후 해당 파일에 소스코드를 작성한다.

 

소스 코드 작성이 마쳐지면, 빌드를 이용해 실행파일(.exe)을 생성하는데, 

이는 프로젝트 폴더 안에 Debug라는 별도에 파일이 생성되고, 그 안에 exe실행파일이 생성된다.

 

이제 이를 디버그 하지 않고 시작을 이용하여 콘솔창에 실행시킬 수 있다. 

 

정리하면 다음과 같다. 

 

 

솔루션 파일이 무엇인가? vcxproj파일은 무엇인가? 에 대하여는 다음 글을 참고하시면 좋을 것 같습니다.

m.blog.naver.com/PostView.nhn?blogId=kkson50&logNo=220760784702&proxyReferer=https:%2F%2Fwww.google.com%2F

 

[Visual Studio] 프로젝트(project)와 솔류션(solution)의 차이

비주얼 스튜디어에서 프로젝트와 솔류션이라는 개념이 있습니다. 프로젝트는 물리적으로 XML 파일 ( .vb...

blog.naver.com

docs.microsoft.com/ko-kr/cpp/build/reference/vcxproj-file-structure?view=vs-2019

 

.vcxproj 및 .props 파일 구조

.vcxproj 및 .props 파일 구조.vcxproj and .props file structure 이 문서의 내용 --> MSBuild는 Visual Studio의 기본 프로젝트 시스템입니다. Visual C++에서 파일 > 새 프로젝트를 차례로 선택하면 .vcxproj 확장명의 XML

docs.microsoft.com

 

 

 

<참고자료>

헤더파일 

programfrall.tistory.com/20

 

[C언어]18. 헤더파일이란 무엇인가 ( 헤더파일을 만드는 법 )

 안녕하십니까. 리습입니다. 지금까지 프로그램을 만들면서 간단한 기능은 만들거나 #include 를 이용해서 헤더파일을 불러오는 방식으로 새로운 기능을 쓸 수 있었습니다. 하지만 아직 헤더파일

programfrall.tistory.com

 

DLL vs LIB 

dpdpdpdpdpdp.tistory.com/235

 

*.lib 와 *.dll 파일의 차이점

Library 란 ? 함수, 데이터, 타입 등 여러가지 프로그래밍 요소들의 집합. 같은 프로그래밍 코드를 작성할 필요를 제거하여, 개발을 빠르게 할 수 있도록 한다. Library 에는 두가지 연결 모드가 있��

dpdpdpdpdpdp.tistory.com

luyin.tistory.com/201

 

정적 라이브러리(Static library) vs 동적 라이브러리(Dynamic library)

1. Static library Dynamic (linking) library (흔히 얘기하는 DLL)을 설명하기 위해 간단하게 정리한다. 특정 기능의 라이브러리를 static 하게 제작한다는 것은 link 단계에서 라이브러리(*.lib 파일)를 실행 바..

luyin.tistory.com

 

 

 

<참고자료> 

개념을 콕콕 잡아주는 프로그래밍 C(천정아 저)

728x90

'LANGUAGE > C C++' 카테고리의 다른 글

[C/C++] 비트마스크(BitMask)  (0) 2021.09.23
[C++] 입출력  (0) 2021.08.27
컴파일러 분석  (0) 2021.03.24