IT

GCC 및 ld로 ​​사용하지 않는 C / C ++ 기호를 제거하는 방법은 무엇입니까?

lottoking 2020. 8. 14. 08:03
반응형

GCC 및 ld로 ​​사용하지 않는 C / C ++ 기호를 제거하는 방법은 무엇입니까?


내 실행 파일의 크기를 심각하게 최적화 ( ARM개발)해야하는데 현재 빌드 체계 ( gcc+를 ld) 사용하지 않는에서 기호가 제거되지 않는다는 것을 알았습니다 .

arm-strip --strip-unneeded결과 실행 파일 / 라이브러리에 대한 의 사용은 실행 파일의 출력 크기를 변경하지 않습니다 (이유를 모르겠습니다 . 불가능할 수도 있습니다) .

건물 파이프 라인을 수정하여 파일에서 사용하지 않는 기호를 제거 하는 방법 (존재하는 경우) 은 무엇입니까?


난이 생각하지,하지만 내 현재의 활동 환경은 매우 "강력한"심지어는 저장되지 않는 외 견적 작업 500K2M아주 좋은로드 성능 향상의 결과입니다.

최신 정보 :

불행하게도 현재 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_libraryld에 옵션 제공합니다 ) 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

반응형