FocusriteGroup / juce-end-to-end

Library to assist with end-to-end testing of JUCE desktop applications
Apache License 2.0
88 stars 10 forks source link

Debug build is not working, usage of JUCE's CMake API seems incorrect #175

Open Barabas5532 opened 1 year ago

Barabas5532 commented 1 year ago

Describe the bug

Doing a basic debug build causes a linker error:

JUCE/modules/juce_core/juce_core.h:384: undefined reference to `juce::this_will_fail_to_link_if_some_of_your_compile_units_are_built_in_release_mode::this_will_fail_to_link_if_some_of_your_compile_units_are_built_in_release_mode()'

JUCE explains why this appears:

 /*
    As the very long class names here try to explain, the purpose of this code is to cause
    a linker error if not all of your compile units are consistent in the options that they
    enable before including JUCE headers. The reason this is important is that if you have
    two cpp files, and one includes the juce headers with debug enabled, and another does so
    without that, then each will be generating code with different class layouts, and you'll
    get subtle and hard-to-track-down memory corruption!
 */

To Reproduce

Steps to reproduce the behavior:

  1. Set up a project using juce-end-to-end or use my project
  2. cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
  3. cmake --build build
  4. See error

Expected behavior

Build completes without error.

Screenshots

If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context

Compare these invocations from the same build in my project:

[1/17] ccache /usr/bin/g++ -DDEBUG -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 -I/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/cmake-build-debug/_deps/juce-end-to-end-src/source/cpp/include -I/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/JUCE/modules -I/modules -g -fdiagnostics-color=always -std=gnu++17 -MD -MT _deps/juce-end-to-end-build/source/cpp/CMakeFiles/focusrite-e2e.dir/source/Command.cpp.o -MF _deps/juce-end-to-end-build/source/cpp/CMakeFiles/focusrite-e2e.dir/source/Command.cpp.o.d -o _deps/juce-end-to-end-build/source/cpp/CMakeFiles/focusrite-e2e.dir/source/Command.cpp.o -c /home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/cmake-build-debug/_deps/juce-end-to-end-src/source/cpp/source/Command.cpp
[13/17] ccache /usr/bin/g++ -DDEBUG=1 -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 -DJUCE_MODULE_AVAILABLE_juce_core=1 -DJUCE_MODULE_AVAILABLE_juce_data_structures=1 -DJUCE_MODULE_AVAILABLE_juce_events=1 -DJUCE_MODULE_AVAILABLE_juce_graphics=1 -DJUCE_MODULE_AVAILABLE_juce_gui_basics=1 -DJUCE_STANDALONE_APPLICATION=1 -DJUCE_STRICT_REFCOUNTEDPOINTER=1 -DJUCE_VST3_CAN_REPLACE_VST2=0 -DLINUX=1 -DPIP_JUCE_EXAMPLES_DIRECTORY_STRING=\"/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/JUCE/examples\" -D_DEBUG=1 -I/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/cmake-build-debug/ChildProcessDemo_artefacts/JuceLibraryCode -I/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host -I/usr/include/webkitgtk-4.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-4 -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/fribidi -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/cloudproviders -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/libsoup-2.4 -I/usr/include/libxml2 -I/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/JUCE/modules -I/home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/cmake-build-debug/_deps/juce-end-to-end-src/source/cpp/include -g -fdiagnostics-color=always -pthread -std=gnu++17 -MD -MT CMakeFiles/ChildProcessDemo.dir/ChildProcessDemo_artefacts/JuceLibraryCode/Main.cpp.o -MF CMakeFiles/ChildProcessDemo.dir/ChildProcessDemo_artefacts/JuceLibraryCode/Main.cpp.o.d -o CMakeFiles/ChildProcessDemo.dir/ChildProcessDemo_artefacts/JuceLibraryCode/Main.cpp.o -c /home/barabas/projects/software/flutter_juce_ipc_plugin/juce_ipc/example/tool/host/cmake-build-debug/ChildProcessDemo_artefacts/JuceLibraryCode/Main.cpp

First one is building a file in this library, the second is building the generated Main.cpp file for my project. There are many extra JUCE compile flags on the second invocation, and we can also see the _DEBUG, which is directly responsible for the failing linker.

There are a few topics on the JUCE forum discussing similar use cases: https://forum.juce.com/t/how-to-create-a-static-library-that-use-juce-in-official-cmake/50080/3. Generally the advice seems to be that the same JUCE flags are required everywhere where a JUCE header gets included.

As far as I understand, the current build setup in this library has a chance to produce errors (linker, compiler or possibly UB) depending on the JUCE flags set by the user project. To fix this, there needs to be a way for the user project to supply the correct JUCE flags to this library. Possibly instead of linking directly to the JUCE modules in https://github.com/FocusriteGroup/juce-end-to-end/blob/51c5200d254df42ab912eb7d3c87ff5c0fcb6d94/source/cpp/CMakeLists.txt#L24-L43, it should link to a user defined target that can have the correct flags.

Barabas5532 commented 1 year ago

This seems to be breaking the build in example/app as well.

I get a linker error again, and the build commands show that JUCE_USE_CURL=0 is not used when building juce_core.cpp, but it is used for some other files.

: && /usr/bin/c++   source/cpp/CMakeFiles/focusrite-e2e-tests.dir/tests/main.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/tests/TestCommand.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/tests/TestComponentSearch.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/tests/TestResponse.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/__/__/_deps/juce-src/modules/juce_core/juce_core.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/__/__/_deps/juce-src/modules/juce_events/juce_events.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/__/__/_deps/juce-src/modules/juce_gui_basics/juce_gui_basics.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/__/__/_deps/juce-src/modules/juce_graphics/juce_graphics.cpp.o source/cpp/CMakeFiles/focusrite-e2e-tests.dir/__/__/_deps/juce-src/modules/juce_data_structures/juce_data_structures.cpp.o -o source/cpp/focusrite-e2e-tests  source/cpp/libfocusrite-e2e.a  /usr/lib/libfreetype.so  -lrt  -ldl  -lpthread && :
/usr/bin/ld: source/cpp/CMakeFiles/focusrite-e2e-tests.dir/__/__/_deps/juce-src/modules/juce_core/juce_core.cpp.o: in function `juce::CURLSymbols::create()':
juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x37): undefined reference to `curl_easy_init'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x4d): undefined reference to `curl_easy_setopt'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x64): undefined reference to `curl_easy_cleanup'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x7b): undefined reference to `curl_easy_getinfo'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x92): undefined reference to `curl_multi_add_handle'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0xa9): undefined reference to `curl_multi_cleanup'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0xc0): undefined reference to `curl_multi_fdset'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0xd7): undefined reference to `curl_multi_info_read'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0xee): undefined reference to `curl_multi_init'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x105): undefined reference to `curl_multi_perform'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x11c): undefined reference to `curl_multi_remove_handle'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x133): undefined reference to `curl_multi_timeout'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x14a): undefined reference to `curl_slist_append'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x161): undefined reference to `curl_slist_free_all'
/usr/bin/ld: juce_core.cpp:(.text._ZN4juce11CURLSymbols6createEv[_ZN4juce11CURLSymbols6createEv]+0x178): undefined reference to `curl_version_info'
collect2: error: ld returned 1 exit status
[29/29] : && /usr/bin/c++   example/app/CMakeFiles/e2e-example-app.dir/source/Main.cpp.o example/app/CMakeFiles/e2e-example-app.dir/__/__/_deps/juce-src/modules/juce_gui_extra/juce_gui_extra.cpp.o example/app/CMakeFiles/e2e-example-app.dir/__/__/_deps/juce-src/modules/juce_gui_basics/juce_gui_basics.cpp.o example/app/CMakeFiles/e2e-example-app.dir/__/__/_deps/juce-src/modules/juce_graphics/juce_graphics.cpp.o example/app/CMakeFiles/e2e-example-app.dir/__/__/_deps/juce-src/modules/juce_events/juce_events.cpp.o example/app/CMakeFiles/e2e-example-app.dir/__/__/_deps/juce-src/modules/juce_core/juce_core.cpp.o example/app/CMakeFiles/e2e-example-app.dir/__/__/_deps/juce-src/modules/juce_data_structures/juce_data_structures.cpp.o -o example/app/e2e-example-app_artefacts/e2e-example-app  source/cpp/libfocusrite-e2e.a  /usr/lib/libfreetype.so  -lrt  -ldl  -lpthread && :
ninja: build stopped: subcommand failed.