GCC 링커에서 사용하지 않는 함수는 제외 되어야하는게 아닌가요??

syseop의 이미지

Avr Gcc로 코딩중입니다. 마이컴의 용량이 작아 항상 코드사이즈가 신경이 쓰이는데

아래와 같은 문제에 봉착하여 원인을 알고자 이곳에 글을 올립니다.

Pc의 Gcc또한 같은 문제일것이라 생각하는데 어느 부분에서.. 왜 용량이 증가하는 것일까요?
//-----------------------------------------------------------------------

그동안 알고 있기로는 각각의 재배치 가능 파일에는 들어있더라도 링커가 사용하는 함수만 골라 hex파일을 만
드는 줄알았습니다.

헌데 오늘 보니까.. 단순히 makefile의 SRC함목에 소스파일 이름을 명시하고 main.c에서 #include로 헤더를 포함하기만해도 용량이 증가하는 이유가 무얼까요??

main.c에서는 해당 파일내의 어떤함수도 사용하지 않았는데 말이죠...

혹 이점에 대해 알고 계신 분 안계신가요???

CCS-C등의 일부 특정마이컴 전용 컴파일러의 경우 파일내 함수가 포함되어있더라도 컴파일시에 사용하지 않으면 제외되어 hex파일의 용량이 증가 하지 않는데...

GCC의 경우 어떻게 해야 사용하지 않는 함수를 결과물에서 배재할수있는 것일까요??

flane의 이미지

같은 문제로 고민하고 있었는데 아무런 답변이 없군요.
일단 제가 아는 바는 링커 옵션에 --gc-sections를 사용하면 참조되지 않는 오브젝트(*.o)는 제거가 된다는 겁니다. 근데 이걸로는 부족하죠. 혹 아시는 분 꼭 답변 부탁드립니다.

ironiris의 이미지

그런가요?
저는 puts만 쓰다가 printf 를 포함하면 실행파일이 더 커지던데...(둘다 stdio.h)

익명 사용자의 이미지

보통 표준 C라이브러리는 동적라이브러리인 경우가 대부분이라서
그걸 가지고는 본문에서 얘기하는 증상(?)이 뚜렷하게 나타나지 않을 듯 합니다.

winner의 이미지

http://kldp.org/node/23110

제 글은 읽지 마세요.
이 문제에 대한 답변이 될 겁니다.
결론은 linker 는 생각보다 단순하다. -_-a

fontutil의 이미지

꼭 GCC에 국한된 문제는 아닌것 같고요.
C/C++ 컴파일러가 다 그렇다고 보시면 됩니다.

파스칼 컴파일러의 경우 스마트링킹인가 뭔가하는 기술로
한 번도 참조되지 않은 함수는 링크에서 제외되지만
C/C++은 그게 무조건 모듈 단위로 처리됩니다.

게다가 그 모듈의 함수를 전혀 참조하지 않고
그 모듈의 외부 변수를 참조하기만 해도
그 모듈의 함수들까지 통째로 링크되는걸로 알고 있습니다.

이런 문제를 피하기 위해선 소스 파일을 함수 단위로
잘개잘개 쪼개면 됩니다. 물론 그만큼 소스 파일이 많아져서
관리에 좀 번거로운수도 있으나 어쩔 수 없을 것 같네요.

한라프로에서는 이런 방법을 통해서 불필요한 코드가 링크되는걸
원천 봉쇄했고 최종 실행파일 크기도 획기적으로 줄였지요.

요즘 나오는 최신 버전의 상용 C++ 컴파일러는 어떨지 모르겠습니다.
컴파일러나 링커 기술도 많이 발전했을텐데 혹시 최적화 옵션 설정에 따라
스마트링킹과 비슷한 기술이 C++에서도 될지 모르겠네요.

fontutil의 이미지

질문하신 내용을 MinGW로 직접 테스트해보고 있는데
뭔가 좀 이상하긴 이상하군요.
좀더 해 보고 다시 말씀드리겠습니다.

fontutil의 이미지

테스트 결과:

http://kldp.org/node/23110 링크에 있는
main.c, lib.c 두 소스를 컴파일 테스트한 결과입니다.

[BCC32 5.5.1 for Win32 컴파일러]

bcc32 -ebcctest1.exe main.c
bcc32 -ebcctest2.exe main.c lib.c

결과: bcctest1.exe, bcctest2.exe 두 파일의 크기는 52,224 byte로 동일.
단, 두 파일의 바이너리 비교를 했을 때 몇 바이트 다른 부분이 있음.

[MinGW - gcc 3.4.2]

gcc -o gcctest1.exe main.c
gcc -o gcctest2.exe main.c lib.c

결과:

gcctest1.exe -- 15,898 byte
gcctest2.exe -- 16,752 byte

--> 854바이트 차이

strip gcctest1.exe
strip gcctest2.exe

gcctest1.exe -- 5,632 byte
gcctest2.exe -- 6,144 byte

--> 512바이트 차이

역시 볼랜드 컴파일러가 더 똑똑하다고 봐도 될까요?

fontutil의 이미지

한 가지 방법을 찾아냈는데요.
이미 알고 계실지도 모르겠습니다만.

해당 모듈을 라이브러리(.a)로 만들어두면 되더군요.
그러니까 위의 서브모듈 lib.c를 컴파일하고..
담에 ar로 test.a라는 라이브러리를 새로 만들어서
거기에 lib.o를 추가해 넣었습니다.
그리고 컴파일

gcc -o gcctest1.exe main.c
gcc -o gcctest2.exe main.c test.a

이렇게 하니까 gcctest1.exe, gcctest2.exe 둘 다 크기가 같더군요.
라이브러리로 만들어두어야 참조되지 않은 모듈을
알아서 걸러내는 것 같네요.

fontutil의 이미지

헌데 오늘 보니까.. 단순히 makefile의 SRC함목에 소스파일 이름을 명시하고 main.c에서 #include로 헤더를 포함하기만해도 용량이 증가하는 이유가 무얼까요??

--> 이건 잘 모르겠네요. 제가 테스트를 해봤는데..

#include [stdio.h]
#include [stdlib.h]
#include [string.h]

위처럼 표준 헤더파일은 포함하나 안하나
컴파일된 실행파일 크기가 똑같던데요?
(각 헤더의 함수를 사용하지 않은 조건에서)

그 헤더가 직접 작성한 헤더인가요?
혹시 그 안에 외부변수 정의한게 있는건 아닌지..

syseop의 이미지

저는 해당 모듈을 언제 쓸지 몰라 SRC에 명시하여 모듈을 추가하고 #include로 함수 선언을 불러들인것뿐이죠.. 이것을 설명하려 했던것입니다. 헌데 이때 어떤함수에서도 모듈내의 함수도 호출하지 않았던거죠. 헌데 용량이 증가했다는것을 설명하다보니... 전달이 잘못된듯 하군요..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.