Skip to content

Commit

Permalink
feat: Remove unused data and function for AppleClang
Browse files Browse the repository at this point in the history
  • Loading branch information
zchrissirhcz committed Nov 24, 2024
1 parent 9cccc2e commit 2e2d919
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
16 changes: 16 additions & 0 deletions rocbuild.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,21 @@ function(rocbuild_link_as_needed TARGET)
endfunction()


function(rocbuild_remove_unused_data_and_function TARGET)
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR "$<CONFIG:Release>")
if((CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang)$") OR
(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang)$"))
target_compile_options(${TARGET} PRIVATE "-fdata-sections" "-ffunction-sections")
target_link_options(${TARGET} PRIVATE "LINKER:--gc-sections")
elseif((CMAKE_C_COMPILER_ID STREQUAL "AppleClang") OR
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))
target_compile_options(${TARGET} PRIVATE "-fdata-sections" "-ffunction-sections")
target_link_options(${TARGET} PRIVATE "LINKER:-dead_strip")
#target_link_options(${TARGET} PRIVATE "LINKER:-s,-S")
endif()
endif()
endfunction()


rocbuild_set_artifacts_path()
rocbuild_enable_ninja_colorful_output()
30 changes: 26 additions & 4 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ def test_link_as_needed(self):
self.check_build('link_as_needed')
cmd = 'ldd build/link_as_needed/libfoo_math.so'
ret, out = check_output(cmd)
print(out)
self.assertEqual(0, ret, out)
self.assertIn('libfoo.so =>', out)
shutil.rmtree('build/link_as_needed')
Expand All @@ -237,7 +236,6 @@ def test_link_as_needed(self):
self.check_build('link_as_needed')
cmd = 'ldd build/link_as_needed/libfoo_math.so'
ret, out = check_output(cmd)
print(out)
self.assertEqual(0, ret, out)
self.assertTrue('libfoo.so =>' not in out)
shutil.rmtree('build/link_as_needed')
Expand All @@ -246,7 +244,6 @@ def test_link_as_needed(self):
self.check_build('link_as_needed')
cmd = 'otool -L build/link_as_needed/libfoo_math.dylib'
ret, out = check_output(cmd)
print(out)
self.assertEqual(0, ret, out)
self.assertIn('@rpath/libfoo.dylib', out)
shutil.rmtree('build/link_as_needed')
Expand All @@ -255,10 +252,35 @@ def test_link_as_needed(self):
self.check_build('link_as_needed')
cmd = 'otool -L build/link_as_needed/libfoo_math.dylib'
ret, out = check_output(cmd)
print(out)
self.assertEqual(0, ret, out)
self.assertTrue('@rpath/libfoo.dylib' not in out)
shutil.rmtree('build/link_as_needed')

def test_unused_data_and_function(self):
if os_name == 'mac':
self.check_generate('unused_data_and_function', args='-DCMAKE_BUILD_TYPE=Release REMOVE_UNUSED_DATA_AND_FUNCTION=0')
self.check_build('unused_data_and_function')
cmd = 'objdump -t build/unused_data_and_function/test'
ret, out = check_output(cmd)
self.assertEqual(0, ret, out)
out = out.replace('\r\n', '\n')
lines = out.strip().split('\n')
self.assertEqual(len(lines), 11, lines)
self.assertTrue(lines[5].endswith('g F __TEXT,__text _unused_function'))
self.assertTrue(lines[6].endswith('g O __DATA,__data _unused_global_variable'))
shutil.rmtree('build/unused_data_and_function')

self.check_generate('unused_data_and_function', args='-DCMAKE_BUILD_TYPE=Release -DREMOVE_UNUSED_DATA_AND_FUNCTION=1')
self.check_build('unused_data_and_function')
cmd = 'objdump -t build/unused_data_and_function/test'
ret, out = check_output(cmd)
self.assertEqual(0, ret, out)
out = out.replace('\r\n', '\n')
lines = out.strip().split('\n')
self.assertEqual(len(lines), 9, lines)
for line in lines:
self.assertTrue(not line.endswith('unused_function'))
shutil.rmtree('build/unused_data_and_function')

if __name__ == "__main__":
unittest.main()
8 changes: 8 additions & 0 deletions tests/unused_data_and_function/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.10)
project(test_artifacts_path)
include(../../rocbuild.cmake)

add_executable(test test.c)
if(REMOVE_UNUSED_DATA_AND_FUNCTION)
rocbuild_remove_unused_data_and_function(test)
endif()
24 changes: 24 additions & 0 deletions tests/unused_data_and_function/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdio.h>

// Unused function (should be removed)
void unused_function() {
printf("This function is not used.\n");
}

// Used function (should be kept)
void used_function() {
printf("This function is used.\n");
}

// Unused global variable (should be removed)
int unused_global_variable = 42;

// Used global variable (should be kept)
int used_global_variable = 100;

int main() {
void (*volatile func_ptr)() = used_function;
func_ptr();
printf("Used global variable: %d\n", used_global_variable);
return 0;
}

0 comments on commit 2e2d919

Please sign in to comment.