diff --git a/CMakeLists.txt b/CMakeLists.txt index 27ab6e5..e59256e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,17 +256,10 @@ if(NOT WIN32) include(GNUInstallDirs) add_definitions(-DSYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}") - add_definitions(-DDATADIR="${CMAKE_INSTALL_FULL_DATADIR}") - # Make sure /etc is searched by the loader - if (NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc")) + if(NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc")) add_definitions(-DEXTRASYSCONFDIR="/etc") endif() - - # Make sure /usr/share is searched by the loader - if (NOT (CMAKE_INSTALL_FULL_DATADIR STREQUAL "/usr/share")) - add_definitions(-DEXTRADATADIR="/usr/share") - endif() endif() if(UNIX) diff --git a/loader/loader.c b/loader/loader.c index 24758f4..af7cc85 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -2909,7 +2909,7 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, const char *env_override, const char *source_override, bool is_layer, bool warn_if_not_present, - const char *location, const char *home_location, + const char *location, const char *relative_location, struct loader_manifest_files *out_files) { const char * override = NULL; char *override_getenv = NULL; @@ -2941,9 +2941,9 @@ loader_get_manifest_files(const struct loader_instance *inst, } #if !defined(_WIN32) - if (location == NULL && home_location == NULL) { + if (location == NULL && relative_location == NULL) { #else - home_location = NULL; + relative_location = NULL; if (location == NULL) { #endif loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, @@ -2962,16 +2962,89 @@ loader_get_manifest_files(const struct loader_instance *inst, // Make a copy of the input we are using so it is not modified // Also handle getting the location(s) from registry on Windows if (override == NULL) { - loc = loader_stack_alloc(strlen(location) + 1); + size_t loc_size = strlen(location) + 1; +#if !defined(_WIN32) + const char *xdgconfdirs = secure_getenv("XDG_CONFIG_DIRS"); + const char *xdgdatadirs = secure_getenv("XDG_DATA_DIRS"); + if (xdgconfdirs == NULL || xdgconfdirs[0] == '\0') + xdgconfdirs = "/etc/xdg"; + if (xdgdatadirs == NULL || xdgdatadirs[0] == '\0') + xdgdatadirs = "/usr/local/share:/usr/share"; + const size_t rel_size = strlen(relative_location); + // Leave space for trailing separators + loc_size += strlen(xdgconfdirs) + strlen(xdgdatadirs) + 2*rel_size + 2; + for (const char *x = xdgconfdirs; *x; ++x) + if (*x == PATH_SEPARATOR) loc_size += rel_size; + for (const char *x = xdgdatadirs; *x; ++x) + if (*x == PATH_SEPARATOR) loc_size += rel_size; + loc_size += strlen(SYSCONFDIR) + rel_size + 1; +#ifdef EXTRASYSCONFDIR + loc_size += strlen(EXTRASYSCONFDIR) + rel_size + 1; +#endif +#endif + loc = loader_stack_alloc(loc_size); if (loc == NULL) { loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_get_manifest_files: Failed to allocate " "%d bytes for manifest file location.", - strlen(location)); + loc_size); res = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; } - strcpy(loc, location); + char *loc_write = loc; +#if !defined(_WIN32) + const char *loc_read; + + loc_read = &xdgconfdirs[0]; + for (const char *x = loc_read;; ++x) { + if (*x == PATH_SEPARATOR || *x == '\0') { + const size_t s = x - loc_read; + memcpy(loc_write, loc_read, s); + loc_write += s; + memcpy(loc_write, relative_location, rel_size); + loc_write += rel_size; + *loc_write++ = PATH_SEPARATOR; + if (*x == 0) + break; + loc_read = ++x; + } + } + + memcpy(loc_write, SYSCONFDIR, strlen(SYSCONFDIR)); + loc_write += strlen(SYSCONFDIR); + memcpy(loc_write, relative_location, rel_size); + loc_write += rel_size; + *loc_write++ = PATH_SEPARATOR; + +#ifdef EXTRASYSCONFDIR + memcpy(loc_write, EXTRASYSCONFDIR, strlen(EXTRASYSCONFDIR)); + loc_write += strlen(EXTRASYSCONFDIR); + memcpy(loc_write, relative_location, rel_size); + loc_write += rel_size; + *loc_write++ = PATH_SEPARATOR; +#endif + + loc_read = &xdgdatadirs[0]; + for (const char *x = loc_read;; ++x) { + if (*x == PATH_SEPARATOR || *x == '\0') { + const size_t s = x - loc_read; + memcpy(loc_write, loc_read, s); + loc_write += s; + memcpy(loc_write, relative_location, rel_size); + loc_write += rel_size; + *loc_write++ = PATH_SEPARATOR; + if (*x == 0) + break; + loc_read = ++x; + } + } + --loc_write; + *loc_write = '\0'; +#else + memcpy(loc_write, location, loc_size); + loc[loc_size-1] = '\0'; +#endif + #if defined(_WIN32) VkResult reg_result = loaderGetRegistryFiles(inst, loc, ®); if (VK_SUCCESS != reg_result || NULL == reg) { @@ -3122,14 +3195,14 @@ loader_get_manifest_files(const struct loader_instance *inst, } file = next_file; #if !defined(_WIN32) - if (home_location != NULL && + if (relative_location != NULL && (next_file == NULL || *next_file == '\0') && override == NULL) { char *xdgdatahome = secure_getenv("XDG_DATA_HOME"); size_t len; if (xdgdatahome != NULL) { char *home_loc = loader_stack_alloc(strlen(xdgdatahome) + 2 + - strlen(home_location)); + strlen(relative_location)); if (home_loc == NULL) { loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_get_manifest_files: Failed to allocate " @@ -3139,15 +3212,15 @@ loader_get_manifest_files(const struct loader_instance *inst, } strcpy(home_loc, xdgdatahome); // Add directory separator if needed - if (home_location[0] != DIRECTORY_SYMBOL) { + if (relative_location[0] != DIRECTORY_SYMBOL) { len = strlen(home_loc); home_loc[len] = DIRECTORY_SYMBOL; home_loc[len + 1] = '\0'; } - strcat(home_loc, home_location); + strcat(home_loc, relative_location); file = home_loc; next_file = loader_get_next_path(file); - home_location = NULL; + relative_location = NULL; loader_log( inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, @@ -3160,7 +3233,7 @@ loader_get_manifest_files(const struct loader_instance *inst, char *home = secure_getenv("HOME"); if (home != NULL) { char *home_loc = loader_stack_alloc(strlen(home) + 16 + - strlen(home_location)); + strlen(relative_location)); if (home_loc == NULL) { loader_log( inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, @@ -3178,15 +3251,15 @@ loader_get_manifest_files(const struct loader_instance *inst, } strcat(home_loc, ".local/share"); - if (home_location[0] != DIRECTORY_SYMBOL) { + if (relative_location[0] != DIRECTORY_SYMBOL) { len = strlen(home_loc); home_loc[len] = DIRECTORY_SYMBOL; home_loc[len + 1] = '\0'; } - strcat(home_loc, home_location); + strcat(home_loc, relative_location); file = home_loc; next_file = loader_get_next_path(file); - home_location = NULL; + relative_location = NULL; loader_log( inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, @@ -3263,7 +3336,7 @@ VkResult loader_icd_scan(const struct loader_instance *inst, // Get a list of manifest files for ICDs res = loader_get_manifest_files(inst, "VK_ICD_FILENAMES", NULL, false, true, DEFAULT_VK_DRIVERS_INFO, - HOME_VK_DRIVERS_INFO, &manifest_files); + RELATIVE_VK_DRIVERS_INFO, &manifest_files); if (VK_SUCCESS != res || manifest_files.count == 0) { goto out; } @@ -3490,7 +3563,7 @@ void loader_layer_scan(const struct loader_instance *inst, if (VK_SUCCESS != loader_get_manifest_files(inst, LAYERS_PATH_ENV, LAYERS_SOURCE_PATH, true, true, DEFAULT_VK_ELAYERS_INFO, - HOME_VK_ELAYERS_INFO, &manifest_files[0])) { + RELATIVE_VK_ELAYERS_INFO, &manifest_files[0])) { goto out; } @@ -3499,7 +3572,7 @@ void loader_layer_scan(const struct loader_instance *inst, // overridden by LAYERS_PATH_ENV if (VK_SUCCESS != loader_get_manifest_files(inst, NULL, NULL, true, false, DEFAULT_VK_ILAYERS_INFO, - HOME_VK_ILAYERS_INFO, + RELATIVE_VK_ILAYERS_INFO, &manifest_files[1])) { goto out; } @@ -3569,7 +3642,7 @@ void loader_implicit_layer_scan(const struct loader_instance *inst, // overridden by LAYERS_PATH_ENV VkResult res = loader_get_manifest_files( inst, NULL, NULL, true, false, DEFAULT_VK_ILAYERS_INFO, - HOME_VK_ILAYERS_INFO, &manifest_files); + RELATIVE_VK_ILAYERS_INFO, &manifest_files); if (VK_SUCCESS != res || manifest_files.count == 0) { return; } diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h index dc4ac10..50a7966 100644 --- a/loader/vk_loader_platform.h +++ b/loader/vk_loader_platform.h @@ -57,47 +57,9 @@ #define VULKAN_ILAYERCONF_DIR "implicit_layer.d" #define VULKAN_LAYER_DIR "layer" -#if defined(EXTRASYSCONFDIR) -#define EXTRA_DRIVERS_SYSCONFDIR_INFO ":" \ - EXTRASYSCONFDIR VULKAN_DIR VULKAN_ICDCONF_DIR -#define EXTRA_ELAYERS_SYSCONFDIR_INFO ":" \ - EXTRASYSCONFDIR VULKAN_DIR VULKAN_ELAYERCONF_DIR -#define EXTRA_ILAYERS_SYSCONFDIR_INFO ":" \ - EXTRASYSCONFDIR VULKAN_DIR VULKAN_ILAYERCONF_DIR -#else -#define EXTRA_DRIVERS_SYSCONFDIR_INFO -#define EXTRA_ELAYERS_SYSCONFDIR_INFO -#define EXTRA_ILAYERS_SYSCONFDIR_INFO -#endif - -#if defined(EXTRADATADIR) -#define EXTRA_DRIVERS_DATADIR_INFO ":" \ - EXTRADATADIR VULKAN_DIR VULKAN_ICDCONF_DIR -#define EXTRA_ELAYERS_DATADIR_INFO ":" \ - EXTRADATADIR VULKAN_DIR VULKAN_ELAYERCONF_DIR -#define EXTRA_ILAYERS_DATADIR_INFO ":" \ - EXTRADATADIR VULKAN_DIR VULKAN_ILAYERCONF_DIR -#else -#define EXTRA_DRIVERS_DATADIR_INFO -#define EXTRA_ELAYERS_DATADIR_INFO -#define EXTRA_ILAYERS_DATADIR_INFO -#endif - -#define DEFAULT_VK_DRIVERS_INFO \ - SYSCONFDIR VULKAN_DIR VULKAN_ICDCONF_DIR ":" \ - DATADIR VULKAN_DIR VULKAN_ICDCONF_DIR \ - EXTRA_DRIVERS_SYSCONFDIR_INFO \ - EXTRA_DRIVERS_DATADIR_INFO -#define DEFAULT_VK_ELAYERS_INFO \ - SYSCONFDIR VULKAN_DIR VULKAN_ELAYERCONF_DIR ":" \ - DATADIR VULKAN_DIR VULKAN_ELAYERCONF_DIR \ - EXTRA_ELAYERS_SYSCONFDIR_INFO \ - EXTRA_ELAYERS_DATADIR_INFO -#define DEFAULT_VK_ILAYERS_INFO \ - SYSCONFDIR VULKAN_DIR VULKAN_ILAYERCONF_DIR ":" \ - DATADIR VULKAN_DIR VULKAN_ILAYERCONF_DIR \ - EXTRA_ILAYERS_SYSCONFDIR_INFO \ - EXTRA_ILAYERS_DATADIR_INFO +#define DEFAULT_VK_DRIVERS_INFO "" +#define DEFAULT_VK_ELAYERS_INFO "" +#define DEFAULT_VK_ILAYERS_INFO "" #define DEFAULT_VK_DRIVERS_PATH "" #if !defined(DEFAULT_VK_LAYERS_PATH) @@ -109,9 +71,9 @@ #endif #define LAYERS_PATH_ENV "VK_LAYER_PATH" -#define HOME_VK_DRIVERS_INFO VULKAN_DIR VULKAN_ICDCONF_DIR -#define HOME_VK_ELAYERS_INFO VULKAN_DIR VULKAN_ELAYERCONF_DIR -#define HOME_VK_ILAYERS_INFO VULKAN_DIR VULKAN_ILAYERCONF_DIR +#define RELATIVE_VK_DRIVERS_INFO VULKAN_DIR VULKAN_ICDCONF_DIR +#define RELATIVE_VK_ELAYERS_INFO VULKAN_DIR VULKAN_ELAYERCONF_DIR +#define RELATIVE_VK_ILAYERS_INFO VULKAN_DIR VULKAN_ILAYERCONF_DIR // C99: #define PRINTF_SIZE_T_SPECIFIER "%zu" @@ -251,9 +213,9 @@ loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) { #define LAYERS_SOURCE_PATH NULL #endif #define LAYERS_PATH_ENV "VK_LAYER_PATH" -#define HOME_VK_DRIVERS_INFO "" -#define HOME_VK_ELAYERS_INFO "" -#define HOME_VK_ILAYERS_INFO "" +#define RELATIVE_VK_DRIVERS_INFO "" +#define RELATIVE_VK_ELAYERS_INFO "" +#define RELATIVE_VK_ILAYERS_INFO "" #define PRINTF_SIZE_T_SPECIFIER "%Iu" // File IO