juce-framework / JUCE

JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, LV2 and AAX audio plug-ins.
https://juce.com
Other
6.59k stars 1.74k forks source link

JUCE module precompiled binaries are not resolved #629

Open atsushieno opened 4 years ago

atsushieno commented 4 years ago

module-libs-issue.zip JUCE_Module_Format.txt says it supports precompiled binaries:

Precompiled libraries
---------------------

Precompiled libraries can be included in a module by placing them in a libs/ subdirectory.
The following directories are automatically added to the library search paths, and libraries
placed in these directories can be linked with projects via the OSXLibs, iOSLibs,
windowsLibs, linuxLibs and mingwLibs keywords in the module declaration (see the following
section).
Linux:
    libs/Linux/{arch}, where {arch} is the architecture you are targeting with the compiler. Some
    common examples of {arch} are "x86_64", "i386" and "armv6".

However this did not work for Linux. The attached project contains foo module under modules directory, and the project .jucer specifies this module. The module contains references libfoo.a, but unlike typical(?) JUCE modules it does not include foo.c in the module sources. Instead, foo.c is compiled apart from JUCE app build (clang -c foo.c -o foo.o; ar rcs libfoo.a foo.o) and copied into modules/foo/libs/Linux/x86_64. And foo.h in the module header it has linuxLibs foo so it should resolve libfoo.a. What happens?

/usr/bin/ld: build/intermediate/Debug/MainComponent_a6ffb4a5.o: in function `MainComponent::MainComponent()':
/home/atsushi/Desktop/NewProject/Builds/LinuxMakefile/../../Source/MainComponent.cpp:14: undefined reference to `x()'

So this does not seem to work.

atsushieno commented 4 years ago

Is there any single example in the world that actually makes use of this feature? I couldn't find any.

McMartin commented 4 years ago

The first issue I can see is that there is a typo in foo.h. There is a colon character missing after the linuxLibs key:

--- a/modules/foo/foo.h
+++ b/modules/foo/foo.h
@@ -14,7 +14,7 @@
   description:      libfoo
   website:          https://github.com/atsushieno/
   license:          MIT
-  linuxLibs         foo
+  linuxLibs:        foo

  END_JUCE_MODULE_DECLARATION
atsushieno commented 4 years ago

oops, true. That makes some difference:

make: Entering directory '/home/atsushi/Desktop/NewProject/Builds/LinuxMakefile'
Linking NewProject - App
/usr/bin/ld: cannot find -lfoo
McMartin commented 4 years ago

Now you should have a look at NewProject/Builds/LinuxMakefile, find the line where -lfoo is written, and see where it is searched for (-L is the flag for library search path).

atsushieno commented 4 years ago
  JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L../../modules/foo/libs/Linux/native $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -fvisibility=hidden -lfoo -lrt -ldl -lpthread -lGL $(LDFLAGS)

Now you see where the bug lies.

McMartin commented 4 years ago

I wouldn't call that a bug. I would call that "undocumented behavior" or "misaligned expectations".

Projucer uses this function to decide what {arch} is https://github.com/WeAreROLI/JUCE/blob/724ae27c71ef809b836df06713cf9e50bc14162b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h#L57-L74 and by default Projucer sets architectureTypeValue to -march=native: https://github.com/WeAreROLI/JUCE/blob/724ae27c71ef809b836df06713cf9e50bc14162b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h#L40

This is why the line where you found -lfoo contains -L../../modules/foo/libs/Linux/native.

atsushieno commented 4 years ago

If there is something that needs fix, especially in code, that's a bug. As I described on this issue at first, native is not listed on JUCE_Module_Format.txt. And all other CPU archs have particular ABI name. There is no technical advantage nor consistency of accepting the value "native" at all.

jony543 commented 1 year ago

I'm getting the same error on Linux with a different module that uses a precompiled library (this one). I tried renaming the folder from Linux/x86_64 to Linux/native but still linking fails to find the library. Is there any update on this on new versions of Juce since 2019?