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

Michael Ellery mellery451 at gmail.com
Sun Jul 9 10:45:06 EDT 2017


> 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.

If it were up to me, I’d probably choose to not install the newer lib to /usr/local because fighting the compiler regarding system include paths is not fun. If/when I needed the newer version, I’d put it in some non-system path (like /opt) and then tell the compiler to treat that alternate path with top precedence if/when I need to use the newer version. That’s just my 2 cents.

-Mike



More information about the CMake mailing list