@@ -911,6 +911,26 @@ if(STATIC_BUILD_DO_NOT_USE)
911911 foreach(tgt ${BINARY_TARGETS} ${TEST_TARGETS} )
912912 target_link_libraries(${tgt} PRIVATE gcc_eh)
913913 endforeach()
914+
915+ if(WITH_UNIVERSAL_BINARY OR WITH_FUSE_EXTRACT_BINARY)
916+ # Build stub for self-extracting universal binary.
917+ add_executable(sfxstub_zstd sfx/stub.c)
918+ target_compile_options(sfxstub_zstd PRIVATE -O2)
919+
920+ if(LIBLZ4_FOUND)
921+ add_executable(sfxstub_lz4 sfx/stub.c)
922+ target_compile_definitions(sfxstub_lz4 PRIVATE DWARFS_SFX_STUB_USE_LZ4=1)
923+ target_link_libraries(sfxstub_lz4 PRIVATE PkgConfig::XXHASH PkgConfig::LIBLZ4)
924+ endif()
925+
926+ foreach(tgt sfxstub_zstd sfxstub_lz4)
927+ if(TARGET ${tgt} )
928+ target_compile_options(${tgt} PRIVATE -fno-stack-protector -fno-asynchronous-unwind-tables)
929+ target_link_options(${tgt} PRIVATE -Wl,--build-id=none)
930+ list(APPEND BINARY_TARGETS ${tgt} )
931+ endif()
932+ endforeach()
933+ endif()
914934endif(STATIC_BUILD_DO_NOT_USE)
915935
916936foreach(tgt ${TEST_TARGETS} )
@@ -1040,6 +1060,10 @@ if(STATIC_BUILD_DO_NOT_USE OR WIN32)
10401060 list(APPEND UNIVERSAL_TARGETS dwarfsfuseextract)
10411061 endif()
10421062
1063+ if(${CMAKE_SYSTEM_PROCESSOR } MATCHES " ^ (i386|x86_64|AMD64|aarch64|ppc64le|arm )$ ")
1064+ find_program(UPX_EXE upx upx.exe PATHS " c:/bin " DOC " ultimate packer for executables ")
1065+ endif()
1066+
10431067 foreach(tgt ${UNIVERSAL_TARGETS} )
10441068 get_target_property(TARGET_FILENAME ${tgt} OUTPUT_NAME)
10451069 get_filename_component(TARGET_FILENAME ${TARGET_FILENAME} NAME_WLE)
@@ -1055,10 +1079,6 @@ if(STATIC_BUILD_DO_NOT_USE OR WIN32)
10551079 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
10561080 )
10571081 else()
1058- if(${CMAKE_SYSTEM_PROCESSOR } MATCHES " ^ (i386|x86_64|AMD64|aarch64|ppc64le|arm )$ ")
1059- find_program(UPX_EXE upx upx.exe PATHS " c:/bin " DOC " ultimate packer for executables ")
1060- endif()
1061-
10621082 if(UPX_EXE)
10631083 # upx -9 is a good compromise between compression ratio and speed
10641084 # also, anything above --best increases the startup time of the compressed
@@ -1068,12 +1088,40 @@ if(STATIC_BUILD_DO_NOT_USE OR WIN32)
10681088 COMMAND ${UPX_EXE} -9 --best -o ${UNIVERSAL_OUT} $<TARGET_FILE :${tgt} >
10691089 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
10701090 )
1091+ elseif(TARGET sfxstub_lz4 OR TARGET sfxstub_zstd)
1092+ # Fallback if UPX is not found or doesn't support the target architecture.
1093+ # Prefer lz4 if available (as it is faster), otherwise use zstd.
1094+ if(TARGET sfxstub_zstd)
1095+ set(_sfx_stub_target sfxstub_zstd)
1096+ # Sweet spot between compression ratio and decompression speed.
1097+ set(_sfx_options " --level=16 ")
1098+ else()
1099+ set(_sfx_stub_target sfxstub_lz4)
1100+ set(_sfx_options " --lz4 ")
1101+ endif()
1102+ add_custom_command(
1103+ OUTPUT ${UNIVERSAL_OUT}
1104+ COMMAND ${CMAKE_SOURCE_DIR } /sfx/pack.py
1105+ ${_sfx_options}
1106+ --stub $<TARGET_FILE :${_sfx_stub_target} >
1107+ --input $<TARGET_FILE :${tgt} >
1108+ --output ${UNIVERSAL_OUT}
1109+ COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR}
1110+ ${UNIVERSAL_OUT} --extract-wrapped-binary ${UNIVERSAL_OUT} .extracted
1111+ COMMAND ${CMAKE_COMMAND } -E compare_files
1112+ ${CMAKE_CURRENT_BINARY_DIR } /${UNIVERSAL_OUT} .extracted
1113+ $<TARGET_FILE :${tgt} >
1114+ COMMAND ${CMAKE_COMMAND } -E remove
1115+ ${CMAKE_CURRENT_BINARY_DIR } /${UNIVERSAL_OUT} .extracted
1116+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
1117+ COMMENT " UPX not found/supported, using ${_sfx_stub_target} for universal binary "
1118+ )
10711119 else()
10721120 add_custom_command(
10731121 OUTPUT ${UNIVERSAL_OUT}
10741122 COMMAND ${CMAKE_COMMAND } -E copy $<TARGET_FILE :${tgt} > ${UNIVERSAL_OUT}
10751123 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
1076- COMMENT " UPX not found, copying binary without compression "
1124+ COMMENT " UPX not found/supported , copying binary without compression "
10771125 )
10781126 endif()
10791127 endif()
0 commit comments