Compiler 옵션

OS/리눅스 & 유닉스 2012. 5. 23. 15:01

C언어의 여러가지 컴파일러에 대해서 알아봅시다.

 

Compiler의 종류에 따른 옵션

 

아래 사이트에 정말 잘 정리 되어 있다.

 

LinuxSolarisHP-UXCompaq (Digital) Tru64AIXSGIWin32MacOS XVMSOS/390
Version[kernel 2.x, GCC 2.95.x and later][2.8][11][4.x][4.3 and later][Irix 6.5][NT 4][10.x][unmaintained][unmaintained]
1compiler flag (position independent code)-fPIC-KPIC, -Kpic+z/+Zxxxxxxxx-KPIC (default)xxxx-fno-commonxxxx-DLL
2ashared library creation flag-shared-G-b-shared-bM:SRE-sharedlink /DLLcc -bundle, -dynamiclib
libtool -dynamic
/SHARExxxx
2bshared library creation (C++)g++ -fPIC -shared -oCC -G -oaCC -b -ocxx -shared -oxlC -G (or -qmkshrobj)
obsolete:/usr/vacpp/bin/makeC++SharedLib -G -o
(was in /usr/ibmcxx/bin or /usr/lpp/xlC/bin/)
CC -shared -oCL -LD -Fexxx.DLL??
libtool -dynamic
????
2cstatic archiver (C++)arCC -xar -oarararCC -ar -oLIB (avoid link /lib that creates __impl symbols)??
libtool -static
????
3alibrary name(ld option) -soname name-h name(ld option) +h name(ld option) -soname namexxxx(ld option) -soname name/OUT:name-compatibility_version, -current_version/SHARE=xxxx
3bfile extension.so.so.sl.so.so (or .a).so.DLL.dylib.EXE??
4executable link options-Bdynamic
-Lpath -lname
-Bdynamic
-Lpath -lname
-a,shared
-Lpath -name
-no_archive
-Lpath -lname
-brtl
-bdynamic
-Lpath -lname
-Bdynamic,
-Lpath -lname
Controlled by .lib files??xxxxfilename/SHAREABLE
5aruntime path specification-rpath <path>-R <pathlist>-Wl,+b <pathlist> -Wl,+s-rpath <path>-blibpath:<path>
(by default, it is set to the arguments of -L)
-rpath <path>/LIBPATH:-install_name <path>xxxxxxxx
5bDoes not build the path for shared libraries into the executabledefault-norunpathchatr +b disable <file>default-blibpath:/usr/lib:/libdefault????????
6controlling symbolsusing a script file (see "info ld")-z defs/ nodefs/ muldefs+v[no] shlibunsats-expect [error] _unresolvedxxxx-ignore[no] _unresolved/FORCE: MULTIPLE [UNRESOLVED]??xxxxxxxx
LinuxSolarisHP-UXCompaq (Digital) Tru64AIXSGIWin32MacOS XVMSOS/390
7exports file/link option
(see notes)
using a script file (see "info ld")using a script file (see "man ld")+e,symname-exported_symbol.exp-exported_symbol
-exports_file filename
.def/__declspec(dllexport)-exported_symbols_list/SYMBOL_TABLE=(...).x file/
#pragma export()
8hiding symbolsusing a script file: VERSION command (see "Version Script" section in "info ld")using a script file (see "man ld") (see thisarticle)-h symname-hidden_symbol, -hiddenxxxx-hidden_symbol,
-hiddens_file filename
using a .def file-unexported_symbols_listxxxxxxxx
9runtime library pathLD_LIBRARY_PATHLD_LIBRARY_PATH
LD_LIBRARY_PATH_64
SHLIB_PATH
LD_LIBRARY_PATH (64 bits)
LD_LIBRARY_PATHLIBPATHLD_LIBRARY_PATH
LD_LIBRARYN32_PATH
LD_LIBRARY64_PATH
. and then PATHDYLD_LIBRARY_PATH
DYLD_FALLBACK_LIBRARY_PATH
SYS$SHARELIBPATH
10symbol binding-Bsymbolic-Bsymbolic-Bsymbolic /immediate /deferredxxxxxxxx-Bsymbolicxxxx??xxxxxxxx
11runtime debugging(c.f. man ld.so)
LD_BIND_NOW
LD_TRACE_LOADED_OBJECTS
LD_DEBUG=help
ltrace
(c.f. man ld.so.1)
LD_BIND_NOW
LD_DEBUG
ld -D help
(c.f. man dld.sl)
_HP_DLDOPTS
(c.f. man loader)
LD_BIND_NOW
_RLD_ARGS
LDR_CNTRL(c.f. man rld)
LD_BIND_NOW
_RLD_PATH, _RLD_ARGS
xxxxDYLD_BIND_AT_LAUNCH
DYLD_PRINT_LIBRARIES
DYLD_PREBIND_DEBUG
xxxxxxxx
12runtime preloadLD_PRELOADLD_PRELOADLD_PRELOAD (probably HP-UX >= 11)_RLD_LIST "xxx.so:DEFAULT"xxxx_RLD_LIST "xxx.so:DEFAULT"??DYLD_INSERT_LIBRARIES????
13loaderld.sold.sodld.slloaderxxxxrldxxxxdyldxxxxxxxx
14runtime performancexxxxxxxxfastbind tool-quickstart_infoxxxx-quickstart_info/DELAYLOADxxxxxxxxxxxx
LinuxSolarisHP-UXCompaq (Digital) Tru64AIXSGIWin32MacOS XVMSOS/390
15versioningusing a script file: VERSION command (see "info ld")using a script file (see "man ld")
-M mapfile
xxxxxxxxxxxx-set_version/-exact_version/
-ignore_version
/VERSION:major.minor??/GSMATCH=xxxx
16entry pointsxxxxxxxxxxxxxxxxxxxxxxxxDllMainxxxxxxxxxxxx
17dynamic loading /
dynamic symbol access
dlopen / dlsymdlopen / dlsymshl_load / shl_findsym
(64 bits) dlopen / dlsym
dlopen / dlsymloadquery/loadbind
(AIX 4.2) dlopen / dlsym
dlopen / dlsymLoadLibrary / GetProcAddress"man 3 dyld"lib$find_image_symboldllload / dllqueryfn/ dllqueryvar
18utilitiesldd, ldconfig, objdump, ltrace, readelfldd, elfdump, pvs, dumpstabs (compilers V.6), crle (Solaris>=8)chatr
odump
ldd, elfdump (HP-UX >= 11)
odump -Dldump -H
ldd (in AIX tools)
elfdump -Dl
pldd
ldd (IRIX >= 6.5)
DUMPBIN, depends, EXEHDR, link -dumpotoolANALYSE/IMAGExxxx
19documentationman: ld, ld.so, ldd
info: ld, gcc, binutil
HOWTO: ELF-HOWTO, GCC-HOWTO
man: ld, ld.so.1, ldd, pvsman: ld, dld.sl, chatrman: ld, loader, odumpman: ld, dumpman: dso, ld, rld, elfdump, lddMSDNman: ld, libtool, dyld, otool????
LinuxSolarisHP-UXCompaq (Digital) Tru64AIXSGIWin32MacOS XVMSOS/390

 

