The Linux Page

Failing cmake find_library(), returning just a path instead of the path and library name

Today I spent hours trying to find out why one of my find_library() would fail.

I fixed the search implementation, to make it cleaner as a result, which is not a bad thing, but the problem was a -D on a cmake call that would define the value ahead of time. That is...

There is the search I used:

find_library( ADVGETOPT_LIBRARY advgetopt
            PATHS ${ADVGETOPT_LIBRARY_DIR} ENV ADVGETOPT_LIBRARY
         )

This looks just fine and it should work, easy. I even added a test in my main CMakeLists.txt to see what would happen:

find_library( TEST_LIBRARY advgetopt
            PATHS ENV ADVGETOPT_LIBRARY
         )
message(STATUS "TEST library = [" ${TEST_LIBRARY} "]")

And sure enough, I would get the correct path and filename in my TEST_LIBRARY variable.

So why would the other one fail so badly?!

At some point I thought, I should re-read the documentation, just in case (you know, after hours of search!) and while reading something caught my eye:

Once one of the calls succeeds the result variable will be set and stored in the cache so that no call will search again.

There we go. If the variable is already defined, the call does nothing since the system is considered happy. In other words, if you already defined that parameter, then it won't be necessary to re-define it.

I have a master CMakeLists.txt which calls each sub-directory and has a set of -D definitions that look like this:

ConfigureMakeProject( PROJECT_NAME ve
    COMPONENT non-free
    CONFIG_ARGS
        -DCMAKE_PREFIX_PATH:PATH="${SNAP_DIST_PATH}"
        -DCMAKE_INSTALL_PREFIX:PATH="${SNAP_DIST_PATH}"
        -DADVGETOPT_INCLUDE_DIR:PATH="${SNAP_INCLUDE_DIR}"
        -DADVGETOPT_LIBRARY:PATH="${SNAP_LIBRARY_DIR}"
        ...snip...

Here I should you the one with the incorrect -D. See it?

Yes. I do:

-DADVGETOPT_LIBRARY:PATH="<some path>"

Therefore, the cmake variable ADVGETOPT_LIBRARY is defined by that one line of code. This is added to the cmake cache and as mentioned above, once in the cache, the find_...() commands do nothing.

Once I thought I was on the right track, I tested the variable before call the find_library() and could see that the path was already defined in that variable.

message( STATUS "The ADVGETOPT_LIBRARY var = [" ${ADVGETOPT_LIBRARY} "]")

This message() command would print the path to the library folder, kind of like more or less expected, and  that was definitely wrong.

I'm not 100% sure how I will fix the final version, but for now I added _DIR to the name in the -D definition.

-DADVGETOPT_LIBRARY_DIR:PATH="${SNAP_LIBRARY_DIR}"

And everything started to work as expected.

If you're a beginner and want to learn moreabout cmake, you may want to look into getting a book: Mastering CMake. (Note that I'm an Amazon affiliate and usually make a commission when you make such a purchase which makes me happy and allows me to support my website here.)