GCC 및 ld로 사용하지 않는 C / C ++ 기호를 제거하는 방법은 무엇입니까?
내 실행 파일의 크기를 심각하게 최적화 ( ARM
개발)해야하는데 현재 빌드 체계 ( gcc
+를 ld
) 사용하지 않는에서 기호가 제거되지 않는다는 것을 알았습니다 .
arm-strip --strip-unneeded
결과 실행 파일 / 라이브러리에 대한 의 사용은 실행 파일의 출력 크기를 변경하지 않습니다 (이유를 모르겠습니다 . 불가능할 수도 있습니다) .
건물 파이프 라인을 수정하여 파일에서 사용하지 않는 기호를 제거 하는 방법 (존재하는 경우) 은 무엇입니까?
난이 생각하지,하지만 내 현재의 활동 환경은 매우 "강력한"심지어는 저장되지 않는 외 견적 작업 500K
의 2M
아주 좋은로드 성능 향상의 결과입니다.
최신 정보 :
불행하게도 현재 gcc
버전 I의 사용은하지 않는 -dead-strip
옵션과 -ffunction-sections... + --gc-sections
에 대한 ld
결과 출력을위한 의미있는 차이를 제공하지 않습니다.
gcc + ld
사용하지 않는 기호를 자동으로 사용하지 않는 확신이 들었 기 때문에 확실하게 확신이 사실에 충격을받을 것 입니다.
GCC의 경우 다음 두 단계로 수행됩니다.
먼저 데이터를 준비하되 번역 단위로 내에서 코드를 별도의 섹션으로 분리하여 컴파일러에 지시하십시오. 이 작업은 다음 두 컴파일러 플래그를 사용하여 함수, 클래스 및 외부 변수에 대해 수행합니다.
-fdata-sections -ffunction-sections
링커 최적화 플래그를 사용하여 번역 단위를 함께 연결합니다. 이렇게하면 링커가 참조되지 않은 섹션을 삭제합니다.
-Wl,--gc-sections
따라서 두 개의 개의 함수가 선언 된 test.cpp라는 파일이 하나 있는데 그중 하나가 사용되지 않는 경우 gcc (g ++)에 다음 명령을 사용할 수 있습니다.
gcc -Os -fdata-sections -ffunction-sections test.cpp -o test -Wl,--gc-sections
(-Os는 GCC에 크기 최적화를 지시하는 추가 컴파일러 플래그입니다.)
경우 이 스레드가 믿을 수있다,은 제공해야 우리 당신 -ffunction-sections
하고-fdata-sections
자신의 섹션에서 각 기능 현관 및 데이터 object-를 넣어을 구석으로입니다 GCC에. 그런 다음 사용하지 않는 섹션을 제거하기 위해 및 GNU ld를 제공 합니다.--gc-sections
gcc 및 ld의 버전에 대한 문서를 확인하고 싶을 것입니다.
그러나 나를 위해 (OS X gcc 4.0.1) ld
-dead_strip
진입 점 또는 내 보낸 기호로 도달 할 수없는 함수 및 데이터를 제거합니다.
-dead_strip_dylibs
진입 점 또는 내에서 발송 된 기호로 수없는 dylib를 제거합니다. 즉, 링크 생성 중에 기호를 제공하지 않는 dylibs에 대한 명령 명령을 제한합니다. 이 옵션은 dylib에 중요한 이니셜 라이저가있는 것과 같은 간접적 인 실행 운영에 필요한 dylib에 링크 할 때 사용하는 것입니다.
그리고이 유용한 옵션
-why_live symbol_name
symbol_name에 대한 참조 체인을 기록합니다. 에만 적용 가능합니다
-dead_strip
. 데드 항목을 제거해야 할 것이 생각하는 것이 제거되지 않은 이유를 수행하는 데 도움이 될 수 있습니다.
gcc / g ++ man에는 특정 종류의 데드 코드 제거가 수행되는 경우에만 활성화가 활성화됩니다.
/ 조건은 컴파일러에 맞지 않는 것이 좋습니다.
프로그래밍 습관도 도움이 될 수 있습니다. 예 : static
특정 파일 외부에서 액세스하지 않는 기능에 추가 ; 기호에 대해 더 짧은 이름을 사용하십시오 (너무 많이는 약간 도움이 될 수 있음). const char x[]
가능한 경우 사용 합니다. ... 이 문서 는 동적 공유 객체에 대해 이야기하지만, 따라갈 최종 바이너리 출력 크기를 더 작게 만드는 데 도움이 될 수있는 제안을 포함합니다 (목표가 ELF 인 경우).
대답은 -flto
입니다. 전달 및 링크 단계 모두에 전달해야합니다. 아무 작업도 수행하지 않습니다.
실제로 매우 잘 작동합니다. 내가 지금 마이크로 컨트롤러 프로그램의 크기를 이전 크기의 50 % 미만으로 줄였습니다!
불행히도 약간 버그가있는 것처럼 보였습니다. 제대로 빌드되지 않은 인스턴스가 있습니다. 내가 사용하고있는 빌드 시스템 (QBS; 아주 새로운 것) 빌드 일 수 있고, 어쨌든 가능하면 최종 빌드 활성화하고 해당 빌드를 철저히 테스트하는 것이 좋습니다.
하게 기호에 엄격 관한 [해석] 아니지만 크기를 고려한다면 항상 -Os
및 -s
플래그로 컴파일하십시오 . -Os
최소 실행 가능 크기에 대한 결과 코드를 최적화하고 실행 파일 -s
에서 기호 테이블 및 재배치 정보를 제거합니다.
거기에-작은 크기를 원할 경우-다른 최적화 플래그를 가지고 있습니다. 예를 들어 토글 -ffast-math
및 / 또는 사용 -fomit-frame-pointer
가능합니다.
Nemo가 제공하는 대답이 올바른 것입니다. 지침이 작동 이러한하지 않으면 여기에 설명 된 지침을 사용하여 예제 프로그램을 컴파일 한 실습으로 사용중인 GCC / LD과 관련된 문제 버전 일 수 있습니다.
#include <stdio.h>
void deadcode() { printf("This is d dead codez\n"); }
int main(void) { printf("This is main\n"); return 0 ; }
그런 다음 점진적으로 더 공격적인 데드 코드 제거 스위치를 사용하여 코드를 획득했습니다.
gcc -Os test.c -o test.elf
gcc -Os -fdata-sections -ffunction-sections test.c -o test.elf -Wl,--gc-sections
gcc -Os -fdata-sections -ffunction-sections test.c -o test.elf -Wl,--gc-sections -Wl,--strip-all
큰 우선 및 연결 매개 변수는 각각 8457, 8164 및 6160 바이트 크기의 실행 파일을 사용, 가장 기여는 'strip-all'선언에서 비롯되었습니다. 플랫폼에서 추천 감소를 생성 할 수없는 경우 gcc 버전이 기능을 지원하지 않습니다. Linux Mint 2.6.38-8-generic x86_64에서 gcc (4.5.2-8ubuntu4), ld (2.21.0.20110327)를 사용하고 있습니다.
strip --strip-unneeded
실행 파일의 기호 테이블은 작동합니다. 실제로 실행 가능한 코드를 제거하기.
표준 라이브러리는 모든 함수를 별도의 개체 파일로 분할하여 ar
. 그런 다음 결과 아카이브를 라이브러리로 연결하면 (즉, -l your_library
ld에 옵션 을 제공합니다 ) ld는 실제로 사용되는 개체 파일과 기호 만 포함합니다.
이것이 최근 기능이기 때문에 이것이 현재의 곤경에 도움이 될지 모르겠지만 전역 방식으로 기호의 가시성을 지정할 수 있습니다. -fvisibility=hidden -fvisibility-inlines-hidden
컴파일시 전달 하면 링커가 나중에 불필요한 기호를 제거하는 데 도움이 될 수 있습니다. 실행 파일을 생성하는 경우 (공유 라이브러리가 아닌) 더 이상 할 일이 없습니다.
자세한 정보 (예 : 라이브러리에 대한 세분화 된 접근 방식)는 GCC 위키 에서 확인할 수 있습니다 .
GCC 4.2.1 매뉴얼에서 섹션 -fwhole-program
:
현재 컴파일 단위가 컴파일중인 전체 프로그램을 나타낸다고 가정합니다.
main
속성에 의해 병합 된 것을 제외한 모든 공용 함수 및 변수는externally_visible
정적 함수가되고 영향을받는 경우 프로 시저 간 최적화 프로그램에 의해보다 적극적으로 최적화됩니다. 이 옵션은static
단일 파일로 구성된 프로그램에 대한 키워드의 적절한 사용과 동일하지만 ,--combine
이 플래그 를 옵션과 함께 사용하면 함수와 변수가 결합 된 전체 컴파일 단위에 대해 로컬이되기 때문에 대부분의 소규모 C 프로그램을 컴파일하는 데 사용할 수 있습니다. 단일 소스 파일 자체.
개체 파일 (예 : 실행 파일)에 스트립 바이너리를 사용하여 모든 기호를 제거 할 수 있습니다.
참고 : 파일 자체를 변경하고 복사본을 만들지 않습니다.
참고 URL : https://stackoverflow.com/questions/6687630/how-to-remove-unused-cc-symbols-with-gcc-and-ld
'IT' 카테고리의 다른 글
JWT 토큰의 서버 측 처리를위한 모범 사례 (0) | 2020.08.15 |
---|---|
C #의 'yield'키워드에 해당하는 Java가 있습니까? (0) | 2020.08.15 |
Rails 및 HTTParty를 사용하여 API에 JSON 게시 (0) | 2020.08.14 |
LastPass가 양식 작성 중지 (0) | 2020.08.14 |
ES6는 배열을 매핑하여 새 키가있는 배열을 반환합니다. (0) | 2020.08.14 |