http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html

 

GCC Simple Option

 

-Idir 옵션

dir은 디렉토리 이름 이고 -I와 디렉토리 이름을 붙이면 라이브러리를 찾아준다.

 

-Dmacro

Ex) -DMAXLEN=255 = #define MAXLEN 255

 

-M Makefile파일을 만들 때 파일 컴파일 규칙을 stdout에 찍어준다.

 

-Wall 모든 경고 메시지를 출력하도록 한다.

 

-O -O2 -O3 최적화 모드 뒤로 갈수록 더 빠르게 많은 옵션으로 최적화를 한다.

 

-p, -pg 프로파일링

gcc -pg -o main main.cpp

gprof hello gmon.out

 

ar -t /usr/lib/libc.a

ar -r libsample.a main.o

 

GCC Compile 과정

 

  1. preprocessing

    • gcc -E main.cpp
  2. compling

    • cc1
    • cc1plus
  3. Assembling

    • gcc -S main.cpp
    • gcc -c main.cpp 링크를 하지말고 object 코드까지만 만들어라 하는 옵션
  4. Linking

    • -static dynamic linking을 지원하고 있는 시스템에서 static linking을 하라는 옵션

 

우선 내가 요세 쓰고 있는 컴파일러 종류

 

  • visual studio 6,7,8의 컴파일러 CL.exe
  • gnu compiler gcc, g++
  • xlC compiler
  • aCC compiler

 

새로 알게 된 xlC에 대해서 스크랩

 

1. 32bit/64bit 컴파일

 

기본적으로 AIX용 컴파일러는 프로그램을 32bit 모드로 컴파일한다. 원하는 bit 모드를 지정하려면 컴파일러, 아카이버, 링키지 에디터 등을 위해 아래와 같이 bit 모드 옵션이나 환경변수를 사용할 수 있다.

