라이브러리크기와 실행파일과의 관계

koddakgi의 이미지

공유라이브러리는 제외하고
정적인 라이브러리를 링크하는 실행파일의 경우 라이브러리의 모든
모듈들이 실행화일로 반입되는지 궁금합니다.
제가 알기로 사용하는 모듈만 실행파일로 반입되는걸로 알고 있는데
옆에서 자꾸 전부포함된다구 합니다.
그렇다면 라이브러리 크기가 500k이면 실행파일의 크기는 최소한 500k 보다는크겠죠.
제가 잘못알고 있는걸까요?

tifler의 이미지

존칭생략합니다.

[lib1.c]
int addval;

int add(int a, int b)
{
    addval = a + b;
    return addval;
}

[lib2.c]
int mulval;

int mul(int a, int b)
{
    mulval = a * b;
    return mulval;
}

[lib3.c]
int addval2;
int mulval2;

int add2(int a, int b)
{
    addval2 = a + b;
    return addval2;
}

int mul2(int a, int b)
{
    mulval2 = a + b;
    return mulval2;
}

[main1.c]
#include <stdio.h>

extern int add(int, int);
extern int mul(int, int);

int main(int argc, char argv)
{
    return printf("add : %d\n", add(1, 1));
}

[main2.c]
#include <stdio.h>

extern int add(int, int);
extern int mul(int, int);

int main(int argc, char argv)
{
    return printf("add : %d\n", mul(1, 1));
}

[main3.c]
#include <stdio.h>

extern int add(int, int);
extern int mul(int, int);
extern int add2(int, int);
extern int mul2(int, int);

int main(int argc, char argv)
{
    return printf("add : %d\n", mul2(1, 1));
}

우선 lib[1-3].c를 각각 컴파일하여 .o를 만들자

gcc -c *.c

그런후 lib.a로 slib을 만들자.

ar cr lib.a *.o

이제 main[1-3].c를 컴파일한후 링크까지 하자

gcc -o 1 main1.c lib.a
gcc -o 2 main2.c lib.a
gcc -o 3 main3.c lib.a

이런후 각 excutable의 심볼을 확인해 볼까나...

nm 1

...
08048360 T add
08049538 B addval
...
08048328 T main
...

nm 2

...
08048328 T main
08048360 T mul
08049538 B mulval
...

nm 3

...
08048360 T add2
0804954c B addval2
...
08048328 T main
08048375 T mul2
08049550 B mulval2
...

1 = main1 모듈 + lib1 모듈 + 베이스라이브러리
2 = main2 모듈 + lib2 모듈 + 베이스라이브러리
3 = main3 모듈 + lib3 모듈 + 베이스라이브러리

따라서 다음과 같은 결론이 나온다.
<B>모든 링크의 단위는 모듈이다.</B>

주의해서 볼것은 바로 3번인데...

lib3.c에는 addval2, add2가 존재하지만, 실제로 main3에서 사용은 되지 않는다.
그런데도 분명 링크가 되어 있다.
즉 모듈단위로만 링크가 가능하고, 심볼단위의 링크는 불가능한 것이다.

여기서 느껴야할것!!!

실행화일의 크기가 요즘은 중요치 않게 생각하지만
그래도 가능하다면 모듈단위로 분리하는것이 좋다.

만약 수백개의 함수들이 들어있는 한개의 모듈을 링크를 하는 이유가
1개의 함수 때문이라면???

좀 불합리하지 않을까 하는 생각이 든다...

그렇다고 함수단위로 쪼갠다면??? :-)

/***********************
* while(1) sleep(INFINITE);
***********************/

koddakgi의 이미지

자세하게 설명해 주셔서 정말 감사드립니다.
일단 제생각이 크게 틀린건 아니군요...(휴..다행이다)
모듈단위로 링크된다는 말은 하나의 파일단위이라고 생각해도
되는건지.... 보통하나의 파일이 하나의 오브젝트 모듈을 만들어 내니까요
그럼 수고하십시요

여자는 도대체 무엇으로 사는가?

tifler의 이미지

koddakgi wrote:
자세하게 설명해 주셔서 정말 감사드립니다.
일단 제생각이 크게 틀린건 아니군요...(휴..다행이다)
모듈단위로 링크된다는 말은 하나의 파일단위이라고 생각해도
되는건지.... 보통하나의 파일이 하나의 오브젝트 모듈을 만들어 내니까요
그럼 수고하십시요

맞습니다. object 파일 단위를 모듈단위로 표현한 것입니다.

/***********************
* while(1) sleep(INFINITE);
***********************/

windower의 이미지

다른 질문입니다만,
2,3에서
각각 부분이 main함수 뒷부분으로 mul과 mul2/mulval2가 위치하는데
1번의 경우에는 add/addval부분이 main부분 앞쪽에 위치하고 있는 것을 볼 수 있습니다.

