wxWidgets / wxWidgets

Cross-Platform C++ GUI Library
https://www.wxwidgets.org/
6.18k stars 1.77k forks source link

wx-config assumes regex and scintilla libraries are shared even if static #18885

Open wxtrac opened 4 years ago

wxtrac commented 4 years ago

Issue migrated from trac ticket # 18885

component: build | priority: normal | keywords: CMake

2020-08-13 14:27:21: hobbes1069 (Richard) created the issue


I am cross compiling from Fedora Linux MinGW for Windows. I'm statically linking in all wxWidgets requirements.

It builds fine but the produced wx-config assumes the regex and scintilla support libraries are shared (-l) even when built statically, causing the FindwxWidgets CMake module to fail.

wxWidgets_LIBRARIES=-L/home/build/build/freedv/external/dist/lib;;;-Wl,--subsystem,windows;-mwindows;/home/build/build/freedv/external/dist/lib/libwx_mswu_aui-3.1-x86_64-w64-mingw32.a;/home/build/build/freedv/external/dist/lib/libwx_baseu_net-3.1-x86_64-w64-mingw32.a;/home/build/build/freedv/external/dist/lib/libwx_mswu_html-3.1-x86_64-w64-mingw32.a;/home/build/build/freedv/external/dist/lib/libwx_mswu_core-3.1-x86_64-w64-mingw32.a;/home/build/build/freedv/external/dist/lib/libwx_baseu-3.1-x86_64-w64-mingw32.a;-L/usr/x86_64-w64-mingw32/sys-root/mingw/lib;-lwxregexu-3.1-x86_64-w64-mingw32;-lwxscintilla-3.1-x86_64-w64-mingw32;-lexpat;-lpng;-ljpeg;-L/usr/x86_64-w64-mingw32/sys-root/mingw/lib;-ltiff;-lz;-lrpcrt4;-loleaut32;-lole32;-luuid;-llzma;-luxtheme;-lwinspool;-lwinmm;-lshell32;-lshlwapi;-lcomctl32;-lcomdlg32;-ladvapi32;-lversion;-lwsock32;-lgdi32;-loleacc
-- /usr/share/cmake/Modules/FindwxWidgets.cmake(171): wxWidgets_LIBRARY_DIRS=/home/build/build/freedv/external/dist/lib;/usr/x86_64-w64-mingw32/sys-root/mingw/lib;/usr/x86_64-w64-mingw32/sys-root/mingw/lib
-- Looking for wxregexu-3.1-x86_64-w64-mingw32
-- Looking for wxscintilla-3.1-x86_64-w64-mingw32
-- Looking for expat
-- Looking for png
-- Looking for jpeg
-- Looking for tiff
-- Looking for z
-- Looking for rpcrt4
-- Looking for oleaut32
-- Looking for ole32
-- Looking for uuid
-- Looking for lzma
-- Looking for uxtheme
-- Looking for winspool
-- Looking for winmm
-- Looking for shell32
-- Looking for shlwapi
-- Looking for comctl32
-- Looking for comdlg32
-- Looking for advapi32
-- Looking for version
-- Looking for wsock32
-- Looking for gdi32
-- Looking for oleacc
CMake Error at /usr/share/cmake/Modules/FindwxWidgets.cmake:960 (message):
  wxWidgets not found due to following missing libraries:
  wxregexu-3.1-x86_64-w64-mingw32 wxscintilla-3.1-x86_64-w64-mingw32
