Thanks a lot, I’ll give it a try!
Your recipe above worked (so far), thanks!
A couple of minor caveats:
-
I had to
add_library()
asSTATIC
rather thanOBJECT
for my JUCE dependencies library: CMake complained about cyclic dependencies. I guess this isn’t a problem though. -
I had to add the
juce::
namespace everywhere (not a problem, just a note for anyone else following this) -
I wasn’t able to use the following:
const juce::String getApplicationName() override
{
return juce::ProjectInfo::projectName;
}
const juce::String getApplicationVersion() override
{
return juce::ProjectInfo::versionString;
}
in my juce::JUCEApplication
; I assume juce::ProjectInfo
is created along with JuceHeader.h
. Not a show-stopper by any means; I can hard-code them for now and worst case, just define these some other way. Would be nice to re-use the JUCE way though.
Following up on this thread @reuk @eyalamir as I am trying to contribute to Eyal’s CMake template, which has every project type except for the library type - as I mostly am making libraries it would be convenient to have a Github template set up with as much of the boiler plate as possible.
I tried the above recommendations, and unfortunately it seems that for me, the call
_juce_initialise_target(${TargetName})
is the single difference between the template building successfully or not. Without this line, there are many errors where juce_core’s .cpp files cannot find their own .h nor other symbols referenced from other headers.
Here’s what I have so far, if anyone can recommend a better way of doing it than this, thanks in advance!
project(LibraryTemplate VERSION 0.0.1)
set (TargetName ${PROJECT_NAME})
add_library(${TargetName} OBJECT)
_juce_initialise_target(${TargetName})
target_link_libraries(${TargetName}
PRIVATE
juce::juce_core
PUBLIC
juce::juce_recommended_config_flags
juce::juce_recommended_warning_flags)
target_compile_definitions(${TargetName}
INTERFACE
$<TARGET_PROPERTY:${TargetName},COMPILE_DEFINITIONS>)
target_include_directories(${TargetName}
INTERFACE
$<TARGET_PROPERTY:${TargetName},INCLUDE_DIRECTORIES>)
set(SOURCES
Source/LibraryAPI.cpp
Source/LibraryImpl.cpp)
target_sources(${TargetName} PRIVATE ${SOURCES})
add_library(${TargetName}_shared SHARED)
add_library(${TargetName}_static STATIC)
target_link_libraries(${TargetName}_shared PUBLIC ${TargetName})
target_link_libraries(${TargetName}_static PUBLIC ${TargetName})
This might be a better reference, I was also trying to determine in what scenarios having both a static library and a consuming CLI app using juce_core would cause problems:
Maybe it was privately linking to juce_core in the static library that allowed things to (seemingly) work alright?
Here is also @eyalamir 's upstream equivalent, i noted he also needed to use the private _juce_initialise_target and so there is perhaps no better way to do this as of yet. (Caveat: I suspected in some projects I worked on that libraries could compile with JUCE without this call, but only if other non-library projects were part of the same larger CMake project and JUCE had the right visibility between parts of the larger project.)
I was also curious about the purpose of
target_compile_definitions(DLL PRIVATE JUCE_STANDALONE_APPLICATION=1)
as I did not need to add it to mine for things to work.
When I remove it and try to build, I get the following warning:
#ifndef JUCE_STANDALONE_APPLICATION
JUCE_COMPILER_WARNING ("Please re-save your project with the latest Projucer version to avoid this warning")
#define JUCE_STANDALONE_APPLICATION 0
#endif
And I like my builds warning-free.