Skip to content

Commit

Permalink
Merge pull request #2476 from rouault/fix_2399
Browse files Browse the repository at this point in the history
Add build time option to make PROJ_LIB env var tested last (fixes #2399)
  • Loading branch information
kbevers committed Feb 7, 2021
2 parents c0fb004 + 9488b26 commit 197ea05
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ if(ENABLE_CURL)
endif()
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
################################################################################
Expand Down
13 changes: 13 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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 ---------------------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions docs/source/resource_files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
79 changes: 63 additions & 16 deletions src/filemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 197ea05

Please sign in to comment.