From dd8332d253cfaf3a9be306af4194e4dffc2e3b3c Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Thu, 17 Aug 2023 16:12:26 -0600 Subject: [PATCH] Add support for AppleClang and iOS cross compilation Compiling for iOS on an intel mac failed due to not handling the locations of gen_defines.asm and asm_offset.s when running under AppleClang. This solution works for the toolchain file used during development but may not work in other situations. iOS does not support secure_getenv, which is fine, except that the cmake code check_function_exists seems to think it is supported, causing compilation to fail. Just hardcoding secure_getenv to not be supported is enough for the unix shim logic to compile. The compilation revelaed a few issues in the test code, like not using [[maybe_unused]] and a signed/unsigned comparison. --- CMakeLists.txt | 4 ++-- loader/CMakeLists.txt | 10 +++++++++- scripts/parse_asm_values.py | 6 ++++-- tests/framework/icd/test_icd.cpp | 18 ++++++++++++------ tests/framework/shim/unix_shim.cpp | 16 +++++++++++----- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52e33d1e..c113d55d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,7 +164,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Cl target_compile_options(loader_common_options INTERFACE /WX) endif() target_compile_options(loader_common_options INTERFACE /W4) -elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") # using GCC or Clang with the regular front end if (ENABLE_WERROR) target_compile_options(loader_common_options INTERFACE -Werror) @@ -172,7 +172,7 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "C target_compile_options(loader_common_options INTERFACE -Wall -Wextra) endif() -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") target_compile_options(loader_common_options INTERFACE -Wno-missing-field-initializers) # need to prepend /clang: to compiler arguments when using clang-cl diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 2b3b6c27..394ce220 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -216,15 +216,23 @@ elseif(UNIX) # i.e.: Linux & Apple # Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it. target_compile_options(asm_offset PRIVATE -save-temps=obj) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(ASM_OFFSET_EXECUTABLE_LOCATION "$/gen_defines.asm") set(ASM_OFFSET_INTERMEDIATE_LOCATION "$/CMakeFiles/asm_offset.dir/asm_offset.c.s") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(ASM_OFFSET_EXECUTABLE_LOCATION "$/gen_defines.asm") set(ASM_OFFSET_INTERMEDIATE_LOCATION "$/CMakeFiles/asm_offset.dir/asm_offset.s") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + # Need to use the current binary dir since the asm_offset.s file is in that folder rather than the bundle + set(ASM_OFFSET_EXECUTABLE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm") + set(ASM_OFFSET_INTERMEDIATE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/asm_offset.dir/asm_offset.s") + else() + message(FATAL_ERROR "CXX_COMPILER_ID not supported!") endif() find_package(Python3 REQUIRED QUIET) # Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on add_custom_command(TARGET asm_offset POST_BUILD - COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "$/gen_defines.asm" + COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${ASM_OFFSET_EXECUTABLE_LOCATION}" "${ASM_OFFSET_INTERMEDIATE_LOCATION}" "GAS" "${CMAKE_CXX_COMPILER_ID}" "${ASM_OFFSET_SYSTEM_PROCESSOR}" BYPRODUCTS gen_defines.asm ) diff --git a/scripts/parse_asm_values.py b/scripts/parse_asm_values.py index df7a0460..e6ae90f5 100644 --- a/scripts/parse_asm_values.py +++ b/scripts/parse_asm_values.py @@ -39,6 +39,8 @@ compiler = sys.argv[4] # Only used with GAS - MASM doesn't need this, as it has its own way to determine x86 vs x64 arch = sys.argv[5] +POSIX_COMPILERS = ["GNU", "Clang", "AppleClang"] + if destination_file is None or source_asm_file is None or assembler_type is None or compiler is None or arch is None: print("Required command line arguments were not provided") sys.exit(1) @@ -80,13 +82,13 @@ with open(destination_file, "w", encoding="utf-8") as dest: if d == "VULKAN_LOADER_ERROR_BIT": continue # skip due to special case match = re.search(d + " DD [ ]*([0-9a-f]+)H", asm_intermediate_file) - elif compiler == "Clang" or compiler == "GNU": + elif compiler in POSIX_COMPILERS: match = re.search(d + " = ([0-9]+)", asm_intermediate_file) if match: if compiler == "MSVC": value = str(int(match.group(1), 16)) - elif compiler == "Clang" or compiler == "GNU": + elif compiler in POSIX_COMPILERS: value = match.group(1) if assembler_type == "MASM": # MASM uses hex values, decode them here diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp index f620f1dd..a2c47574 100644 --- a/tests/framework/icd/test_icd.cpp +++ b/tests/framework/icd/test_icd.cpp @@ -606,16 +606,20 @@ VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceDirectFBPresentationSuppo #endif // VK_USE_PLATFORM_DIRECTFB_EXT #if defined(VK_USE_PLATFORM_MACOS_MVK) -VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, - const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) { +VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMacOSSurfaceMVK([[maybe_unused]] VkInstance instance, + [[maybe_unused]] const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, + [[maybe_unused]] const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface) { common_nondispatch_handle_creation(icd.surface_handles, pSurface); return VK_SUCCESS; } #endif // VK_USE_PLATFORM_MACOS_MVK #if defined(VK_USE_PLATFORM_IOS_MVK) -VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, - const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) { +VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateIOSSurfaceMVK([[maybe_unused]] VkInstance instance, + [[maybe_unused]] const VkIOSSurfaceCreateInfoMVK* pCreateInfo, + [[maybe_unused]] const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface) { common_nondispatch_handle_creation(icd.surface_handles, pSurface); return VK_SUCCESS; } @@ -632,8 +636,10 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateStreamDescriptorSurfaceGGP(VkInstanc #endif // VK_USE_PLATFORM_GGP #if defined(VK_USE_PLATFORM_METAL_EXT) -VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) { +VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMetalSurfaceEXT([[maybe_unused]] VkInstance instance, + [[maybe_unused]] const VkMetalSurfaceCreateInfoEXT* pCreateInfo, + [[maybe_unused]] const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface) { common_nondispatch_handle_creation(icd.surface_handles, pSurface); return VK_SUCCESS; } diff --git a/tests/framework/shim/unix_shim.cpp b/tests/framework/shim/unix_shim.cpp index 16bd73ad..12b3bfa5 100644 --- a/tests/framework/shim/unix_shim.cpp +++ b/tests/framework/shim/unix_shim.cpp @@ -72,6 +72,7 @@ FRAMEWORK_EXPORT PlatformShim* get_platform_shim(std::vector* #define DLOPEN_FUNC_NAME my_dlopen #define GETEUID_FUNC_NAME my_geteuid #define GETEGID_FUNC_NAME my_getegid +#if !defined(TARGET_OS_IPHONE) #if defined(HAVE_SECURE_GETENV) #define SECURE_GETENV_FUNC_NAME my_secure_getenv #endif @@ -79,6 +80,7 @@ FRAMEWORK_EXPORT PlatformShim* get_platform_shim(std::vector* #define __SECURE_GETENV_FUNC_NAME my__secure_getenv #endif #endif +#endif using PFN_OPENDIR = DIR* (*)(const char* path_name); using PFN_READDIR = struct dirent* (*)(DIR* dir_stream); @@ -102,7 +104,7 @@ using PFN_SEC_GETENV = char* (*)(const char* name); #define real_geteuid geteuid #define real_getegid getegid #if defined(HAVE_SECURE_GETENV) -#define real_secure_getenv _secure_getenv +#define real_secure_getenv secure_getenv #endif #if defined(HAVE___SECURE_GETENV) #define real__secure_getenv __secure_getenv @@ -281,6 +283,7 @@ FRAMEWORK_EXPORT gid_t GETEGID_FUNC_NAME(void) { } } +#if !defined(TARGET_OS_IPHONE) #if defined(HAVE_SECURE_GETENV) FRAMEWORK_EXPORT char* SECURE_GETENV_FUNC_NAME(const char* name) { #if !defined(__APPLE__) @@ -306,20 +309,21 @@ FRAMEWORK_EXPORT char* __SECURE_GETENV_FUNC_NAME(const char* name) { } } #endif - +#endif #if defined(__APPLE__) FRAMEWORK_EXPORT CFBundleRef my_CFBundleGetMainBundle() { static CFBundleRef global_bundle{}; return reinterpret_cast(&global_bundle); } -FRAMEWORK_EXPORT CFURLRef my_CFBundleCopyResourcesDirectoryURL(CFBundleRef bundle) { +FRAMEWORK_EXPORT CFURLRef my_CFBundleCopyResourcesDirectoryURL([[maybe_unused]] CFBundleRef bundle) { static CFURLRef global_url{}; return reinterpret_cast(&global_url); } -FRAMEWORK_EXPORT Boolean my_CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, UInt8* buffer, +FRAMEWORK_EXPORT Boolean my_CFURLGetFileSystemRepresentation([[maybe_unused]] CFURLRef url, + [[maybe_unused]] Boolean resolveAgainstBase, UInt8* buffer, CFIndex maxBufLen) { if (!platform_shim.bundle_contents.empty()) { - size_t copy_len = platform_shim.bundle_contents.size(); + CFIndex copy_len = (CFIndex)platform_shim.bundle_contents.size(); if (copy_len > maxBufLen) { copy_len = maxBufLen; } @@ -352,6 +356,7 @@ __attribute__((used)) static Interposer _interpose_fopen MACOS_ATTRIB = {VOIDP_C __attribute__((used)) static Interposer _interpose_dlopen MACOS_ATTRIB = {VOIDP_CAST(my_dlopen), VOIDP_CAST(dlopen)}; __attribute__((used)) static Interposer _interpose_euid MACOS_ATTRIB = {VOIDP_CAST(my_geteuid), VOIDP_CAST(geteuid)}; __attribute__((used)) static Interposer _interpose_egid MACOS_ATTRIB = {VOIDP_CAST(my_getegid), VOIDP_CAST(getegid)}; +#if !defined(TARGET_OS_IPHONE) #if defined(HAVE_SECURE_GETENV) __attribute__((used)) static Interposer _interpose_secure_getenv MACOS_ATTRIB = {VOIDP_CAST(my_secure_getenv), VOIDP_CAST(secure_getenv)}; @@ -360,6 +365,7 @@ __attribute__((used)) static Interposer _interpose_secure_getenv MACOS_ATTRIB = __attribute__((used)) static Interposer _interpose__secure_getenv MACOS_ATTRIB = {VOIDP_CAST(my__secure_getenv), VOIDP_CAST(__secure_getenv)}; #endif +#endif __attribute__((used)) static Interposer _interpose_CFBundleGetMainBundle MACOS_ATTRIB = {VOIDP_CAST(my_CFBundleGetMainBundle), VOIDP_CAST(CFBundleGetMainBundle)}; __attribute__((used)) static Interposer _interpose_CFBundleCopyResourcesDirectoryURL MACOS_ATTRIB = { -- 2.34.1