링크번지의 위치는 어떤 순서가 있는 것인가요?
아니면 항상 add는 main보다 앞에 위치하고,
mul은 main부분 뒤에 위치 할 수 밖에 없는 이유가 있거나?
혹은 무작위(?) 인건가요?

Always

pynoos의 이미지

windower wrote:
다른 질문입니다만,
2,3에서
각각 부분이 main함수 뒷부분으로 mul과 mul2/mulval2가 위치하는데
1번의 경우에는 add/addval부분이 main부분 앞쪽에 위치하고 있는 것을 볼 수 있습니다.

링크번지의 위치는 어떤 순서가 있는 것인가요?
아니면 항상 add는 main보다 앞에 위치하고,
mul은 main부분 뒤에 위치 할 수 밖에 없는 이유가 있거나?
혹은 무작위(?) 인건가요?

함수의 위치는 아무 상관 없습니다. 발견되는 대로 일수도 있고.. 어쨌거나 같은 section 끼리 모이는 것 외에는 크게 상관없습니다. 단 최적화가 들어가면, call-graph가 가까운 것 끼리는 모을 수 도 있겠습니다
최근의 VC에 실험적으로 들어가더군요.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/profileguidedoptimization.asp

그리고 tifler 님께서 재밌는 실험을 해주셨는데, 사실 몇가지 주의해야할 부분이 더 있습니다.

addval, mulval 같은 전역 변수에 대해서는 static 으로 만들어야 옳습니다.
마찬가지로 외부에서 사용하지 않는 함수들은 (위의 예에는 없습니다만) 모두 static을 붙여야합니다.

이렇게 할 경우, 참조되지도 않고, exported 되지도 않는 변수나 함수가 생길 수 있습니다. 이런 것을 garbage라고 할 수 있는데,

AIX 링커의 경우 이런 녀석들을 모두 제거하는 것이 기본 동작으로 되어 있습니다. 이런 경우, 모듈에 들어 있는 모든 녀석은 다 링크된다는 말은 부분적으로 옳지 않습니다.

AIX 의 경우 모든 library가 shared object 이기도 하고, 특이한 링커의 행동도 있기도 하기 때문에, 위 내용은 구현에 따라 다르다고 해야 옳습니다.

물론, exported된 심볼 즉 static이 아닌 변수 들은 링커의 마수를 피해가기 때문에 계속 존재하게 됩니다.

골치아픈 예로, cvs id 같은 경우

static const char id[] = "$Id$";

가 들어가게 되는데, AIX 의 경우 모두 제거 됩니다.

windower의 이미지

답변감사합니다.
그런데 검색해봐도 AIX란게 마땅히 뭔지
잘 모르겠습니다 ㅠ_ㅠ

IBM관련 OS도 나오던데 ㅡ_ㅡ;;
그게 그 AIX인지요?

Always

pynoos의 이미지

AIX 는 UNIX의 한 종류입니다. IBM에서 만들죠...

