[CMake] Tell cmake use /usr/include/db.h, not /usr/local/include/db.h

Larry Hynes larry at larryhynes.com
Sun Jul 9 12:22:20 EDT 2017


Michael Ellery <mellery451 at gmail.com> wrote:

>> On Jul 9, 2017, at 4:16 AM, Larry Hynes <larry at larryhynes.com> wrote:
>> 
>> Hi
>> 
>> I'm building nvi2[0], on (Mac OS X Yosemite (10.10.5)), which uses
>> cmake.
>> 
>> nvi2 depends on a reasonably sane BSD environment, which would
>> include Berkeley DB V1 which is found at /usr/include/db.h.
>> 
>> I also have installed BDB V4, which lives at /usr/local/include/db.h,
>> for use by other programs.
>> 
>> The only way I can get nvi2 to build, is to uninstall BDB V4, in
>> which case cmake picks up V1 and all is well. Otherwise cmake
>> resolutely picks up V4 and the build fails.
>> 
>> I'm trying to figure out if it is possible to tell cmake to use the
>> V1 that is at /usr/include/db.h.
>> 
>> I've tried various invocations of find_path and find_library in
>> CMakeLists.txt, with and without appeals to default paths and such
>> like, to no avail. I've tried any variation of -DCMAKE_XXXFLAGS I
>> can think of, in CMakeLists.txt and on the command line, to no
>> avail. (When using find_XXX, cmake tells me they're found, but still
>> uses DB4. In the case of passing flags, cmake tells me that it
>> is ignoring them.)
>> 
>> Now, at day's end, this is not A Big Deal; I uninstall BDB4, build
>> nvi2, reinstall BDB4. But one would imagine that there is some
>> (simple) way to instruct cmake to use X over Y when building Z?
>> 
>> [0] https://github.com/lichray/nvi2
>> 
> system include order path is implementation defined, but it sounds
> to me like your compiler (clang) is behaving in a fairly normal way
> - that is, it checks /usr/local/include before /usr/include, which
> allows you to have newer versions of libs in local. This has nothing
> to do with CMake - this is standard compiler behavior. So, now it
> sounds like you want to change that default behavior for this target.
> If you can figure out the right set of flags to pass to clang to get
> it to find the right header, then it’s possible to convince CMake to
> pass those flags using something like target_compile_options().
>
> The CMake find_path and find_library functions don’t do anything
> magical…they just simplify the process of searching various locations
> on your filesystem for the specified files, and conveniently
> find_library knows about library file naming convention. When those
> functions are used, they just end-up setting some variables to tell
> you what it found and where, but they don’t do anything special with
> compiler flags. It’s up to you to take the results (variables) of
> those functions and pass them along to your compiler/toolchain as you
> see fit.
>
> So that’s the challenge here - figure out how to convince your
> compiler to ignore /usr/local/include, at least of this one
> dependency. If you have other things in /usr/local/include that you
> depend on, then this might be very tricky. It looks like the -include
> option to clang might allow you to specify a full path to a file to
> include before preprocessing, but that might also require that you
> remove all #include <db.h> from your sources - I don’t know if that’s
> feasible.

Thanks Mike - you gave me an idea here, and it works. Turns out
<db.h> is only included from one file - common/common.h - and
changing it to '#include "/usr/include/db.h"' does the trick. Yes,
it's a little hacky and amateurish and will probably anger the Gods,
but it takes less time than the uninstall / reinstall dance, so
we'll call it a victory.



More information about the CMake mailing list