c++cmakemakefilestatic-librarieswxwidgets

How do I link to a static library (libtiff) using CMake in my wxWidgets project?


For my wxWidgets project, I am trying to make the switch from my self-written Makefile to Cmake. I develop on macOS.

When I was writing that Makefile I ran into an issue with libtiff. I wanted to statically link my application so that I don't have to distribute any dylibs myself or rely on my users to install them. I built wxWidgets as a static library but when I compiled my code and checked my binary with otool I always found that my binary required a local dylib.

/usr/local/opt/libtiff/lib/libtiff.5.dylib

Finally I found a solution on here. In essence, in the linking line of my Makefile I replaced wx-config –-libs with LDFLAGS. LDFLAGS looks like this:

WXCONFIGLIBS := $(shell wx-config --libs)
WXCONFIGLIBS := $(WXCONFIGLIBS:-ltiff=/usr/local/opt/libtiff//lib/libtiff.a)
# I am not sure whether the double slash is a typo but it works so I don't change it
LDFLAGS := $(WXCONFIGLIBS)

Basically, I search-and-replaced -ltiff with the path to my static libtiff library.

Now I've managed to compile my project using Cmake. However, I'm getting the same warning message as I did when I battled my original issue.

ld: warning: dylib (/usr/local/lib/libtiff.dylib) was built for newer macOS version (11.0) than being linked (10.11)

How do I fix this? My CMakeLists contains these sections pertaining to wxWidgets:

find_package(wxWidgets REQUIRED gl core base OPTIONAL_COMPONENTS net)
include(${wxWidgets_USE_FILE})
...
add_executable(myapp ${SOURCES})
target_link_libraries(myapp ${wxWidgets_LIBRARIES})
set_property(TARGET myapp PROPERTY CXX_STANDARD 17)

I already tried running some search-and-replace shenanigans like

string(REPLACE "-ltiff" "/usr/local/opt/libtiff/lib/libtiff.a" wxWidgets_LIBRARIES ${wxWidgets_LIBRARIES})

But that doesn't work. It does replace -ltiff but also seems to remove the semicolons and whitespaces separating the different libraries.

I've been scouring the web for any clues as to what to do, but I don't seem to have a good enough grasp of libraries to fix this.

Any help would be greatly appreciated.


Solution

  • My search-and-replace idea turned out to be not so bad. I was able to achieve the same outcome with Cmake as with my Makefile.

    My problem was not using double quotes in the appropriate place. So instead of this:

    string(REPLACE "-ltiff" "/usr/local/opt/libtiff/lib/libtiff.a" wxWidgets_LIBRARIES ${wxWidgets_LIBRARIES})
    

    I simply needed to write:

    string(REPLACE "-ltiff" "/usr/local/opt/libtiff/lib/libtiff.a" wxWidgets_LIBRARIES "${wxWidgets_LIBRARIES}")
    

    So to solve my actual problem, I am calling this string() command just before the target_link_libraries() command.


    2024 Update:

    After my original solution stopped working, I came back to this issue and finally found a proper solution. The solution comes from this 2014 blog post on the wxWidgets website.

    This is the relevant quote:

    [...] sometimes you may want to avoid using the system libraries, e.g. because you want to build a statically linked version of your program with as few dependencies as possible. This was always possible by explicitly disabling the use of each and every library with -with-libfoo=builtin, but this was relatively tiresome and it was easy to forget a library or two.

    To remedy this, I’ve just added a new --disable-sys-libs configure option which does exactly what it says: when it is specified on configure command line, only the built-in versions of the third party libraries will be used.

    So the solution is simply to use the option --disable-sys-libs when configuring wxWidgets. No more dependencies on local dylibs.