Since I've already started building FLTK 1.4 with CMake on Windows, I thought I'd try to switch to CMake on all platforms.
I was able to switch from autoconf to cmake on Linux without any issues. (And it's a clear improvement over autoconf, btw.)
But on macOS, I am getting a linker error when building my application and linking with FLTK. (Using cmake 3.29.3)
First, this is how I configured FLTK:
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX="$(realpath "$PWD/../..")"
(I clone the fltk repo into the ./lib/fltk/ directory in my application repo, which is why I set the install prefix to "../..", to install fltk into the include/ and lib/ directories at the root of my repo. This works on Linux just fine and so I don't think it is related to the errors that I'm seeing on macOS.)
Then after running the cmake command, I ran make and make install (just like on Linux).
Then when I invoke my own project's Makefile, it fails while linking with the below error messages:
c++ -o bin/crystaltracker tmp/config.o tmp/directory-chooser.o tmp/edit-context-menu.o tmp/help-window.o tmp/hex-spinner.o tmp/it-module.o tmp/main-window.o tmp/main.o tmp/modal-dialog.o tmp/note-properties.o tmp/option-dialogs.o tmp/parse-drumkits.o tmp/parse-song.o tmp/parse-waves.o tmp/piano-roll.o tmp/preferences.o tmp/ruler.o tmp/song.o tmp/themes.o tmp/utils.o tmp/widgets.o tmp/cocoa.o -DNDEBUG -O3 -flto -std=c++17 -Isrc -Ires -I/Users/Daniel/gb/crystal-tracker/include -I/Users/Daniel/gb/crystal-tracker/include/FL/images -I/Users/Daniel/gb/crystal-tracker/include/png -I/Users/Daniel/gb/crystal-tracker/include/zlib -I/Users/Daniel/gb/crystal-tracker/include/jpeg -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT lib/libportaudio.a lib/libportaudiocpp.a lib/libopenmpt.a -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework CoreFoundation -framework CoreServices lib/libfltk_images.a /usr/local/opt/libpng/lib/libpng.a -lz /usr/local/Cellar/jpeg-turbo/2.1.5.1/lib/libjpeg.a /Users/Daniel/gb/crystal-tracker/lib/libfltk.a -lm -lpthread -framework Cocoa -framework UniformTypeIdentifiers
undef: _fltk_png_error
undef: _fltk_png_get_tRNS
undef: _fltk_png_read_info
Sorry for the wall of text, but I figured the full link command and error output would be useful.
I gave a quick read through README.CMake.txt but didn't spot anything obvious that I should be doing differently. (For example, it mentions passing -G Xcode to cmake but my impression is that that is only necessary if I plan on using the XCode IDE, which I do not.)
This is probably simple user-error, but I'm unsure how to fix it so I thought I'd post here in case someone else can spot my mistake.
If there's additional useful information I can provide about how I am building FLTK or my application please let me know. Thanks!
P.S. Not related to the error, but possibly useful context..
I also tried configuring CMake with -D CMAKE_OSX_DEPLOYMENT_TARGET="11.0" which removed some warnings, but didn't change the error during linking.
The warning was:ld: warning: object file (...) was built for newer macOS version (11.4) than being linked (11.0)
It's clear that your build misses the FLTK PNG lib (_fltk_png*) but tries to link the system PNG and JPEG libs instead:> /usr/local/opt/libpng/lib/libpng.a -lz /usr/local/Cellar/jpeg-turbo/2.1.5.1/lib/libjpeg.a
... which provide "the same" symbols (functions) w/o the '_fltk' prefix. We need to find out why your project doesn't "find" the correct ZLIB, PNG, and JPEG libs...
I'm not sure why this happens though.
I may come back to you if I need more info. One quick test would be to include '/path/to/fltk/CMake/fl_debug_var.cmake' in your build and then, after FLTK has been found and configured, execute: 'fl_debug_target(fltk::images)' and 'fl_debug_target(fltk::images-shared)'. The latter may issue "not a target" if you didn't build it but that doesn't matter. Please post the output here.
I believe it would be "interesting" which "object file (...)" is mentioned in the warning message. It may be something of your Homebrew installation ("/usr/local/Cellar/..." in your log above indicates that you have Homebrew installed).
On Sunday, May 12, 2024 at 8:46:03 AM UTC-5 Albrecht-S wrote:It's clear that your build misses the FLTK PNG lib (_fltk_png*) but tries to link the system PNG and JPEG libs instead:> /usr/local/opt/libpng/lib/libpng.a -lz /usr/local/Cellar/jpeg-turbo/2.1.5.1/lib/libjpeg.a
... which provide "the same" symbols (functions) w/o the '_fltk' prefix. We need to find out why your project doesn't "find" the correct ZLIB, PNG, and JPEG libs...
I'm not sure why this happens though.
ISTR when originally setting up my project for Mac and figuring out how to build and link FLTK (1.3.8) with autoconf, I had trouble with libpng, because (modern?) libpng is not a standard library on Mac.However, the output for ./fltk-config --use-images --ldstaticflags is:
./lib/libfltk_images.a -lpng -lz -ljpeg ./lib/libfltk.a -lpthread -framework Cocoa
which failed to build my program due to "-lpng". (Either libpng was missing or unusablely old, I don't remember.)
So I manually installed libpng at /usr/local/opt/libpng/lib, and then I want to link with libpng statically and not dynamically, because I don't want to make my users dependent on a "custom" installation path of libpng (which means that the "-lpng" output of fltk-config is unusable).
To link libpng statically, I remove --use-images from the fltk-config command and specify the linker flags for libpng.a using pkg-config instead. (Then I'm pretty sure the only reason that I link libjpeg in the same way is because removing "-lpng" also removes "-ljpeg" too. libjpeg was not the source of any problems itself that I can recall.)
Just an observation: If I configure CMake with -D FLTK_USE_SYSTEM_LIBPNG=ON, I notice this in the configure output:-- System PNG or ZLIB not usable, falling back to local PNG for compatibility.
but it doesn't elaborate on why it's "not usable".
If I continue with make && make install after the CMake config, that's how I get the linker errors mentioned in the OP when building my application (with my usual Makefile).
But I've just realized that now the output of ./fltk-config --use-images --ldstaticflags is now:
/Users/Daniel/gb/crystal-tracker/lib/libfltk_images.a /Users/Daniel/gb/crystal-tracker/lib/libfltk_jpeg.a /Users/Daniel/gb/crystal-tracker/lib/libfltk_png.a /Users/Daniel/gb/crystal-tracker/lib/libfltk_z.a /Users/Daniel/gb/crystal-tracker/lib/libfltk.a -lm -lpthread -framework Cocoa -framework UniformTypeIdentifiers
Very different than with autoconf! So maybe I don't need my "special handling" for libpng linker flags in my Makefile anymore.. When I add back --use-images to my Makefile, I then have errors with my other main dependency (an audio library) unable to link with zlib functions (the error output even says things like "(maybe you meant: _fltk_z_inflateEnd)").
But after I add "-lz" explicitly in my linker flags, the build is successful.
So it was user-error after all. I think it works well. I'm certainly not going to complain about being able to delete some quirky code from my Makefile.
I would guess that what I should have done at the very beginning was tell autogen.sh to use the bundled libpng somehow and maybe that would have avoided the whole problem.
Thanks for the rubber duck troubleshooting. Writing this out helped.
I may come back to you if I need more info. One quick test would be to include '/path/to/fltk/CMake/fl_debug_var.cmake' in your build and then, after FLTK has been found and configured, execute: 'fl_debug_target(fltk::images)' and 'fl_debug_target(fltk::images-shared)'. The latter may issue "not a target" if you didn't build it but that doesn't matter. Please post the output here.
Sorry, my ignorance of CMake makes it difficult to figure out how to accomplish what you're asking. My project doesn't use CMake, just a (relatively) simple Makefile. Are these commands things that I would add to the FLTK CMake build process?
I believe it would be "interesting" which "object file (...)" is mentioned in the warning message. It may be something of your Homebrew installation ("/usr/local/Cellar/..." in your log above indicates that you have Homebrew installed).
Sorry, I probably shouldn't have omitted the object file. The warning messages refer to libfltk.a and libfltk_images.a, like so:
ld: warning: object file (/Users/Daniel/gb/crystal-tracker/lib/libfltk.a(fl_draw.cxx.o)) was built for newer macOS version (11.4) than being linked (11.0)
ld: warning: object file (/Users/Daniel/gb/crystal-tracker/lib/libfltk.a(fl_contrast.cxx.o)) was built for newer macOS version (11.4) than being linked (11.0)
ld: warning: object file (/Users/Daniel/gb/crystal-tracker/lib/libfltk.a(fl_color.cxx.o)) was built for newer macOS version (11.4) than being linked (11.0)
And so on for each .cxx/.o file.
First I need to say that I misinterpreted your report, I got the impression that you built your own application with CMake as well.
I'm not sure how you can convince the CMake process to find the system libpng. Our CMake code uses 'find_package(PNG)', hence you may need to add its location to CMAKE_PREFIX_PATH or run `cmake` with '-D PNGDIR=...' or something like that.
On Sunday, May 12, 2024 at 7:22:13 PM UTC-5 Albrecht-S wrote:
I'm not sure how you can convince the CMake process to find the system libpng. Our CMake code uses 'find_package(PNG)', hence you may need to add its location to CMAKE_PREFIX_PATH or run `cmake` with '-D PNGDIR=...' or something like that.
For the sake of only linking with one version of zlib, I tried to figure out how to get CMake to use my system libpng. I started testing with CMAKE_PREFIX_PATH but found that that actually isn't necessary. The path to libpng is already configured correctly with pkg-config, which CMake uses.
The issue was that I needed to specify both FLTK_USE_SYSTEM_LIBPNG=ON and FLTK_USE_SYSTEM_ZLIB=ON. I was incorrectly assuming that just FLTK_USE_SYSTEM_LIBPNG would be sufficient in order for options.cmake to at least attempt to use (both) system libraries. Not a big deal.
This was enough to do the whole build without the bundled libraries, but I noticed the cmake configure output said:
PNG = System: /usr/local/opt/libpng/lib/libpng.dylibI thought it was interesting that it mentions libpng.dylib and not libpng.a. (Later when compiling my program I statically link with libpng.a, not dynamically link with libpng.dylib, but I'm not sure if this matters to FLTK at this point.)
Regardless, I'm able to build FLTK and my program like usual.
When I run my program, it immediately logs this:libpng warning: Application built with libpng-1.4.12 but running with 1.6.39
1.6.39 is the version of my system libpng.a (verified with pkg-config --modversion libpng).
I'm not sure where 1.4.12 is coming from. Maybe the version of the .dylib file?
I'll keep looking into this, but thought I'd report on my progress. Thanks.
First of all, you should always keep in mind that CMake caches the results of all find* calls. It's always a good idea to clear the cache, but you can easily forget it - or there is an internal variable you miss - and then you can try whatever you want, you'll always get the same results. Been there, done that...
Unfortunately I had to manually set a lot more CMake variables than I had anticipated, like this screenshot shows:
[...]
When you are satisfied with the result, use a script to run CMake with all these variables as '-D...' on the commandline and you should be able to preset exactly the libs you want, including their include directories. Hopefully.
Another point: I believe that you could try `fltk-config --use-images --ldstaticflags` if you want to use the correct libs from FLTK's build process and link statically. Once you convinced the FLTK build to use the libs you want, this combination (with '--use-images'!) should give you what you need for your project. But this is only the theory, there may be other issues...
Good luck! Feedback welcome.
On Thursday, May 16, 2024 at 3:22:53 PM UTC-5 Albrecht-S wrote:
To avoid any doubt, I've always ran this before every re-configure:rm .gitignore && git clean -df && git reset --hard HEAD
There might be a simpler CMake command for doing the equivalent, but this way I "know" it's done fully and completely.
Unfortunately I had to manually set a lot more CMake variables than I had anticipated, like this screenshot shows:
[...]
When you are satisfied with the result, use a script to run CMake with all these variables as '-D...' on the commandline and you should be able to preset exactly the libs you want, including their include directories. Hopefully.
Thanks for these suggestions.
I was able to resolve all issues with CMake on my mac this way. I ended up with these configuration options:
cmake \
-D CMAKE_INSTALL_PREFIX="$(realpath "$PWD/../..")" \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_OSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -d '.' -f 1).0" \
-D FLTK_USE_SYSTEM_LIBPNG=ON \
-D PNG_PNG_INCLUDE_DIR="$(pkg-config --cflags-only-I libpng | cut -d ' ' -f 1 | cut -c 3-)" \
-D PNG_LIBRARY_RELEASE="$(pkg-config --static --libs-only-L libpng | cut -d ' ' -f 1 | cut -c 3-)/libpng.a" \
-D LIB_png="$(pkg-config --static --libs-only-L libpng | cut -d ' ' -f 1 | cut -c 3-)/libpng.a" \
-D FLTK_USE_SYSTEM_ZLIB=ON \
-D ZLIB_INCLUDE_DIR="$(pkg-config --cflags-only-I zlib | cut -c 3-)" \
-D ZLIB_LIBRARY_RELEASE="$(pkg-config --static --libs-only-L zlib | cut -c 3-)/libz.a" \
-D LIB_zlib="$(pkg-config --static --libs-only-L zlib | cut -c 3-)/libz.a"
Compared to my usual options on Linux:
cmake -D CMAKE_INSTALL_PREFIX="$(realpath "$PWD/../..")" -D CMAKE_BUILD_TYPE=Release
These options allow me to use "system" (homebrew) versions of both libpng and zlib (while still using the bundled libjpeg), with static linking, with only 1 copy of zlib in the executable, and without the "libpng warning: Application built with libpng-1.4.12 but running with 1.6.39" warning that I mentioned previously.
It's a bit ugly, but it allows me to flexibly refer to the lib dirs and include dirs of each library.
Another point: I believe that you could try `fltk-config --use-images --ldstaticflags` if you want to use the correct libs from FLTK's build process and link statically. Once you convinced the FLTK build to use the libs you want, this combination (with '--use-images'!) should give you what you need for your project. But this is only the theory, there may be other issues...
Yes, this is working correctly now. Like mentioned previously in the thread, I've never been able to use --use-images with FLTK 1.3 on Mac because its output would include -lpng.
But with the new cmake configuration options, `fltk-config --use-images --ldstaticflags` now outputs the paths to the .a files that I provided to cmake.
Somewhat related though, I have one concern.
The output of `fltk-config --use-images --cxxflags` includes (among other things):
-I/Users/Daniel/gb/crystal-tracker/include/FL/images
And the ./include/FL/images/ directory contains header files for all 3 libraries: libjpeg, libpng, and zlib.
If I use fltk-config in my Makefile to help control my cxx compiler flags, and fltk-config tells the cxx compiler to include libpng/zlib headers that correspond to the "bundled" libraries, but my project links with the system libpng and zlib libraries, then isn't this another source of unexpected compiler errors?
Should `cmake -D ... && make && make install` copy only the header files for libraries which are actually bundled (libjpeg in my case)?