I want to be able to link statically to a juce project and be able to use all juce functionality (Windows only for now). I created a juce solution changed the target type to static .lib added in the include paths for headers for both modules and route juceLib (copied into project) folder. Hit build and sure enough tons of linker errors so I added the juce project as reference and hitting build starts juce compiling before my main project but I still get one linker error of
|Error|LNK2019|unresolved external symbol āpublic: static int __cdecl juce::JUCEApplicationBase::main(int,char const * * const)ā (?main@JUCEApplicationBase@juce@@SAHHQEAPEBD@Z) referenced in function main|FromScratchCpp|C:\Data\Source\Repos\FromScratchCpp\App\Main.obj|1||
Any ideas on how to resolve. PS below is how Iām trying to setup my project. The reason for this is because itās part of a much broader solution with many projects inside.
// How do I initalize an instance of
// class MyApplication : public juce::JUCEApplication
// in a main function
// e.g.
int main() {
MyApplication app{};
}
Would rather use the START_JUCE_APPLICATION macro for future proofing but for now I would settle knowing the above.
I know this sounds very unintuitive, but JUCE really doesnāt like building as a static library this way. It would only work if the static lib āhidesā JUCE as an implementation detail and just exposes your own headers.
For example in your case, exposing juce::Component to your app means that it would only work if the exact same set of flags are built in both your app and static lib, which means it will probably fail if you try to link more than one app to that static lib.
If you want to share JUCE-based code in multiple projects, I really suggest using JUCE modules. While that means that youāll have to rebuild JUCE for each project, you can also be sure that each project will build JUCE with the right flags and you wonāt encounter any mismatches.
Yeah I fully get if projects are greenfield and Juce is at the top of the stack. But there are a couple of use cases that I have run intoā¦
If you have an existing UI project and you need to add Juce into it for audioā¦
If you have multiple complex solutions that have lets of setup required in IDE the projucer doesnāt cut above a few additional flags and dependancies. Adding files to project becomes a bitch as projucer overwrites solution changes
If say you use something like CUDA and the project files need some extra things in each save to make cuda kernels compile
So having the ability to compartmentalize Juce as a seperate project and link to it can have its advantages. All three above I have run into as problems. Any way my last post gives me a work around for now.
Ps. as a side note I have been dying to try and write a basic RUST lang wrapper for components and audio engineā¦
If itās about the limited capabilities of the Projucer when it comes to set up more complex projects, did you consider moving to CMake? All the use cases you mention can be managed ln a convenient way with CMake.
Iād rather take that route than a static lib that exposes juce classes.
Just as an example, I already used CMake to set up a juce project targeting an FPGA SoC and compiling OpenCL sources for the FPGA along with the project. Or in my current project I compile rust sources in a CMake target that my app depends on. All that would have never been possible with a Projucer based workflow.
Yeah, sounds to me like youāre searching specifically for a CMake approach, where you can build all your shared configuration/source files stuff into an interface target/JUCE module and link against those to avoid repetition when setting up multiple projects that depend on an identical configuration.
The Projucer is indeed very limited when it comes to reusability of configurations.
Yeah so think weāve spoken about embedded systems a while back. Yeah CMake I should imagine would be a good option but my knowledge is limited.
@eyalamir itās not so much about code reuse/repetition and Iām quite comfortable knocking up a few juce modules which I have done for some of my commercial audio projects. But they are just pure Juce projects anyway.
For a real world example we built a game-ified audiometry test for kids in hospital which had an existing c++ Qt application were they wanted integration with. So great juce is a good call to expose audio hardware and we could do alot of the work on unit testing and getting code through EN7XXX and ISO27001 e.t.c. as a medical grade device. So mangling the 2 code bases was fun!..
Fortunitely on that project when I took over as Cheif Eng everything got rewritten in Unity so gave us Juce as a simple option for DSP.
So in CMake hereās a simple way to create a shared ālibraryā for shared configuration (which could be anything, from sources, to compile flags, to the list of JUCE modules to link against):
project(AudioAppTemplate VERSION 0.0.1)
#Shared config stuff, ideally in it's own CMakeLists.txt file so it's shared with many targets
add_library(Shared_Target INTERFACE)
target_sources(Shared_Target INTERFACE
Source/MainComponent.cpp
Source/MainWindow.cpp)
target_compile_definitions(Shared_Target INTERFACE
JUCE_WEB_BROWSER=0
JUCE_USE_CURL=0)
target_link_libraries(Shared_Target INTERFACE
juce_recommended_config_flags
juce_recommended_lto_flags
juce_recommended_warning_flags
juce_gui_basics
shared_processing_code)
#App-specific stuff
juce_add_gui_app(AudioAppTemplate PRODUCT_NAME "Audio App")
target_sources(AudioAppTemplate PRIVATE Source/Main.cpp)
target_link_libraries(AudioAppTemplate PRIVATE Shared_Target)
target_compile_definitions(AudioAppTemplate PRIVATE
JUCE_APPLICATION_NAME_STRING="$<TARGET_PROPERTY:AudioAppTemplate,JUCE_PROJECT_NAME>"
JUCE_APPLICATION_VERSION_STRING="$<TARGET_PROPERTY:AudioAppTemplate,JUCE_VERSION>")