111 – make로 컴파일 자동화하기

프로그래밍을 할 때는 아무리 작은 수정이라도 수정을ㄹ 하면 소스 파일을 재컴파일해야 실행 파일에 수정 내용이 반연된다. 그런데 파일 하나나 작은 수의 파일로 이루어진 프로그램에서는 별 문제가 없으나, 여러 파일로 이루어진 대규모 프로그램인 경우에는 파일 하나만 수정해도 몯든 파일을 재컴파일해야 하게 되므로 부담이 크다. 이와 같이 여러 파일이 이루어진 프로그램을 개발할 때, 통합 개발툴의 경우에는 설정도 간단하고 자동으로 관리까지 해주니 편한 반면 리눅스 환경에서 개발을 할 경우에는 이 여러 파일로 이루어진 프로그램 코드의 컴파일을 관리해줄 수 있어야 한다.

make는 주어진 조건으로부터 대상을 만들어내는 다목적 프로그램으로, 다수의 소스 파일로 구성된 큰 프로그램 중 어떤 파일이 변경되었으므로 재컴파일이 필요한지 판단해 프로그램 개주성 작업을 효율적으로 수행하는 역할을 해준다. 그리고 이 때, 어떤 일을 해야 하는지 make에 알려줄 정보를 담고 있는 파일이 makefile이다. make 자체로도 여러모로 옵션과 기능들이 있는데 이 기능들에 대해서는 하나하나 살펴보도록 하겠다.

110 – GCC 옵션(최적화 관련)

성능을 개선시키기 위해 코드를 최적화하여 불필요하거나 비효율적인 계산 과정을 효율적으로 대체하여 코드의 크기와 실행 시간을 줄인다. 그러면 컴파일 시간이 늘고 컴파일 과정에서 메모리 사용량이 늘어나기도 하는 단점이 존재하기도 한다. 실행 최적화를 위해 진행하는 과정에서 발생하는 것인데, 사람이 직접 최적화하는 과정 또한 존재하지만 컴파일러에 의한 자동 최적화 또한 존재한다. 이 옵션은 컴파일러에 의한 자동 최적화를 다룬다.

  • -O

뒤에 숫자를 써줌으로써 최적화 단계를 구분할 수 있다. gcc의 버전마다 차이가 나고, 값이 커질수록 더욱 최적화된 결과물이 나온다. 일반적으로는 -O1, -O2를 주로 이용하고, 오래된 gcc에서도 -O3까지는 기본적으로 지원한다.

  • -O1 | -O 옵션과 같은 간뎨의 옵션으로 최소한으로 스레드 분기 동작 횟수를 줄이고, 호출된 각 함수 반환 시 스택에 인수를 모아 두었다가 동시에 꺼내게 해준다.
  • -O2 | -O1 단계의 최적화와 함께 프로세서가 닫른 명령어의 결과나 캐시 메모리 또는 메모리의 데이터를 기다리는 동안 컴파일러가 다른 명령어를 실행하도록 한다. 컴파일 시간이 더 오래 걸리지만, 수정된 코드는 더 최적화되어 실행이 빨라진다.
  • -O3 | -O2 단계의 모든 최적화와 루프 해체, 그 밖의 프로세서 전용 특징을 포함하여 최적화한다.

이걸로 일단 간단하게 gcc의 옵션을 다 다뤄봤다. 이제 make에 대한 글로 이어지겠다.

109 – GCC 옵션(디버깅 관련)

이 블로그에서는 솔직이 엄청 간단한 레벨에서만 C 언어를 주로 다뤄왔다. 그러나, 대부분의 C 언어를 처음 다루는 사람에게는 이 예제를 따라하다가도 실수를 해서 오류가 많이 생기기도 한다. 그럴 때, 왜 컴파일이 안되지?” 하는 사람들이 있다. 사실 몇 줄 안되는 프로그램이라 쉽게 잡을 수 있다만, 몇 만 라인 이상의 프로그램의 버그를 찾는 것은 쉽지 않다. 이러한 이유로 디버깅을 위한 프로그램인 gdb를 이용하기도 한다. gdb에 대한 것은 나중에 확인해 보겠다.

-g, -ggdb 옵션은 이런 디버거를 사용해 디버깅을 할 때, 좀 더 쉽게 할 수 있도록 정보를 삽입해주는 옵션이다. 그 중에서도 -g 옵션에 대해서 살펴보겠다.

  • -g

-g 옵션은 디버깅 정보의 양에 따라 3 단계로 된다. -g1, -g2, -g3 이렇게 구성되어 있는데,  -g로만 하면 기본적으로 -g2로 인식된다. 이 단계에 대한 자세한 내용은 다음과 같다.

  • -g1 | 역추적 스텍 덤프 생성에 필요한 정보를 포함하지만 지역 변수, 문장 번호를 위한 디버깅 정보는 삽입하지 않는다.
  • -g2 | 확장 기호 테이블, 문장 번호, 지역과 외부 변수에 대한 디버깅 정보를 삽입한다.
  • -g3 | -g2 옵션의 디버깅 정보와 모든 매크로 관련 정보를 삽입한다.

이를 확인하기 위해 간단한 예시 프로그램을 작성하였다.

스크린샷_2017-06-21_18-00-47.png

hello world 레벨의 간단한 코드이다. 이 프로그램에 -g 옵션을 적용시켜 컴파일을 진행하고, 결과물의 파일 사이즈를 확인해 보기로 하였다.

스크린샷_2017-06-21_18-01-55.png

옵션이 커지면 커질수록 사이즈가 늘어나는 것을 볼 수 있다. (kyuling 뒤에 쓰여진 숫자가 파일 사이즈이다.) 늘어난 사이즈만큼 디버깅 정보가 추가되었다는 것이다.

-ggdb 옵션도 -g 옵션과 거의 유사하나 다른 점이 있다면, 디버깅 작업을 도와주는 추가 정보가 필요하고, gdb 외에 다른 디버그에서는 사용이 불가능하다.

-g, -ggdb 옵션에 의한 디버깅 코드 삽입은 파일의 크기를 크게 하기 때문에 최종 실행 파일을 생성할 때에는 이러한 옵션을 주지 말고 컴파일 하는 것이 바람직하다. 이 옵션들에 의해 실행 속도 및 실행 과정에서의 차이가 발생한다. 또한 최적화된 코드의 경우에는 디버깅을 어렵게 만들기 때문에 최적화 수행은 디버깅이 다 끝난 다음에 하는 것이 좋다.