Prevent CMake from looking into PATH for libraries

2019-06-23 23:35发布

Consider the simple CMake script below trying to find a fictional theheader.h C header file. As far as I know, this is the typical way to locate the include directory of a library in the FindXXX.cmake modules.

cmake_minimum_required(VERSION 2.6)
project(test)

find_path(
    TEST_INCLUDES
    NAMES "theheader.h"
)

message(STATUS "TEST_INCLUDES: ${TEST_INCLUDES}")

Now assume that, in a way unrelated to this CMake script, I have edited my PATH environment variable (I'm running Linux) to contain a custom bin directory:

PATH="/home/cschreib/someapp/bin:$PATH"

Turns out, the directory /home/cschreib/someapp/include exists, and contains a file named theheader.h. This header was only used locally to build someapp, it was never meant to be used by other programs*.

Before CMake 3.3, this custom location was never found by CMake. However, starting with version 3.3, CMake tries to be smart and substitutes bin for include for all directories in $PATH. Therefore, CMake 3.3 (and above) does find theheader.h in this custom directory. Because this was never intended, this is causing all sorts of trouble, including a mismatch between headers and shared objects versions.

I know I can tell CMake not to look in $PATH by using the NO_SYSTEM_ENVIRONMENT_PATH option in find_path, but I am looking for a more generic solution to this issue. Indeed, this problem can happen for any library. I could make a copy of all the FindXXX.cmake modules I need and systematically add the NO_SYSTEM_ENVIRONMENT_PATH option, but I would rather avoid this.

Is there a global switch I could use to turn off this unwanted feature? Or some other way out?

*: Before someone comments on this. I am aware this is not good practice. I am also aware that, in my community, people tend not to care much about good and bad practices, and this situation is very common. Since I am not going to change the community, I want my CMake scripts to be robust against bad practices.

标签: cmake
2条回答
该账号已被封号
2楼-- · 2019-06-24 00:12

This behavior was removed again for non-Windows platform with CMake version 3.6.

If you run into this problem just update the the latest CMake version. See version 3.6 release notes Deprecated and Removed Features:

The find_library(), find_path(), and find_file() commands no longer search in installation prefixes derived from the PATH environment variable on non-Windows platforms. This behavior was added in CMake 3.3 to support Windows hosts but has proven problematic on UNIX hosts. Users that keep some <prefix>/bin directories in the PATH just for their tools do not necessarily want any supporting <prefix>/lib directories searched. One may set the CMAKE_PREFIX_PATH environment variable with a ;-list of prefixes that are to be searched.

查看更多
Animai°情兽
3楼-- · 2019-06-24 00:23

To my knowledge, such a switch does not exist in CMake 3.5. I would not try working around this, because even if you hack it with regard to CMake, this might still confuse compilers or users.

Where are the headers from? Can you ask one of the projects to change the header? Usually projects don't want to clash with other libraries and try to address such issues.

查看更多
登录 后发表回答