aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2021-02-07 11:16:21 +0100
committerGitHub <noreply@github.com>2021-02-07 11:16:21 +0100
commit197ea0569bc39651a5c7a216bfbe1e674a099c84 (patch)
tree3852365d8d07a81c84419981a32c037afcb94623
parentc0fb0041c2933b4cc953fb763aaaccd4f85a9c0d (diff)
parent9488b26ca5b7ea763db4e210b311bcf3f04233ca (diff)
downloadPROJ-197ea0569bc39651a5c7a216bfbe1e674a099c84.tar.gz
PROJ-197ea0569bc39651a5c7a216bfbe1e674a099c84.zip
Merge pull request #2476 from rouault/fix_2399
Add build time option to make PROJ_LIB env var tested last (fixes #2399)
-rw-r--r--CMakeLists.txt7
-rw-r--r--configure.ac13
-rw-r--r--docs/source/resource_files.rst5
-rw-r--r--src/Makefile.am2
-rw-r--r--src/filemanager.cpp79
5 files changed, 89 insertions, 17 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee1444a4..344823ee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -177,6 +177,13 @@ if(ENABLE_CURL)
endif()
################################################################################
+
+option(PROJ_LIB_ENV_VAR_TRIED_LAST "Whether the PROJ_LIB environment variable should be tried after the hardcoded location" OFF)
+if(PROJ_LIB_ENV_VAR_TRIED_LAST)
+ add_definitions(-DPROJ_LIB_ENV_VAR_TRIED_LAST)
+endif()
+
+################################################################################
# threading configuration
################################################################################
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
diff --git a/configure.ac b/configure.ac
index 33f8cc0c..cc138aaa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -321,6 +321,19 @@ AC_SUBST(CURL_LIBS,$CURL_LIBS)
AC_SUBST(CURL_ENABLED_FLAGS,$CURL_ENABLED_FLAGS)
AM_CONDITIONAL(HAVE_CURL, [test "x$FOUND_CURL" = "xyes"])
+
+dnl ---------------------------------------------------------------------------
+dnl proj-lib-env-var-tried-last
+dnl ---------------------------------------------------------------------------
+
+AC_ARG_ENABLE(proj-lib-env-var-tried-last,
+ AS_HELP_STRING([--enable-proj-lib-env-var-tried-last],
+ [Whether the PROJ_LIB environment variable should be tried after the hardcoded location [default=no]]))
+
+if test "x$enable_proj_lib_env_var_tried_last" = "xyes"; then
+ AC_SUBST(PROJ_LIB_ENV_VAR_TRIED_LAST_FLAGS,-DPROJ_LIB_ENV_VAR_TRIED_LAST)
+fi
+
dnl ---------------------------------------------------------------------------
dnl Check for external Google Test
dnl ---------------------------------------------------------------------------
diff --git a/docs/source/resource_files.rst b/docs/source/resource_files.rst
index 22edbc90..0f902d8d 100644
--- a/docs/source/resource_files.rst
+++ b/docs/source/resource_files.rst
@@ -60,6 +60,11 @@ The following paths are checked in order:
that since this is a hard-wired path setting, it only works if the whole
PROJ installation is not moved somewhere else.
+ .. note:: if PROJ is built with the PROJ_LIB_ENV_VAR_TRIED_LAST CMake option /
+ --enable-proj-lib-env-var-tried-last configure switch, then this
+ hard-wired path will be tried before looking at the environment
+ variable :envvar:`PROJ_LIB`.
+
- The current directory
When networking capabilities are enabled, either by API with the
diff --git a/src/Makefile.am b/src/Makefile.am
index 16eca5de..b54f4323 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,7 +6,7 @@ TESTS = geodtest
check_PROGRAMS = geodtest
AM_CPPFLAGS = -DPROJ_LIB=\"$(pkgdatadir)\" \
- -DMUTEX_@MUTEX_SETTING@ -I$(top_srcdir)/include @SQLITE3_CFLAGS@ @TIFF_CFLAGS@ @TIFF_ENABLED_FLAGS@ @CURL_CFLAGS@ @CURL_ENABLED_FLAGS@
+ -DMUTEX_@MUTEX_SETTING@ -I$(top_srcdir)/include @SQLITE3_CFLAGS@ @TIFF_CFLAGS@ @TIFF_ENABLED_FLAGS@ @CURL_CFLAGS@ @CURL_ENABLED_FLAGS@ @PROJ_LIB_ENV_VAR_TRIED_LAST_FLAGS@
AM_CXXFLAGS = @CXX_WFLAGS@ @FLTO_FLAG@
include_HEADERS = proj.h proj_experimental.h proj_constants.h geodesic.h \
diff --git a/src/filemanager.cpp b/src/filemanager.cpp
index 0a0af8cf..121a4b3a 100644
--- a/src/filemanager.cpp
+++ b/src/filemanager.cpp
@@ -1362,6 +1362,12 @@ static const char *proj_lib_name =
nullptr;
#endif
+#ifdef PROJ_LIB_ENV_VAR_TRIED_LAST
+static bool gbPROJ_LIB_ENV_VAR_TRIED_LAST = true;
+#else
+static bool gbPROJ_LIB_ENV_VAR_TRIED_LAST = false;
+#endif
+
static bool dontReadUserWritableDirectory() {
// Env var mostly for testing purposes and being independent from
// an existing installation
@@ -1448,8 +1454,10 @@ static void *pj_open_lib_internal(
sysname = fname.c_str();
}
- /* if is environment PROJ_LIB defined */
- else if (!(projLib = NS_PROJ::FileManager::getProjLibEnvVar(ctx))
+ /* if the environment PROJ_LIB defined, and *not* tried as last
+ possibility */
+ else if (!gbPROJ_LIB_ENV_VAR_TRIED_LAST &&
+ !(projLib = NS_PROJ::FileManager::getProjLibEnvVar(ctx))
.empty()) {
auto paths = NS_PROJ::internal::split(projLib, dirSeparator);
for (const auto &path : paths) {
@@ -1461,17 +1469,42 @@ static void *pj_open_lib_internal(
if (fid)
break;
}
+ }
+
+ else if ((sysname = get_path_from_relative_share_proj(
+ ctx, name, fname)) != nullptr) {
/* check if it lives in a ../share/proj dir of the proj dll */
- } else if ((sysname = get_path_from_relative_share_proj(
- ctx, name, fname)) != nullptr) {
+ } else if (proj_lib_name != nullptr &&
+ (fid = open_file(
+ ctx,
+ (std::string(proj_lib_name) + DIR_CHAR + name).c_str(),
+ mode)) != nullptr) {
+
/* or hardcoded path */
- } else if ((sysname = proj_lib_name) != nullptr) {
- fname = sysname;
+ fname = proj_lib_name;
fname += DIR_CHAR;
fname += name;
sysname = fname.c_str();
+ }
+
+ /* if the environment PROJ_LIB defined, and tried as last possibility */
+ else if (gbPROJ_LIB_ENV_VAR_TRIED_LAST &&
+ !(projLib = NS_PROJ::FileManager::getProjLibEnvVar(ctx))
+ .empty()) {
+ auto paths = NS_PROJ::internal::split(projLib, dirSeparator);
+ for (const auto &path : paths) {
+ fname = path;
+ fname += DIR_CHAR;
+ fname += name;
+ sysname = fname.c_str();
+ fid = open_file(ctx, sysname, mode);
+ if (fid)
+ break;
+ }
+ }
+
+ else {
/* just try it bare bones */
- } else {
sysname = name;
}
@@ -1516,21 +1549,35 @@ std::vector<std::string> pj_get_default_searchpaths(PJ_CONTEXT *ctx) {
ignoreUserWritableDirectory[0] == '\0') {
ret.push_back(proj_context_get_user_writable_directory(ctx, false));
}
+
const std::string envPROJ_LIB = NS_PROJ::FileManager::getProjLibEnvVar(ctx);
- if (!envPROJ_LIB.empty()) {
- ret.push_back(envPROJ_LIB);
- }
- if (envPROJ_LIB.empty()) {
- const std::string relativeSharedProj = pj_get_relative_share_proj(ctx);
+ const std::string relativeSharedProj = pj_get_relative_share_proj(ctx);
+
+ if (gbPROJ_LIB_ENV_VAR_TRIED_LAST) {
+/* Situation where PROJ_LIB environment variable is tried in last */
+#ifdef PROJ_LIB
+ ret.push_back(PROJ_LIB);
+#endif
if (!relativeSharedProj.empty()) {
ret.push_back(relativeSharedProj);
}
- }
+ if (!envPROJ_LIB.empty()) {
+ ret.push_back(envPROJ_LIB);
+ }
+ } else {
+ /* Situation where PROJ_LIB environment variable is used if defined */
+ if (!envPROJ_LIB.empty()) {
+ ret.push_back(envPROJ_LIB);
+ } else {
+ if (!relativeSharedProj.empty()) {
+ ret.push_back(relativeSharedProj);
+ }
#ifdef PROJ_LIB
- if (envPROJ_LIB.empty()) {
- ret.push_back(PROJ_LIB);
- }
+ ret.push_back(PROJ_LIB);
#endif
+ }
+ }
+
return ret;
}