- 컴파일러 옵션: -q32/-q64

- OBJECT_MODE 환경변수: 32/64

- Archive(ar) 옵션: -X32/-X64/-X32_64

   - 링키지 에디터(ld) 옵션: -b32/-b64

아래는 64-bit 오브젝트를 생성하도록 컴파일하고 확인하는 예..

 

  1. $ xlf -c -q64 bt.f
  2. $ dump -ov -X32_64 bt.o
  3. bt.o:
  4.                         ***Object Module Header***
  5. # Sections      Symbol Ptr      # Symbols       Opt Hdr Len     Flags
  6.          4      0x000026fe             81                    0     0x0000
  7. Flags=( )
  8. Timestamp = "Feb 14 11:18:07 2002"
  9. Magic = 0x1f7  (64-bit XCOFF)

 

 위와 같이 dump 명령을 사용하면 실행 파일 또는 오브젝트 파일이 32-bit 모드인지 64-bit 모드인지 확인할 수 있는데, 위의 예에서는 '64-bit XCOFF'로 되어 있으므로 64-bit 오브젝트 파일임을 알 수 있다. 또한, dump 명령의 옵션인 -X32_64, -X32, -X64는 대상 파일의 bit 모드를 지정하는 것으로, 모를 때는 위와 같이 -X32_64를 사용하면 된다.

 

 AIX 4.3 환경에서 컴파일한 64-bit 프로그램은 AIX 5L에서는 실행되지 않으므로 AIX 5L용으로 다시 컴파일 해주어야 하지만, 32-bit 프로그램은 AIX5L 이전의 버전에서 컴파일 된 실행파일을 그대로 사용할 수 있다.

운영체제의 32/64-bit 모드는 'ls -l /unix' 명령으로 확인할 수 있는데 /unix가 /usr/lib/boot/unix_64에 링크되어 있으면 64-bit 커널이고, /usr/lib/boot/unix_mp에 링크되어 있으면 32-bit 커널이다.

 

 xlC 에 대해 알게 된것들

 

 xlC는 주석을 엄밀히 확인하고 일반적인 c style의 comment에 대해 warnning하는 경우가 있다.

그리고 char type을 default로 unsigned값으로 보고 있다. char타입에 대해 멀티플렛폼으로 작성할 여부가 있는 프로그램의 경우 변수의 type을 char보다는 __uint8같은 명확한 type으로 명확히 정의함이 괜찮은 방법이다.

 

 

  1. "sn3crypt.h", line 338.18: 1540-0804 (W) The characters "/*" are detected in a comment.
    "sn3ole.h", line 189.73: 1540-0804 (W) The characters "/*" are detected in a comment.
    "sn3pcm.h", line 70.17: 1540-0848 (S) The macro name "SN3_ARCHITECTURE" is already defined with a different definition.
    "sn3pcm.h", line 54.17: 1540-0425 (I) "SN3_ARCHITECTURE" is defined on line 54 of "sn3pcm.h".
    "sn3xls.h", line 51.49: 1540-0804 (W) The characters "/*" are detected in a comment.
    make: 1254-004 The error code from the last command is

 

aix5, xlC컴파일러에서 next를 실행한 오류

 

 컴파일을 하다가 난 warnning과 error이다. 여러 플렛폼에 있는 다양한 컴파일러로 컴파일을 할때 한번에 되지 않느다면 역시 컴파일러의 옵션을 봐야 한다. 여러종류의 컴파일러를 만났을 때 당황하지 말고 믿을 수 있는 것은 컴파일러에서 생성한 경고나 오류, 그리고 컴파일러 옵션임을 잊지 않는다.

 

위의 경우는 (W)는 warnning (S)에서 에러를 냈으므로 70 line을 찾는다.

 