$ ls -1 external/dist/lib/
libportaudio.a
libportaudio.la
libwx_baseu-3.1-x86_64-w64-mingw32.a
libwx_baseu_net-3.1-x86_64-w64-mingw32.a
libwx_baseu_xml-3.1-x86_64-w64-mingw32.a
libwx_mswu_adv-3.1-x86_64-w64-mingw32.a
libwx_mswu_aui-3.1-x86_64-w64-mingw32.a
libwx_mswu_core-3.1-x86_64-w64-mingw32.a
libwx_mswu_gl-3.1-x86_64-w64-mingw32.a
libwx_mswu_html-3.1-x86_64-w64-mingw32.a
libwx_mswu_media-3.1-x86_64-w64-mingw32.a
libwx_mswu_propgrid-3.1-x86_64-w64-mingw32.a
libwx_mswu_qa-3.1-x86_64-w64-mingw32.a
libwx_mswu_ribbon-3.1-x86_64-w64-mingw32.a
libwx_mswu_richtext-3.1-x86_64-w64-mingw32.a
libwx_mswu_stc-3.1-x86_64-w64-mingw32.a
libwx_mswu_webview-3.1-x86_64-w64-mingw32.a
libwx_mswu_xrc-3.1-x86_64-w64-mingw32.a
libwxregexu-3.1-x86_64-w64-mingw32.a
libwxscintilla-3.1-x86_64-w64-mingw32.a
pkgconfig
wx

I tried backing down to 3.0.5 but it still has the same issue with the regex library.

wxtrac commented 4 years ago

2020-08-13 15:25:20: @MaartenBent commented


Hi. I am not familiar with cross-compiling wxWidgets using CMake, so I don't know which search method FindwxWidgets will use in this case (win32 or unix).

If it uses win32 method, I think this is a bug in FindwxWidgets, which is part of CMake.

If it uses unix method, it uses wx-config internally. In this case, could you post the output of wx-config --libs? This way the CMake stuff is filtered out.

wxtrac commented 4 years ago

2020-08-13 15:25:32: @vadz changed status from new to infoneeded_new

2020-08-13 15:25:32: @vadz commented

Sorry, this is not clear at all. -lfoo doesn't assume anything about the library being shared or static and works absolutely fine for both and libwxregexu-3.1-x86_64-w64-mingw32.a should satisfy -lwxregexu-3.1-x86_64-w64-mingw32 requirement on the linker command line.

We need more diagnostics to understand what exactly goes wrong.

wxtrac commented 4 years ago

2020-08-13 16:16:57: hobbes1069 (Richard) changed status from infoneeded_new to new

2020-08-13 16:16:57: hobbes1069 (Richard) commented

It uses unix.

]$ ./wx-config --libs
-L/home/build/build/freedv/external/dist/lib   -Wl,--subsystem,windows -mwindows /home/build/build/freedv/external/dist/lib/libwx_mswu_xrc-3.1-x86_64-w64-mingw32.a /home/build/build/freedv/external/dist/lib/libwx_mswu_qa-3.1-x86_64-w64-mingw32.a /home/build/build/freedv/external/dist/lib/libwx_baseu_net-3.1-x86_64-w64-mingw32.a /home/build/build/freedv/external/dist/lib/libwx_mswu_html-3.1-x86_64-w64-mingw32.a /home/build/build/freedv/external/dist/lib/libwx_mswu_core-3.1-x86_64-w64-mingw32.a /home/build/build/freedv/external/dist/lib/libwx_baseu_xml-3.1-x86_64-w64-mingw32.a /home/build/build/freedv/external/dist/lib/libwx_baseu-3.1-x86_64-w64-mingw32.a -L/usr/x86_64-w64-mingw32/sys-root/mingw/lib -lwxregexu-3.1-x86_64-w64-mingw32 -lwxscintilla-3.1-x86_64-w64-mingw32 -lexpat -lpng -ljpeg -L/usr/x86_64-w64-mingw32/sys-root/mingw/lib -ltiff -lz -lrpcrt4 -loleaut32 -lole32 -luuid -llzma -luxtheme -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lcomdlg32 -ladvapi32 -lversion -lwsock32 -lgdi32 -loleacc

Ok, so I need to dig into why CMake find_library isn't working in this case.

wxtrac commented 4 years ago

2020-08-13 16:19:06: hobbes1069 (Richard) commented


Just noticed something, are -L linker options additive or is it replaced because:

-L/usr/x86_64-w64-mingw32/sys-root/mingw/lib -lwxregexu-3.1-x86_64-w64-mingw32 -lwxscintilla-3.1-x86_64-w64-mingw32

The second -L points to the system directory for MinGW provided windows libraries. Should the wxWidgets libraries come before the -L?

wxtrac commented 4 years ago

