[CMake] CMake performs search for includes/libs in non-default compiler search paths.

Óscar Fuentes ofv at wanadoo.es
Thu Jan 27 17:51:48 EST 2011


Andreas Pakulat <apaku at gmx.de> writes:

> On 27.01.11 20:08:06, Óscar Fuentes wrote:
>> Okay, so if I have this:
>> 
>> check_include_file(foo.h HAVE_FOO_H)
>> 
>> and it succeeds, I have no guarantees that a program such as this:
>> 
>> #include "foo.h"
>> 
>> will compile, becasue foo.h may be found on a directory not included on
>> the compiler's default search list.
>
> Actually, thats wrong. If you look at the check_include_file macro
> you'll notice that it uses try_compile. That in turn (as documented in
> man cmake) creates a cmakelists.txt which only adds include dirs set via
> the INCLUDE_DIRECTORIES variable passed into the internal cmake call and
> otherwise just uses a simple add_executable() call for the source. 
>
> The convenience paths are only added to things such as find_path,
> find_library etc. They are _not_ added to compiler invocations
> automatically.
>
> Hence the above check_include_file would fail if foo.h is in
> /usr/local/include and your compiler does not search there by default.
>
> So you'd need to either set CMAKE_REQUIRED_INCLUDES or use find_path and
> then add the director to include_directories().

Okay, this helps a lot.

The original problem arised when a user who was trying to add support
for a library reported that cmake was successfully finding the headers
and library file (with find_*) without the user's help, but failing at
build time because the compiler was unable to #include to headers. Then
he reported that the library was located under a catch-all directory
that is not part of the default search list of the compiler (/usr/local
in FreeBSD) and I was reluctant to add it to include_directories,
because that may cause problems like the described on my previous post
if there is some library already installed on those catch-all extra
directories (note that the problem does not arise if the library's
headers are on /usr/include instead of /usr/local/include, because cmake
takes care of /usr/include occurrences of the header search list, as
Michael explained)

All this is a potential source of confussion, but I understand that
cmake is trying to be helpful and the problem is directly related to the
established practice on Unixes.

>> But there is another install of thelib on /usr/local, and that install
>> is the one that will be used by our build because we end having this
>> search list:
>> 
>> /usr/local/include /home/oscar/thelib/include
>
> This has nothing to do with the default paths of the compiler, all you
> need to do with this is fix the order of include's of your target or
> source files. You'd run into compile problems (or compiling against the
> wrong lib version) no matter wether cmake searches in /usr/local/include
> for foo.h or not - unless you actually wanted cmake to _not_ find the
> foo.h header at all.
>
> If you want to ensure that /home/oscar/thelib/include is being searched
> before /usr/local/include then use include_directories with its BEFORE
> parameter so it ends up at the front of the list. This is the same thing
> if you'd create the compiler command yourself in a shell.

When there is a series of libraries to be located and the user is
allowed to give a custom location for each of them, that approach is not
easy to implement.

Thanks.



More information about the CMake mailing list