GCC 링커에서 사용하지 않는 함수는 제외 되어야하는게 아닌가요??
글쓴이: syseop / 작성시간: 화, 2007/05/29 - 9:21오후
Avr Gcc로 코딩중입니다. 마이컴의 용량이 작아 항상 코드사이즈가 신경이 쓰이는데
아래와 같은 문제에 봉착하여 원인을 알고자 이곳에 글을 올립니다.
Pc의 Gcc또한 같은 문제일것이라 생각하는데 어느 부분에서.. 왜 용량이 증가하는 것일까요?
//-----------------------------------------------------------------------
그동안 알고 있기로는 각각의 재배치 가능 파일에는 들어있더라도 링커가 사용하는 함수만 골라 hex파일을 만
드는 줄알았습니다.
헌데 오늘 보니까.. 단순히 makefile의 SRC함목에 소스파일 이름을 명시하고 main.c에서 #include로 헤더를 포함하기만해도 용량이 증가하는 이유가 무얼까요??
main.c에서는 해당 파일내의 어떤함수도 사용하지 않았는데 말이죠...
혹 이점에 대해 알고 계신 분 안계신가요???
CCS-C등의 일부 특정마이컴 전용 컴파일러의 경우 파일내 함수가 포함되어있더라도 컴파일시에 사용하지 않으면 제외되어 hex파일의 용량이 증가 하지 않는데...
GCC의 경우 어떻게 해야 사용하지 않는 함수를 결과물에서 배재할수있는 것일까요??
Forums:
안타깝네요.
같은 문제로 고민하고 있었는데 아무런 답변이 없군요.
일단 제가 아는 바는 링커 옵션에 --gc-sections를 사용하면 참조되지 않는 오브젝트(*.o)는 제거가 된다는 겁니다. 근데 이걸로는 부족하죠. 혹 아시는 분 꼭 답변 부탁드립니다.
그런가요? 저는 puts만
그런가요?
저는 puts만 쓰다가 printf 를 포함하면 실행파일이 더 커지던데...(둘다 stdio.h)
보통 표준
보통 표준 C라이브러리는 동적라이브러리인 경우가 대부분이라서
그걸 가지고는 본문에서 얘기하는 증상(?)이 뚜렷하게 나타나지 않을 듯 합니다.
제 바보같은 글을 볼 수 있는 thread...
http://kldp.org/node/23110
제 글은 읽지 마세요.
이 문제에 대한 답변이 될 겁니다.
결론은 linker 는 생각보다 단순하다. -_-a
꼭 GCC에 국한된
꼭 GCC에 국한된 문제는 아닌것 같고요.
C/C++ 컴파일러가 다 그렇다고 보시면 됩니다.
파스칼 컴파일러의 경우 스마트링킹인가 뭔가하는 기술로
한 번도 참조되지 않은 함수는 링크에서 제외되지만
C/C++은 그게 무조건 모듈 단위로 처리됩니다.
게다가 그 모듈의 함수를 전혀 참조하지 않고
그 모듈의 외부 변수를 참조하기만 해도
그 모듈의 함수들까지 통째로 링크되는걸로 알고 있습니다.
이런 문제를 피하기 위해선 소스 파일을 함수 단위로
잘개잘개 쪼개면 됩니다. 물론 그만큼 소스 파일이 많아져서
관리에 좀 번거로운수도 있으나 어쩔 수 없을 것 같네요.
한라프로에서는 이런 방법을 통해서 불필요한 코드가 링크되는걸
원천 봉쇄했고 최종 실행파일 크기도 획기적으로 줄였지요.
요즘 나오는 최신 버전의 상용 C++ 컴파일러는 어떨지 모르겠습니다.
컴파일러나 링커 기술도 많이 발전했을텐데 혹시 최적화 옵션 설정에 따라
스마트링킹과 비슷한 기술이 C++에서도 될지 모르겠네요.
질문하신 내용을
질문하신 내용을 MinGW로 직접 테스트해보고 있는데
뭔가 좀 이상하긴 이상하군요.
좀더 해 보고 다시 말씀드리겠습니다.
테스트
테스트 결과:
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바이트 차이
역시 볼랜드 컴파일러가 더 똑똑하다고 봐도 될까요?
한 가지 방법을
한 가지 방법을 찾아냈는데요.
이미 알고 계실지도 모르겠습니다만.
해당 모듈을 라이브러리(.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 둘 다 크기가 같더군요.
라이브러리로 만들어두어야 참조되지 않은 모듈을
알아서 걸러내는 것 같네요.
헌데 오늘 보니까..
헌데 오늘 보니까.. 단순히 makefile의 SRC함목에 소스파일 이름을 명시하고 main.c에서 #include로 헤더를 포함하기만해도 용량이 증가하는 이유가 무얼까요??
--> 이건 잘 모르겠네요. 제가 테스트를 해봤는데..
#include [stdio.h]
#include [stdlib.h]
#include [string.h]
위처럼 표준 헤더파일은 포함하나 안하나
컴파일된 실행파일 크기가 똑같던데요?
(각 헤더의 함수를 사용하지 않은 조건에서)
그 헤더가 직접 작성한 헤더인가요?
혹시 그 안에 외부변수 정의한게 있는건 아닌지..
아.. include는 차이가 없습니다.
저는 해당 모듈을 언제 쓸지 몰라 SRC에 명시하여 모듈을 추가하고 #include로 함수 선언을 불러들인것뿐이죠.. 이것을 설명하려 했던것입니다. 헌데 이때 어떤함수에서도 모듈내의 함수도 호출하지 않았던거죠. 헌데 용량이 증가했다는것을 설명하다보니... 전달이 잘못된듯 하군요..
댓글 달기