개인적으로 AIX 싫어합니다... :(

tifler의 이미지

pynoos wrote:
그리고 tifler 님께서 재밌는 실험을 해주셨는데, 사실 몇가지 주의해야할 부분이 더 있습니다.

addval, mulval 같은 전역 변수에 대해서는 static 으로 만들어야 옳습니다.
마찬가지로 외부에서 사용하지 않는 함수들은 (위의 예에는 없습니다만) 모두 static을 붙여야합니다.

이렇게 할 경우, 참조되지도 않고, exported 되지도 않는 변수나 함수가 생길 수 있습니다. 이런 것을 garbage라고 할 수 있는데,

AIX 링커의 경우 이런 녀석들을 모두 제거하는 것이 기본 동작으로 되어 있습니다. 이런 경우, 모듈에 들어 있는 모든 녀석은 다 링크된다는 말은 부분적으로 옳지 않습니다.

맞습니다.
당연히 모듈내에서만 사용되는 symbol들은 static으로 scope제한을 둬야겠지요.
여기서는 symbol의 export테스트 적인 측면보다는,
과연 사용하지 않는 symbol들은 어떻게 처리(링크)되는가를 알기위해
일부러 export시킨것입니다. ^^

/***********************
* while(1) sleep(INFINITE);
***********************/

koddakgi의 이미지

.

Quote:
AIX 의 경우 모든 library가 shared object 이기도 하고, 특이한 링커의 행동도 있기도 하기 때문에, 위 내용은 구현에 따라 다르다고 해야 옳습니다

구체적으로 shared object 란 어떤것을 말하는건가요?
아님 모든 오브젝트를 그렇게 부른것인지, 혹시 실행시간에 링크되는 오브젝트를 지칭하시는건지(*.so)
링크시 중복경고가 많이 발생합니다. 대상체도 그렇고 함수도 그렇고... 라이브러리 만들때
옵션을 잘못줘서 그런것 같기도 하고... 찾을려고 노력했지만 찾지 못해서 ..걍 쓰고 있습니다.

추가질문 각각의 파일에서 같은이름의 변수를 선언했을때
두변수는 extern 으로 선언하지 않았는데도 공유가 되더군요.
이런게 C 표준에 정의된 행동인지 알고싶습니다.
함수호출할때 이런식으로 데이터를 주고 받기도 합니다.
좀 위험하기는 합니다만..

여담이지만 AIX가 싫은 특별한 이유가 있습니까?

여자는 도대체 무엇으로 사는가?

eek의 이미지

http://wiki.kldp.org/HOWTO//html/Program-Library-HOWTO/index.html
위의 링크를 보시면 라이브러리에 관한 소개가 있습니다.
한번 읽어보시면 도움이 될뜻합니다.

개인적으로 HP-UX나 AIX를 싫어합니다. 그래도 AIX는 양반입니다.
HP-UX는 정말 싫조^^;
아마도 UNIX를 처음 접한게 Linux이어서 그런가 봅니다.
Solaris에도 gnu software들이 잘 설치되는데
이놈에 HP는 설치가 잘않되고 왜 이렇게 않되는것도 많은지.. 공력이 부족한 제
탓이라고 생각합니다만 :oops:

Perl 만세~~~

pynoos의 이미지

koddakgi wrote:
링크시 중복경고가 많이 발생합니다. 대상체도 그렇고 함수도 그렇고... 라이브러리 만들때
옵션을 잘못줘서 그런것 같기도 하고... 찾을려고 노력했지만 찾지 못해서 ..걍 쓰고 있습니다.


중복되는 것을 제거하는 데는 nm 이 가장 좋은 툴입니다. 혹 공유하는 header에 함수나 변수의 정의가 들어 있는지 확인해 보세요.

koddakgi wrote:
.

Quote:
AIX 의 경우 모든 library가 shared object 이기도 하고, 특이한 링커의 행동도 있기도 하기 때문에, 위 내용은 구현에 따라 다르다고 해야 옳습니다

구체적으로 shared object 란 어떤것을 말하는건가요?
아님 모든 오브젝트를 그렇게 부른것인지, 혹시 실행시간에 링크되는 오브젝트를 지칭하시는건지(*.so)

AIX 는 약간 다른 방식의 링킹과 로딩이 일어납니다.

http://www.mager.org/aix/?C=N;O=D

http://www.mager.org/aix/aix-linking.pdf
http://www.mager.org/aix/aix_ll.pdf

koddakgi wrote:
.
추가질문 각각의 파일에서 같은이름의 변수를 선언했을때
두변수는 extern 으로 선언하지 않았는데도 공유가 되더군요.
이런게 C 표준에 정의된 행동인지 알고싶습니다.
함수호출할때 이런식으로 데이터를 주고 받기도 합니다.
좀 위험하기는 합니다만..

항상 두 개의 오브젝트에 중복 정의되어 있다고 링킹 에러가 나는 것은 아닙니다. 중요한 코드하나 보여드리면...

$ more a.c b.cc
::::::::::::::
a.c
::::::::::::::
int a;
int b=1;
::::::::::::::
b.cc
::::::::::::::
int c;
int d=1;

$ gcc -c a.c
$ g++ -c b.cc
$ nm a.o b.o

a.o:
00000004 C a
00000000 D b

b.o:
00000000 B c
00000000 D d

같은 코드인데, C와 C++에서 만드는 오브젝트가 달라집니다. C에서는 "C"라는 Common 형으로 만들어 냅니다.
초기값이 없는 변수들은 이른바 BSS라는 영역에 만들어지는 것으로 알려집니다. 그 중에서도 C Compiler는 그것을 다른 녀석과 공유할 수 있는, 즉 링크 타임에서 같은 변수 정의가 다른 곳에서 Common으로 나온다면
하나는 제거되는 모습을 가집니다. 그런데 C++ compiler는 그렇지 않군요...

koddakgi wrote:
.
여담이지만 AIX가 싫은 특별한 이유가 있습니까?

AIX는 다른 System V 계열과 사뭇다른 모습입니다. man page도 다르지요.. shared object도 sl, so가 아닌 .a 입니다.. 그리고 4.1.x까지는 truss, strace 같은 프로세스의 System call tracer도 없습니다.

linux fortune 중에
http://www.nmt.edu/~houdini/signatures.txt

Whip me. Beat me. Make me maintain AIX.

이런 말도 있지요.. ;)

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.