From ac6c7f0d67d1be063c698edac63073c6088cbb01 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 9 Oct 2024 17:03:56 +0200 Subject: [PATCH] Also embed proj.ini if EMBED_RESOURCE_FILES=ON --- docs/source/install.rst | 9 +++---- src/embedded_resources.c | 17 +++++++++++++ src/embedded_resources.h | 1 + src/filemanager.cpp | 41 ++++++++++++++++++++++---------- src/lib_proj.cmake | 12 ++++++++++ test/cli/test_cs2cs_various.yaml | 1 + 6 files changed, 64 insertions(+), 17 deletions(-) diff --git a/docs/source/install.rst b/docs/source/install.rst index bf5291d579..a1b33a5dcc 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -452,16 +452,17 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory. Default is OFF for shared library builds (BUILD_SHARED_LIBS=ON), and ON for static library builds (BUILD_SHARED_LIBS=OFF). - When ON, :file:`proj.db` will be embedded into the PROJ library. + When ON, :file:`proj.db` and :file:`proj.ini` will be embedded into the PROJ library. .. option:: USE_ONLY_EMBEDDED_RESOURCE_FILES=ON/OFF .. versionadded:: 9.6 Even if EMBED_RESOURCE_FILES=ON, by default PROJ will still try to locate - :file:`proj.db` on the file system, and fallback to the embedded version if - not found. By setting USE_ONLY_EMBEDDED_RESOURCE_FILES=ON, no attempt - at localing :file:`proj.db` on the file system is made. Default is OFF. + :file:`proj.db` and :file:`proj.ini` on the file system, and fallback to the + embedded version if not found. + By setting USE_ONLY_EMBEDDED_RESOURCE_FILES=ON, no attempt at localing + those files on the file system is made. Default is OFF. Users will also typically want to set EMBED_PROJ_DATA_PATH=OFF if setting USE_ONLY_EMBEDDED_RESOURCE_FILES=OFF. diff --git a/src/embedded_resources.c b/src/embedded_resources.c index 7714ade8a5..04b721f11e 100644 --- a/src/embedded_resources.c +++ b/src/embedded_resources.c @@ -8,10 +8,27 @@ const unsigned char *pj_get_embedded_proj_db(unsigned int *pnSize) { *pnSize = (unsigned int)sizeof(proj_db); return proj_db; } + +const char *pj_get_embedded_proj_ini(unsigned int *pnSize) { + static const char proj_ini[] = { +#embed PROJ_INI + }; + *pnSize = (unsigned int)sizeof(proj_ini); + return proj_ini; +} + #else + #include "file_embed/proj_db.h" const unsigned char *pj_get_embedded_proj_db(unsigned int *pnSize) { *pnSize = proj_db_size; return proj_db_data; } + +#include "file_embed/proj_ini.h" +const char *pj_get_embedded_proj_ini(unsigned int *pnSize) { + *pnSize = proj_ini_size; + return (const char *)proj_ini_data; +} + #endif diff --git a/src/embedded_resources.h b/src/embedded_resources.h index 6fedbf05b1..39a119b0a7 100644 --- a/src/embedded_resources.h +++ b/src/embedded_resources.h @@ -6,6 +6,7 @@ extern "C" { #endif const unsigned char *pj_get_embedded_proj_db(unsigned int *pnSize); +const char *pj_get_embedded_proj_ini(unsigned int *pnSize); #ifdef __cplusplus } diff --git a/src/filemanager.cpp b/src/filemanager.cpp index c176c70c5b..3c6bcef61d 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -69,6 +69,10 @@ #include #endif +#ifdef EMBED_RESOURCE_FILES +#include "embedded_resources.h" +#endif + //! @cond Doxygen_Suppress using namespace NS_PROJ::internal; @@ -1850,21 +1854,32 @@ void pj_load_ini(PJ_CONTEXT *ctx) { } ctx->iniFileLoaded = true; - auto file = std::unique_ptr( - reinterpret_cast(pj_open_lib_internal( - ctx, "proj.ini", "rb", pj_open_file_with_manager, nullptr, 0))); - if (!file) - return; - file->seek(0, SEEK_END); - const auto filesize = file->tell(); - if (filesize == 0 || filesize > 100 * 1024U) - return; - file->seek(0, SEEK_SET); std::string content; - content.resize(static_cast(filesize)); - const auto nread = file->read(&content[0], content.size()); - if (nread != content.size()) + std::unique_ptr file; +#ifndef USE_ONLY_EMBEDDED_RESOURCE_FILES + file.reset(reinterpret_cast(pj_open_lib_internal( + ctx, "proj.ini", "rb", pj_open_file_with_manager, nullptr, 0))); +#endif + if (!file) { +#ifdef EMBED_RESOURCE_FILES + unsigned int content_size = 0; + const char *c_content = pj_get_embedded_proj_ini(&content_size); + content.assign(c_content, content_size); +#else return; +#endif + } + if (file) { + file->seek(0, SEEK_END); + const auto filesize = file->tell(); + if (filesize == 0 || filesize > 100 * 1024U) + return; + file->seek(0, SEEK_SET); + content.resize(static_cast(filesize)); + const auto nread = file->read(&content[0], content.size()); + if (nread != content.size()) + return; + } content += '\n'; size_t pos = 0; while (pos != std::string::npos) { diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 6b7ed06a78..5f9fad3aaf 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -412,9 +412,21 @@ if (EMBED_RESOURCE_FILES AND NOT IS_SHARP_EMBED_AVAILABLE_RES) DEPENDS generate_proj_db "${PROJECT_BINARY_DIR}/data/proj.db" ) target_sources(proj PRIVATE embedded_resources.c "${EMBEDDED_PROJ_DB}") + + set(EMBEDDED_PROJ_INI "file_embed/proj_ini.c") + add_custom_command( + OUTPUT "${EMBEDDED_PROJ_INI}" + COMMAND ${CMAKE_COMMAND} + -DRUN_FILE_EMBED_GENERATE=1 + "-DFILE_EMBED_GENERATE_PATH=${PROJECT_SOURCE_DIR}/data/proj.ini" + -P ${PROJECT_SOURCE_DIR}/cmake/FileEmbed.cmake + DEPENDS "${PROJECT_SOURCE_DIR}/data/proj.ini" + ) + target_sources(proj PRIVATE embedded_resources.c "${EMBEDDED_PROJ_DB}" "${EMBEDDED_PROJ_INI}") elseif(EMBED_RESOURCE_FILES AND IS_SHARP_EMBED_AVAILABLE_RES) add_library(proj_resources OBJECT embedded_resources.c) target_compile_definitions(proj_resources PRIVATE "PROJ_DB=\"${PROJECT_BINARY_DIR}/data/proj.db\"") + target_compile_definitions(proj_resources PRIVATE "PROJ_INI=\"${PROJECT_SOURCE_DIR}/data/proj.ini\"") target_compile_definitions(proj_resources PRIVATE USE_SHARP_EMBED) add_dependencies(proj_resources generate_proj_db) option(PROJ_OBJECT_LIBRARIES_POSITION_INDEPENDENT_CODE "Set ON to produce -fPIC code" ${BUILD_SHARED_LIBS}) diff --git a/test/cli/test_cs2cs_various.yaml b/test/cli/test_cs2cs_various.yaml index b6c621c853..21b0841748 100644 --- a/test/cli/test_cs2cs_various.yaml +++ b/test/cli/test_cs2cs_various.yaml @@ -1372,6 +1372,7 @@ tests: PROJ_DATA: $tmpdir PROJ_DEBUG: 2 PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY: YES + PROJ_ONLY_BEST_DEFAULT: "" args: EPSG:4326+5773 EPSG:4326+5782 in: 39 -3 0 grep-v: pj_open_lib