GCC
The GNU Compiler Collection (GCC) is a compiler system produced by the GNU Project supporting various programming languages.
Categories
- GCC:Attribute
- GCC:__builtin_expect
- GCC:Optimization: GCC 최적화(Optimization)관련 내용.
- GCC:DependencyHeaderFiles: 종속성 파일들 목록.
- Stack Smashing Protector (SSP)
- libstdc++
- GCC Optimization Option - GCC의 최적화 옵션
- gcov - GNU CC의 코드 커버리지 도구.
- gprof - GNU 프로파일러에 대한 설명.
- pch - Pre-compiled header
How to install
GCC4.8.2를 CentOS6에서 설치하는 방법은 아래와 같다.
## Install pre-requirements:
$ yum install gmp-devel mpfr-devel libmpc-devel
## Download and extract gcc 4.8.2 source tar ball:
$ curl -O ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.gz; tar zxf gcc-4.8.2.tar.gz
$ cd gcc-4.8.2; ./configure --enable-languages=c,c++ --disable-multilib
## Build and install:
$ make; make install
Debian:
RedHat:
in Ubuntu
Ubuntu에서 GCC 4.9버전을 설치하고 싶다면 아래와 같이 설치하면 된다.
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test
$ sudo apt-get update
$ sudo apt-get install gcc-4.9
만약, 기본 gcc
명령을 gcc-4.9
로 대체하고 싶다면 alternatives명령을 사용하면 된다.
간단한 사용 방법
GCC 사용방법에 대한 예제.
컴파일 방법. (오브젝트파일이 출력된다.)
실행파일 작성 방법. (오브젝트 파일을 입력해야 한다.)
Objective-C 소스코드 컴파일 방법.
MinGW Static and Dynamic Libraries
Compiling the Static Library
Building the Library.
Referencing the Library.
Compiling the Dynamic Library
Referencing the Library.
Environment Variables
참고로 LD_DEBUG는 GNU C 항목에서 확인할 수 있다.
- LD_LIBRARY_PATH
- ld에서 사용할 링커 라이브러리가 모여진 디렉토리 경로 모음.
Library dependency
라이브러리는 종속성 문제가 존재한다. 이는 gcc 컴파일 할 경우 명령행 인자 순서에 영향을 미친다.
만약 링크 순서가 꼬일 경우 아래와 같이 적용하면 된다.
## -Wl 대신 -Xlinker를 사용해도 된다
g++ main.o -Wl,--start-group {라이브러리 목록} -Wl,--end-group
## 또는 편법적인 방법이지만 두 번 작성해도 된다.
g++ main.o -lcommon -lutil -lmisc -lcommon -lutil -lmisc
Precompiled Headers
- 더 자세한 내용은 Precompiled Headers 항목 참조.
- [추천] Stackoverflow: GCC - Multiple precompiled headers and specific paths 2
미리 컴파일 된 헤더를 사용하면 컴파일 시간을 단축할 수 있다. PCH파일을 만드는 방법은 아래와 같이 헤더파일을 컴파일 하면 된다.
주의할 점은 -g
플래그를 사용하면 다른 소스파일을 컴파일 할 경우 동일하게 -g
플래그를 사용해야 하며, 사용하지 않을 경우도 동일하게 사용하면 안된다.
이 후, 파일명.h.gch파일이 생성되는데, PCH를 적용할 소스파일 상단에 헤더파일을 추가하면 된다. 자세한 내용은 https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html 에서 확인할 수 있다.
Command-line options
GCC에서 사용할 수 있는 중요한 명령줄(Command line) 옵션 정리.
Common options
-
-c
- 링크과정을 진행하지않고 컴파일까지만 진행한다.
오브젝트파일을 출력한다.
-
-o
<OUTPUT_PATH> - 출력파일을 지정한다.
-
-I
<INCLUDE_DIR> - 대문자 i이며 #include 헤더의 경로를 나타낸다.
-I
와 <INCLUDE_DIR>사이에 공백은 없으며 여러번 사용할 수 있다.
-
-l
<LIBRARY_NAME> - 소문자 L이며 링크(Link)할 라이브러리를 명시한다.
- 접두사
lib
과 접미사.a
(또는*.so
)를 제거한 라이브러리 이름을 적는다. -
-l
와 <INCLUDE_DIR>사이에 공백은 없으며 여러번 사용할 수 있다. (e.g.libmylib.a
를 링크하고싶을 경우-lmylib
라고 적으면 된다.) - 만약 라이브러리의 전체 경로를 입력하고 싶다면 Object(*.o)파일과 같이
-l
를 빼고 입력하면 된다.
-
-L
<LIBRARY_DIR> - 라이브러리를 모아놓은 경로를 명시한다.
-L
과 <LIBRARY_DIR>사이에 공백은 없으며 여러번 사용할 수 있다. (e.g.-L.
은 현재 디렉터리를 나타낸다.)
-
-p
- 프로그램을 prof로 프로파일링 할 수 있도록 링크한다.
-
-w
- 모든 경고 메시지 제거.
-
-W
- 합법적이지만 다소 모호한 코딩에 대하여 부가적인 경고 메시지 출력.
-
-Wall
- 모호한 코딩에 대하여 훨씬 더 자세한 경고 메시지 출력.
-
-Werror
- 모든 경고(Warning)를 오류(Error)로 취급한다. 즉, 한 개의 경고만 나와도 컴파일이 중단된다.
-
-Wtraditional
- 소스코드에 ANSI C와 K&R C 사이에 서로 다른 결과를 가져올 수 있다면 경고를 출력.
-
-Wno-psabi
-
note: the mangling of 'va_list' has changed in GCC 4.4
와 같은 메시지를 제거하고 싶을 경우 사용된다. - NOTE: 정확한 옵션정보는 알아봐야 한다.
-
-Wno-wchar-size-warning
-
ld.exe: warning: ~.o uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
와 같은 메시지를 제거하고 싶을 경우 사용된다. - NOTE: 정확한 옵션정보는 알아봐야 한다.
-
-static
- 정적 라이브러리로 컴파일한다.
-
-shared
- 가능한 공유라이브러리와 링크하고 공유라이브러리가 없을 경우 정적라이브러리와 링크한다.
-
-Wl,--subsystem,windows
- MINGW 커맨드라인 창과 윈도우창이 동시에 나타나지 않는다.
-
-mwindows
- MINGW의 WinMain을 진입점으로 설정한다. Linker 플래그로 설정하면 된다.
- See also: http://blog.jidolstar.com/677|http://blog.jidolstar.com/677
-
-M
- makefile을 위한 종속성(defendency) 리스트를 stdout으로 출력한다.
- 보통 리다이렉트를 이용한 *.d파일을 만들어 makefile에 사용된다. 자세한 내용은 종속물들을 자동으로 생성하기(Generating Dependencies Automatically)를 참조.
-
-MM
-
-M
과 동일하지만 시스템 헤더 파일들에 대해서는 종속물들을 생략하도록 한다.
-
-H
- 사용하고 있는 전체 헤더파일 목록을 스택(Stack)형식으로 출력한다.
-
-std=c++11
- https://gcc.gnu.org/onlinedocs/gcc/Standards.html
- https://gcc.gnu.org/projects/cxx0x.html
- 개정된 C++ 11 표준 (ISO/IEC 14882:2011)을 적용한다.
-
--diag_suppress
- http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348bk/CHDHFIAG.html
- 이 옵션은 지정된 태그가 있는 진단 메시지를 비활성화합니다.
-
--diag_suppress
옵션은 컴파일러에서 지정된 태그가 있는 진단 메시지를 오류 심각도로 설정하는 것이 아닌 해당 메시지를 표시하도록 하는 것을 제외하고--diag_errors
와 유사하게 동작합니다.
-
-save-temps
- Store the normally temporary intermediate files(.s, .i, *.o) permanently.
Code Generation Conventions
These machine-independent options control the interface conventions used in code generation.
Most of them have both positive and negative forms; the negative form of -ffoo
is -fno-foo
. In the table below, only one of the forms is listed—the one that is not the default. You can figure out the other form by either removing no-
or adding it.
-
-fstack-reuse=reuse-level
- This option controls stack space reuse for user declared local/auto variables and compiler generated temporaries.
-
-fdiagnostics-color=auto
- How to get color output from GCC
- 터미널 출력시 색상을 적용한다.
-
-fpermissive
- Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using
-fpermissive
will allow some nonconforming code to compile. 3 - gcc 4.1 버전부터 표준을 더 엄격하게 지키려고 하다보니 발생하는 문제로서 일종의 버그라고 봐도 무방하다. :문제가 되는 변수에
this->
와 같이 명시적으로 변수를 사용하거나, 표준 헤더파일을 먼저 찾을 수 있도록 적절한 헤더파일을 include해준다. (템플릿을 컴파일할 때는 로컬에서 먼저 찾는다고 한다.) 만약 컴파일러 옵션으로 해결하고 싶을 경우 사용하면 된다. - See also: http://wanochoi.com/?tag=fpermissive
-
-fPIC
- 크고 느린코드 생성. 플렛폼에 독립적. CPU에 관계없이 사용할 수 있다. 크기에 상관이 없는 대신 Global Offset Table(GOT)의 심볼 맥세스 속도저하가 크다. (그런데 i386에서는
-fPIC
나-fpic
나 비슷하다) - See also: Shared Library
- See also: shared library관련 기초적인 질문
- See also: http://lists.freebsd.org/pipermail/cvs-ports/2004-March/030214.html
-
-fpic
- 작고 빠른 코드 생성. CPU에 따라
-fpic
로 생성할 수 있는 GOT(Glocal Offset Table)의 크기에 제한이 있다. Global Offset Table(GOT)을 통해 심볼들을 액세스하는데 기계에 따라서 정해진 한계가 있어서 경우에 따라서는 실패할 수도 있다. 하지만 성공하면-fPIC
에 비해 더 적은 속도 저하를 얻을 수 있다. - See also: Shared Library
- See also: GCC 동적 라이브러리(.so) 만들기 및 -fPIC와 -fpic 차이점
-
-fvisibility=hidden
- glibc - ELF symbol visibility
- #Symbol Visibility 항목 참조.
- ELF의 symbol visibility 속성을 변경한다.
-
-finput-charset=
- Character sets - The C Preprocessor
- Stackoverflow - How should I use g++'s -finput-charset compiler option correctly in order to compile a non-UTF-8 source file?
- INPUT 소스코드의 문자열셋을 지정한다. utf8지정시
-finput-charset=UTF-8
로 적용하면 된다.
-
-fmessage-length=n
- 메시지를 출력할 경우 한 라인에 들어갈 문자의 길이를 n의 값으로 설정한다. 0으로 설정할 경우 전체 메시지를 출력한다. (Try to format error messages so that they fit on lines of about n characters. default is 72)
-
-fdata-sections
,-ffunction-sections
- Stackoverflow - How to remove unused C/C++ symbols with GCC and ld?
GCC Optimization
어떤 CPU를 쓰는지 모르겠거나 어떤 설정을 선택해야 할지 모르겠다면, 아마 그냥 -march=native
설정을 사용할 수 있습니다. 이 플래그를 사용하면 GCC는 프로세서를 감지하고 자동으로 적당한 플래그를 설정합니다.
WARNING |
다른 CPU에서 사용할 패키지를 컴파일하려 한다면 |
CPU 특수화 플래그
CPU별 --extra-cflags
추가 플래그.
- ARM v6
-
-marm -march=armv6
- ARM v7vfpv3
-
-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a
- ARM v7vfp
-
-mfloat-abi=softfp -mfpu=vfp -marm -march=armv7-a
- ARM v7n
-
-mfloat-abi=softfp -mfpu=neon -marm -march=armv7-a -mtune=cortex-a8
- ARM v6+vfp
-
-DCMP_HAVE_VFP -mfloat-abi=softfp -mfpu=vfp -marm -march=armv6
Position Independent Code
- 플밍노트 PIC 옵션의 정체
- Stackoverflow - Is there a way to determine that a .a or .so library has been compiled as position indepenent code?
- [추천] Position Independent Code (PIC) in shared libraries 6
- 공유 라이브러리에 PIC를 사용하는 이유 7
Include directory list
INCLUDE 디렉토리 목록은 아래와 같이 확인할 수 있다.
# C
$ echo | gcc -Wp,-v -x c - -fsyntax-only 2>&1
# C++
$ echo | gcc -Wp,-v -x c++ - -fsyntax-only 2>&1
# more information
$ echo | gcc -E -v -x c++ -
# /dev/null use version:
$ g++ -E -x c++ - -v < /dev/null
# Or in Windows Command Prompt:
$ g++ -E -x c++ - -v < nul
# Clang version:
$ clang++ -E -x c++ - -v < /dev/null
참고로 기본 디렉터리 목록은 아래와 같다.
-
/usr/local/include
-
libdir/gcc/target/version/include
-
/usr/target/include
-
/usr/include
Include file list
-M
옵션 등을 사용하여 dependency 목록을 확인할 경우 아래와 같은 명령으로 리스트를 출력할 수 있다.
Include order
우선 헤더 폴더를 지정하는 방법은 아래와 같다.
-
-I dir
-
-iquote dir
-
-isystem dir
-
-idirafter dir
You can specify any number or combination of these options on the command line to search for header files in several directories. The lookup order is as follows:
- For the quote form of the include directive, the directory of the current file is searched first.
- For the quote form of the include directive, the directories specified by -iquote options are searched in left-to-right order, as they appear on the command line.
- Directories specified with -I options are scanned in left-to-right order.
- Directories specified with -isystem options are scanned in left-to-right order.
- Standard system directories are scanned.
- Directories specified with -idirafter options are scanned in left-to-right order.
Dump preprocessor defines
Yes, use -E -dM
options instead of -c
. Example (outputs them to stdout):
For C++
From the gcc manual:
Instead of the normal output, generate a list of `#define' directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor. Assuming you have no file foo.h, the command
will show all the predefined macros.
If you use -dM
without the -E
option, -dM
is interpreted as a synonym for -fdump-rtl-mach
.
sysroot isysroot isystem
-sysroot
는 표준 C 라이브러리의 헤더 파일과 라이브러리의 위치를 변경할 때 사용한다. 크로스 컴파일을 할 때 보통 사용한다.
-sysroot=/mips-root
라면 /mips-root/usr/include
, /mips-root/usr/lib
에서 헤더 파일과 라이브러리를 찾게 된다.
-isysroot
는 라이브러리와 별도로 헤더 파일만 따로 지정하고자 할 때 사용한다. 이 옵션이 없는 경우에는 -sysroot
를 따르게 된다.
표준 C 라이브러리 헤더 파일 이외에도 /usr/include
에는 많은 다른 라이브러리의 헤더 파일이 존재한다. 크로스 컴파일을 하는 경우에는 관련 라이브러리 헤더 파일을 한 곳에 모아 두면 편하게 되는데 위의 mips-root/usr/include
에 추가해도 되지만 섞이는 것을 원치 않는 경우라면 -isystem
옵션을 이용해서 추가로 다른 디렉토리를 지정하면 된다.
헤더 파일을 찾는 우선 순위는 다음과 같다.
-
-I
-
-isystem
-
-sysroot
or-isysroot
Disable GCC warnings for a few lines of code
코드상에서 GCC의 Warning을 제거하는 방법은 아래와 같다.
#if defined(__GNUC__) && defined(__cplusplus)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Winline"
#endif
#include <boost/log/trivial.hpp>
#if defined(__GNUC__) && defined(__cplusplus)
# pragma GCC diagnostic pop
#endif
Symbol Visibility
- Visibility - GCC Wiki - Why is the new C++ visibility support so useful?
- GCC Symbol Visibility Patch
- ned Productions – GCC Symbol Visibility Patch
- (glibc) ELF symbol visibility
GCC 4.0부터 포함되어 있는 GCC Symbol Visibility Patch는 GCC 컴파일러를 조금 더 유용하게 만들어 준다. 홈페이지에서 언급한 이 기능의 장점은 다음과 같다.
- 공유 라이브러리와 같은 DSO(Dynamic Shared Object, 동적 공유 객체)를 로드하는데 걸리는 시간을 획기적으로 향상시켜준다.
- 컴파일러 최적화기(optimiser)가 더 좋은 코드를 만들수 있다.
- DSO 크기를 5~20% 정도 줄여준다.
- 심볼(symbol)이 충돌할 기회를 낮춰준다.
visibility 속성은 다음과 같은 4가지 중의 하나로 설정할 수 있다.
- default: 기본값이다. visibility는 고려하지 않고 해당 심볼(의 바인딩)이 global인지 static(local)인지 만을 이용한다.
- hidden: 주로 사용되는 속성이다. 해당 심볼을 외부로 공개하지 않게 만든다.
- protected: 잘 사용되지 않는다. 해당 심볼은 공개하지만 다른 모듈에 의해 대체되지 않는다.
- internal: 잘 사용되지 않는다. 해당 심볼을 공개하지 않으며 각 아키텍처 별로 약간씩 다른 효과를 가질 수 있다.
Exclude unused symbols
- Stackoverflow - When and why would the C linker exclude unused symbols?
- Stackoverflow - How to remove unused C/C++ symbols with GCC and ld?
For GCC, this is accomplished in two stages:
First compile the data but tell the compiler to separate the code into separate sections within the translation unit. This will be done for functions, classes, and external variables by using the following two compiler flags:
Link the translation units together using the linker optimization flag (this causes the linker to discard unreferenced sections):
So if you had one file called test.cpp that had two functions declared in it, but one of them was unused, you could omit the unused one with the following command to gcc(g++):
(Note that -Os
is an additional compiler flag that tells GCC to optimize for size)
Tip
With mingw this does not work when linking statically statically libstdc++ and libgcc with the flag -static
. The linker option -strip-all
helps quite a bit, but still the generated executable (or dll) is about 4 way bigger than what Visual Studio would generate. Point is, I have no control on how libstdc++ was compiled. There should be a ld only option.
Exclude Functions
-finstrument-functions-exclude-file-list=file,file,...
옵션 또는 -finstrument-functions-exclude-function-list=sym,sym,...
옵션 참조.
... 결국 strip을 사용했다:
Whole archive
- MSVC:
link.exe
의/WHOLEARCHIVE:libA
와 같이 사용하면 된다. - Clang:
-Wl,-force_load,libfoobar.a
를 사용하거나-Wl,-all_load
를 사용하면 된다. - GCC:
-Wl,--whole-archive
와-Wl,--no-whole-archive
플래그 사이에 추가하면 된다.
컴파일 과정
GCC 는 사실 컴파일러 자체를 말하는 것은 아니고, 컴파일 과정에 필요한 여러가지 기능들을 호출하는 역할을 합니다. 따라서 gcc 는 c 언어 뿐만 아니라 다른 언어들도 컴파일이 가능 합니다. 일련의 과정에 다른 언어를 컴파일하는 녀석들을 호출만 해주면 되기 때문입니다.
컴파일 과정 요약
- 전처리 과정
- 어셈블리 소스파일로 컴파일과정
- 인스트럭션 코드 생성 과정
- 링크 과정
전처리 ( ccp0 )
소스파일에 포함된 (#include) 파일들을 불러와 현재컴파일할 파일에 복사해서 붙여 넣는다. (결과물: test.i)
어셈블리 코드로 컴파일 (cc1)
실제 컴파일러라 할 수 있다. 어휘분석 -> 구문분석 -> 의미분석 -> 중간언어생성 -> 코드최적화 -> 목적코드생성 의 과정을 거친다.
- 어휘 분석: 전처리 과정에서 생성된 test.i 파일을 문법적 의미가 있는 최소 단위 (토큰) 로 나눈다.
- 구문 분석: 문법석 오류가 있는지 검사 한 후 파서트리를 만든다.
- 의미 분석: 문법상 문제가 아닌 의미상 문제, 즉 선언되지 않은 변수의 사용이나 자료형 불일치, 함수 인자개수 등의 문제를 검사 한다.
- 중간언어 생성: 어셈블리 코드로 만들기 전에 최적화를 위해 RTL(Register Transfer Language) 라는 lips 언어와 유사한 코드로 생성한다. (결과물 : test.rtl)
- 코드 최적화: 코드의 사이즈를 줄이고, 속도를 높이기 위해 최적화를 진행 한다. gcc 컴파일의 대부분의 시간이 소요되며 아래 두단계를 거친다.
- 중간코드 최적화
- 지역 최적화 : 연산강도 경감, 상수계산등의 최적화
- 전역 최적화 : 사용되지 않는 코드제거
- 루프 최적화 : 사용하지 않는 루프제거, 루프결합
- 중간코드 최적화
- 최대한 메모리보다 레지스트를 사용하게 하고, 효율적인 인스트럭션을 선택하여 메모리 접근을 최적화 한다.
기계어 코드 생성 (as)
.s 인 어셈블리 코드를 .o 인 오브젝트 파일로 바꾼다. 생성된 오브젝트 파일은 ELF(Executable and Linking) 바이너리 파일 구조 규약을 따르며, 이유는 여러 오브젝트 파일을 링크 할 때 파일의 구조가 다르다면 불가능 하기 때문임. 바이너리 포멧은 a.out / ELF / COFF 등이 유닉스 시스템 에서 쓰였으며, 현재는 ELF 가 대부분 사용된다. 윈도우 시스템 에서는 COFF , PE 가 쓰인다.
- ELF 파일 구조는 맨위에 ELF 파일헤더, 프로그램 헤더 Table, 섹선1 ~ n , 섹션 헤더 테이블로 구된다.
- ELF 파일 헤더를 제외하고 나머지는 컴파일된 파일 마다 다를 수 있으며, 인스트럭션과 데이터, GCC컴파일러 버전 등이 기록 된다.
링크 (collect2)
여러개의 오브젝트 파일을 하나로 링크하는 과정이며, 주로 라이브러리의 링크가 이루어 진다.
- 정적 라이브러리 : 링크시에 라이브러리를 포함해서 실행 파일을 만든다. 따라서 다른 프로그램에서도 같은 라이브러리를 사용 한다면, 중복되기 때문에 용량을 많이 차지 하게 되지만, 링크가 완료된 상태이므로 속도는 빠르다.
- 동적 라이브러리(공유 라이브러리) : 링크시 라이브러리의 포함 여부만 기록하고, 실제 동작할 때 메모리에 라이브러리를 로드하여 사용한다. 다른 프로그램에서 같은 라이브러리를 사용 할 경우 메모리에 이미 로드된 것을 사용 하므로, 공유 한다는 의미에서 공유 라이브러리 라고도 한다. 따라서 단 한개의 프로그램이라도 이 라이브러리를 사용 하고 있으면, 메모리에 상주 하며, 아무 프로그램도 사용 하지 않는다면, 메모리에서 제거 된다. 실행시 로드되므로 속도는 다소 느릴 수 있으나 중복로드 되지 않아 메모리 사용이 효율 적이다. (결과물 : 실행 파일).
흔한 컴파일러 오해들
Compiler#흔한 컴파일러 오해들 항목 참조.
디버깅 심볼
- Stackoverflow - Is a program compiled with -g gcc flag slower than the same program compiled without -g?
- Stackoverflow - gcc -g0 and without the -g option
-g
를 명령행에 사용하면 디버깅 심볼을 추가한다. objdump로 해당 섹션을 확인할 수 있다.
다음과 같이 확인한 수 있다.
다음과 같은 내용이 포함된다.
25 .debug_aranges 00000030 0000000000000000 0000000000000000 00003042 2**0
26 .debug_info 000000c4 0000000000000000 0000000000000000 00003072 2**0
27 .debug_abbrev 00000071 0000000000000000 0000000000000000 00003136 2**0
28 .debug_line 0000004c 0000000000000000 0000000000000000 000031a7 2**0
29 .debug_str 0000009f 0000000000000000 0000000000000000 000031f3 2**0
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
-
-g0
를 사용하면 디버깅 심볼을 넣지 않는다.-g
를 명령행에 추가하지 않는 것과 동일하다. - 만약
-g0
옵션과-g
옵션을 함께 사용하면 명령행 기준, 가장 마지막에 입력한 옵션이 적용된다.
디버그 심볼과 타겟 분리
You need to use objcopy to separate the debug information:
objcopy --only-keep-debug "${tostripfile}" "${debugdir}/${debugfile}"
strip --strip-debug --strip-unneeded "${tostripfile}"
objcopy --add-gnu-debuglink="${debugdir}/${debugfile}" "${tostripfile}"
I use the bash script below to separate the debug information into files with a .debug extension in a .debug directory. This way I can tar the libraries and executables in one tar file and the .debug directories in another. If I want to add the debug info later on I simply extract the debug tar file and voila I have symbolic debug information.
This is the bash script:
#!/bin/bash
scriptdir=`dirname ${0}`
scriptdir=`(cd ${scriptdir}; pwd)`
scriptname=`basename ${0}`
set -e
function errorexit()
{
errorcode=${1}
shift
echo $@
exit ${errorcode}
}
function usage()
{
echo "USAGE ${scriptname} <tostrip>"
}
tostripdir=`dirname "$1"`
tostripfile=`basename "$1"`
if [ -z ${tostripfile} ] ; then
usage
errorexit 0 "tostrip must be specified"
fi
cd "${tostripdir}"
debugdir=.debug
debugfile="${tostripfile}.debug"
if [ ! -d "${debugdir}" ] ; then
echo "creating dir ${tostripdir}/${debugdir}"
mkdir -p "${debugdir}"
fi
echo "stripping ${tostripfile}, putting debug info into ${debugfile}"
objcopy --only-keep-debug "${tostripfile}" "${debugdir}/${debugfile}"
strip --strip-debug --strip-unneeded "${tostripfile}"
objcopy --add-gnu-debuglink="${debugdir}/${debugfile}" "${tostripfile}"
chmod -x "${debugdir}/${debugfile}"
License
GCC Runtime Library Exception
- What libraries does the GCC Runtime Library Exception cover?
- The GCC Runtime Library Exception covers any file that has a notice in its license headers stating that the exception applies. This includes libgcc, libstdc++, libfortran, libgomp, libdecnumber, libgcov, and other libraries distributed with GCC.
Troubleshooting
GCC사용과 관련된 문제점에 대하여 정리한다.
ISO C90 forbids mixed declarations and code
위와 같은 경고 메시지가 출력된다면 변수 선언을 함수 시작 부분으로 옮겨보자.
STD C++11 error
thread 등을 사용할 경우 아래와 같은 에러를 뱉으며 컴파일 조차 안되는 현상이 있을 수 있다.
In file included from test.cpp:1:0:
C:/root/msys/tdmgcc/lib/gcc/mingw32/4.9.2/include/c++/thread: In function 'bool std::operator<(std::thread::id, std::thread::id)':
C:/root/msys/tdmgcc/lib/gcc/mingw32/4.9.2/include/c++/thread:88:30: error: no match for 'operator<' (operand types are 'std::thread::native_handle_type {aka ptw32_handle_t}' and 'std::thread::native_handle_type {aka ptw32_handle_t}')
{ return __x._M_thread < __y._M_thread; }
이 경우 910 CPLUS_INCLUDE_PATH
환경변수를 확인하고 만약 설정되어 있다면 제거하자.
결국 이 INCLUDE PATH관련 문제가 아니라 pthread win32의 pthread.h
와 c++11의 thread가 내부적으로 사용하는 mingw/include/pathread.h
가 충돌나는 문제였다.
_stricmp c++11 not existent
c++11에서 _stricmp
, _strdup
, _fileno
등의 심볼을 찾을 수 없다. 그 답변은 아래와 같다.
The -std=c++0x option causes g++ to go into 'strict ANSI' mode so it doesn't declare non-standard functions (and _stricmp() is non-standard - it's just a version of strcmp() that's case-insensitive).
Use -std=gnu++0x instead.
LIBRARY_PATH variable error
GCC 소스코드를 사용하여 직접 설치할 경우 make단계에서 아래와 같은 에러가 발생될 수 있다.
checking LIBRARY_PATH variable... contains current directory
configure: error:
*** LIBRARY_PATH shouldn't contain the current directory when
*** building gcc. Please change the environment variable
*** and run configure again.
Apparently, your LIBRARY_PATH ends in a colon:
Get rid of that:
cannot open shared object file
GLIBCXX not found
컴파일 완료 후, 실행파일을 실행할 경우 아래와 같은 에러 메시지가 출력될 수 있다.
이 경우 Linker 옵션에 -static-libstdc++
를 사용하면 해결될 수 있다.
만약 위와 같이 수정해도 해결되지 않는다면 LD_LIBRARY_PATH
환경변수를 확인해보자. 64bit의 경우 /usr/local/lib64
와 같은 경로가 추가돼있지 않는 경우가 있다.
Undefined reference to ~
라이브러리 링크시 undefined reference to ~
와 같은 메시지가 발생하며 정상적으로 링크되지 않는 현상이 발생할 경우 -l
옵션으로 시작하는 라이브러리의 command-line 위치를 바꿔보면 해결될 수 있다. 예를 들면 g++ -L. -ltest main.o
과 같이 컴파일 할 경우 g++ -L. main.o -ltest
와 같이 변경해보면 정상적으로 컴파일될 가능성이 있다.
DSO missing from command line
DSO here means Dynamic Shared Object; since the error message says it's missing from the command line, I guess you have to add it to the command line.
virtual-move-assign
C++:Inheritance#virtual-move-assign문서를 참조.
warning: direct access in function
아래와 같은 경고가 발생될 수 있다.
ld: warning: direct access in function 'std::__1::basic_filebuf<char, std::__1::char_traits<char> >::open(char const*, unsigned int)' from file '/Path/To/Derived/Data/Xcode/DerivedData/myapp/Build/Intermediates/myapp.build/Debug-iphoneos/myapp.build/Objects-normal/arm64/myapp_lto.o' to global weak symbol 'std::__1::basic_filebuf<char, std::__1::char_traits<char> >::open(char const*, unsigned int)' from file '/Path/To/Derived/Data/Xcode/DerivedData/myapp/Build/Intermediates/myapp.build/Debug-iphoneos/myapp.build/Objects-normal/arm64/myapp_lto.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
컴파일 시 -fvisibility=hidden
을 사용하면 된다.
See also
Favorite site
- GCC web site
- Wikipedia (en) GCC에 대한 간략한 설명
- GCC library 의 사용.
- 리눅스 GCC컴파일러.
- Naver blog: GCC 컴파일 과정, 옵션 (ko) 13
- 리눅스 컴파일 과정과 GCC옵션, 그리고 라이브러리 만들기 14
- The GNU C Library Reference Manual (ko)
- [추천]15 GCC and Make Compiling, Linking and Building C/C++ Applications 16
- so 파일 생성방법 17
- [추천] GCC 옵션정복 18
- [추천] gcc 컴파일 옵션 (한글)
GCC Online documentation
References
-
MinGW_Static_and_Dynamic_Libraries_-_CodeProject.pdf ↩
-
GCC_-Multiple_precompiled_headers_and_specific_paths-_Stack_Overflow.pdf ↩
-
http://stackoverflow.com/questions/8843818/what-does-the-fpermissive-flag-do ↩
-
GCC_optimization_-_Gentoo_Wiki.pdf ↩
-
Gcc-march_options.pdf ↩
-
Position_Independent_Code_-PIC-in_shared_libraries-_Eli_Benderskys_website.pdf ↩
-
Pic_option_for_shared_library.pdf ↩
-
GCC_Warning_Error_List-kor.pdf ↩
-
Linux_-_No_such_so_file.pdf ↩
-
Cannot_open_shared_object_file_-_Litcoder.pdf ↩
-
Naver_blog_GCC_Compile_process_and_commandline_options.pdf ↩
-
GCC_Options_and_how_to_create_library.pdf ↩
-
GCC 컴파일 과정과 생성되는 파일을 볼 수 있다. ↩
-
GCC_and_Make_-_A_Tutorial_on_how_to_compile,_link_and_build_C_C++_applications.pdf ↩
-
Create_so_file.pdf ↩
-
Gcc_options.pdf ↩
-
Gcc.4.7.2.zip ↩