2020-08-13 16:38:52: @vadz commented


-L are additive, and while the order matters, it can't explain not finding the library at all.

We really need to have CMake verbose log which shows which commands it tries to run and why do they fail.

wxtrac commented 4 years ago

2020-08-13 16:54:49: hobbes1069 (Richard) commented


Ok, I've never used cmake --debug-find before. I found a problem but need to fix it before I can say things are "fixed"

 find_library considered the following locations:

    /usr/x86_64-w64-mingw32/sys-root/mingw/home/build/build/freedv/external/dist/lib/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/lib/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/lib64/qt-3.3/bin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/share/Modules/bin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/lib64/ccache/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/bin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/bin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/local/sbin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/sbin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/lib/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/usr/x86_64-w64-mingw32/sys-root/mingw/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/lib/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/bin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)
    /usr/x86_64-w64-mingw32/sys-root/mingw/bin/(lib|)wxregexu-3.1-x86_64-w64-mingw32(\.dll|\.dll\.a|\.a|\.lib)

  The item was not found.

It's prepending the system path when it shouldn't be.

wxtrac commented 4 years ago

2020-08-13 20:06:45: @MaartenBent commented


I think I had a similar problem when building for iOS on Travis. I think setting CMAKE_FIND_ROOT_PATH fixed it.

wxtrac commented 4 years ago

2020-08-14 00:54:54: hobbes1069 (Richard) commented


This can be closed. I found out I could append "/" to the CMAKE_FIND_ROOT_PATH so it will effectively treat absolute directories correctly.

wxtrac commented 4 years ago

2020-08-14 00:56:33: hobbes1069 (Richard) commented


@MaartenB

It's already set for Fedora in a toolchain file assuming everything you want is within /usr/x86_64-w64-mingw32/sys-root/mingw but that prevents you from finding things in your local build tree (via External_Project).

wxtrac commented 4 years ago

2020-08-14 10:54:11: @vadz changed component from wxMSW to build

2020-08-14 10:54:11: @vadz commented

It would be nice to have instructions for cross-compiling wx apps using CMake somewhere, especially if it involves doing something non-obvious, such as appending slash to CMAKE_FIND_ROOT_PATH (which is surprising as it seems to work without slash in the example from the comment:7).

wxtrac commented 4 years ago

2020-08-14 11:36:59: @MaartenBent commented


It is not specifically appending a /, but appending a root find path. When cross-compiling, the CMake find functions will search only inside the sysroot of the target (e.g. inside /usr/x86_64-w64-mingw32/sys-root/mingw/ or inside /Applications/Xcode-11.4.1.app/.../iPhoneOS13.4.sdk/). I think to make sure it does't accidentally find libraries of the source system instead of the target system.

In comment:7 the path is set to /usr/local because that is where the cross-compiled libraries are installed. And as you can see in comment:6, find_library checks if there is a lib directory in the root find path (3th from bottom).

In comment:8 the find path is set to /, so it will search for libraries in this directory. It starts in the directories returned by wx-config --libs (first line in comment:6), and will find the libraries there.

At least this is how I understand it. Just some quirks of CMake.

wxtrac commented 4 years ago

2020-08-14 13:28:46: hobbes1069 (Richard) commented


Let me know if there's a better way to do this than abusing the --prefix flag but here's an excerpt from my BuildwxWidgets.cmake for my project:

if(MINGW AND CMAKE_CROSSCOMPILING)
    # If we're cross-compiling then we need to set the target host manually.
    include(cmake/MinGW.cmake)

    # Fedora MinGW defines this to the system MinGW root which will prevent
    # finding libraries in the build tree. Add / so that it also looks in the
    # build tree. This is specifically for bootstrapping wxWidgets.
    list(APPEND CMAKE_FIND_ROOT_PATH "/")

    # If not cross-compiling then use the built-in makefile, otherwise use standard configure.
    set(CONFIGURE_COMMAND ./configure --build=${BUILD} --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)

Obviously this gives me the desired behavior of installing into a subdir of my project binary directory, but also forces me to add "/" to the cmake root path which I don't care for.