aCC compiler

 

  • case 1: using namespace std

 

  1. Error (future) 600: "sn3ole.h", line 313 # Type specifier is omitted; "int" is no longer assumed.
        typedef map<int, int> SN3OLE_DIR_LIST; /*< PPS Directory Entry L
        ^^^^^^^

 using namespace std;를 정의해야 하는데 하지 않은 경우

 

 어떤 버전의 컴파일러는 using namespace std가 있어야 하고 어떤 컴파일러는 없어야 한다.

왜그럴까~? -_-;;; 만든사람 마음이다. 다음에 빌드할때는 man을 보고 옵션을 좀 따라가봐야 할듯

 

 

  • case 2: 시스템 아키텍쳐의 디파인

 

아이테니엄 64비트 컴퓨터의 경우

 defined(__ia64) || defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64) 의 메크로가 컴파일러 단에서 미리 정의되어 있다. 혹시 시스템이 아이테니엄 64비트 이지만 아키텍쳐의 정의를 타지 않는 경우 컴파일러에서 제공하는 메크로의 명칭이 무엇인지 확인해봐야 할 경우가 있다. 이런 경우는 해당 컴파일러의 헬프를 보면서 찾아보자.

 

  1. man aCC

 컴파일러의 헬프를 알아보자

 

 

 

 

gcc compiler option

 

g++ compiler 옵션에 대해서 알아봅시다.

 

make (Makefile)

g++ -g debugging mode로 빌드

 

gdb linux debugger

gdb - 링크를 따라가자

 

CL.exe compiler

 

Visual Studio에서 빌드자동배치파일을 만들려면..

  • Visual Studio 6.0을 열어서 project - export makefile을 선택하여 makefile을 export한다.
  • 다른 환경으로 옮길때는 CL.exe Path를 잡아준다.
  • Clean에 몇몇 파일을 추가한다.
  • 아래 링크에 필요한 Library를 추가한다.

 

Debug Mode vs Release Mode

 

  • Pointer - 초기화 되지 않은 포인터의 경우 디버그모드에서는 임의값 0xCD로 초기화를 수행하지만 릴리즈에서는 초기화를 수행하지 않는다. 디버그 모드에서 컴파일러 옵션을 조정하여 초기화 하지 않은 포인터 변수를 사용하는것을 예방 할 수 있다. /GZ 컴파일러 옵션은 기본적으로 VC++ 프로젝트 셋팅에서 기본값이 아니므로 필요하다면 추가해서 초기화 되지 않는 포인터의 값을 0xCC로 채우도록 해줘야 한다. /GZ 컴파일러 옵션의 가장 큰 목적은 초기화 하지 않은 메모리 변수의 값을 0xCCCCCCCC로 채워서 디버깅중에 개발자가 초기화 하지 않은 값임을 알 수 있도록 하는것이다.
    디버그모드에서 deallocator에 의해 해제된 메모리에 채워지는 값은 0xDD 이다.

 

  • Heap - 디버그 모드에서 힙영역에 메모리를 할당하게 되면 guard byte( 0xFD로 초기화 )를 추가적으로 할당하여 가장 흔하게 범하는 zero-base의 arrary 인덱스를 잘못 계산하여 경계를 벗어난 영역을 접근하거나 지우려고 하는 코드를 작성했다고 하더라도 디버그 모드에서는 크래쉬가 발생하지 않을 수 있다. 이런 잠재적인 버그를 가진 프로그램을 릴리즈 모드에서 실행시키게 되면 크래쉬가 발생하게 된다.

 

  • ASSERT - ASSERT 구문은 디버그 모드에서는 공백으로 대체되어지는 점을 잊고 아래와 같이 쓰게 되는 경우 이 코드는 릴리즈에서는 공백으로 대체되어 실제로 체크를 할 수 없게 된다. ASSERT (OpenMyWindow () != NULL);
    위의 코드를 다음과 같이 바꾸게 되면 디버그와 릴리즈 모드 모두 정상적으로 동작하게 된다. hWND = OpenMyWindow();
    ASSERT (hWND != NULL);
    이런 체크를 릴리즈에서도 하고 싶다면 VERITY 매크로를 사용하도록 하자.
    Prototypes 사용자 정의 메시지 처리를 위해 ON_MESSAGE 매크로를 사용중이라면 메시지 핸들러의 원형을 요구하는 타입에 정확하게 맞게 선언해줘야 한다. 디버그 모드에서는 원형에 일치하지 않더라도 컴파일러가 수정하여 동작하도록 만들어줘 버그를 발견하기 힘들게 만든다. afx_msg LRESULT <class>::OnMyMessage (WPARAM wParam, LPARAM lParam);
    Optimization Max Speed 옵션은 속도 최적화에 촛점을 맞추고 있기 때문에 최적화 과정에서 안전하지 않을수 있다. 기본적으로 릴리즈 모드에서는 Maximize Speed 옵션이 기본이지만 안전하게 속도 최적화를 보장하는 Minimize Size를 추천한다. 그리고, #pragma 지시자를 사용하여 특정 영역의 옵션을 설정 할 수 있다는것을 기억하자. #pragma optimize("", off)
    // some code here #pragma optimize("", on)

: