Multi-target project exporters

Similarly to Projucer’s Xcode exporter, JUCE will now create multi-target IDE projects on all platforms. This means that each plug-in format is now individually linked and that they only include the code that is needed for that plug-in format.

Multi-target support is needed to support modern plug-in formats which often run sandboxed and need special linker flags (such as AudioUnitv3 or the new “Standalone” target). It also results in slightly smaller binaries in release mode as code for other plug-in formats are not included in your binary.

This feature required some extensive changes at the very heart of JUCE: the Projucer. Although we have extensively tested this feature internally, there are likely to be bugs (see known issues below) or use cases that we didn’t think about. Please give us as much feedback as possible (good and bad!).

Below are some more details on multi-target support for individual IDEs:

  • Visual Studio Multi-target support in Visual Studio is implemented by adding multiple projects per solution. There are several known issues with this approach
    1. When opening a new solution in Visual Studio that you have never opened before, Visual Studio will ask you to confirm loading every contained project. Unfortunately, once this has happened, Visual Studio will never ask you to confirm projects again - even if projects get added to the solution from outside Visual Studio. Visual Studio will silently reject loading projects it hadn’t seen in the solution before. For JUCE users this means, that if you open multi-target solution, that you had already opened sometime in the past, Visual Studio will reject loading the new targets. You will get something that looks like this:

      A workaround is to right-click the project and select “Reload Project”:
    2. To assist browsing the source-code of the various targets, JUCE adds all source code files at the solution level. Unfortunately, Visual Studio will expand the entire source tree when opening the solution for the first time. However, if you choose to close the source tree sub-groups then Visual Studio will remember this setting.
  • Linux Makefile Multi-target support in makefiles is implemented with phony targets. Simply type-in “make VST” to build only the VST target. A convenience target “all” is included in the Makefile and is the default target if you do not specify any on the command line
  • Codeblocks (Linux and Windows) Codeblocks does not have any distinction between build configuration and project targets. Therefore, Codeblocks will include both a release and debug version of every target. Aggregate targets “Debug” and “Release” are automatically added to Codeblocks targets to facilitate building all of the targets in debug or release mode respectively.
  • Android Studio Currently, only the “Standalone” plugin format is supported in Android. As a consequence, there is only ever a single target for any Android JUCE project.

Fantastic glad to see this implemented, we have been waiting for this for quite some time. I’m sure we will be getting our hands dirty with this on some pretty big projects in the coming weeks.

I’m not going to lie, while it may not seem like a big deal on paper the whole “VS solution folders all start out open” is super annoying. By “known issues” do you mean “going to fix by full release”?

What I meant to say in my withdrawn post above (which I canceled because I felt it did break the forum policy of not speaking in a manner that would be inappropriate in person) is this:

The need of Projucer to generate multiple projects in Visual Studio seems to me like a way to mimic the behavior of Xcode, where you can set a target to be built as a dependency of another target. This is not possible in Visual Studio, where this build dependency can only exist between projects.

Given that limitation, I wonder if it wouldn’t be better for Projucer to generate a Solution with a more conventional structure:

  1. One Project to build the whole codebase of JUCE, to be reused by each plug-in format. Such project would be roughly equivalent to the one labeled “Shared Code” of this new structure committed yesterday.

  2. Another project containing the actual plug-in sources. This project would need as many targets as many formats it needs to generate (for example AAX, VST2, Stand-alone, possibly duplicated to have a Release and a Debug target for each format).

This reduces the number of needed projects in the solution from “one per format, plus a ‘Shared’ one”, to “always two”.

Also, if you look at it, you can recognize that as a conventional design: name the project #1 “JUCE” and build an actual library out of it (I mean an actual .lib file), and then use that as a dependency to be linked by the project #2 that builds the actual plug-in (and that should named after it).

That is exactly how JUCE was built back in the days of ver. 1.xx.
I’m not a particular fan of that method, and I am sure Jules is neither, but I should objectively admit that it looks better than a proliferation of Projects in the Solution.

Also, please consider that so many of the configuration issues that made building the JUCE.lib file a complicated thing back in the days (and that probably contributed to the frustration of Jules, in the form of users requesting how to do it and having problems with it), would now be made a lot easier by mean of the Projucer.

Not a bug, but i don’t like that the new VisualStudio exporters creates paths with spaces inside

“Builds/VisualStudio2015/MyPlugin - Shared Code.vcxproj”

1 Like

Yeah, agreed. Had to go and quote all my post-build ops as they all suddently started getting spaces in the paths…

@fabian
what do you think about changing the filename scheme?

“Builds/VisualStudio2015/MyPlugin - Shared Code.vcxproj”

-> “Builds/VisualStudio2015/MyPlugin_Shared_Code.vcxproj”

(its just feels more comfortable, in a unix/scripting environment)

OK I’ve just pushed a fix for this. It will appear on develop in a few minutes.

1 Like

What can i do to run my pre-build script only one time per solution for the SharedCode project ?

On XCode i used the “if [[ $TARGET_NAME == “Shared Code” ]]; then” trick, if there is something similar for Visual Studio?

This is what I’ve worked out so far. I have the following saved in a xxx.bat file:

rem %1 is $(ProjectName)
rem %2 is $(OutDir)$(TargetFileName)
set projectname=%1
set binaryfile=%2

echo %projectname%|findstr /C:"(VST)" >nul 2>&1
IF %errorlevel% EQU 0 (
  echo "Do something with VST"
)

echo %projectname%|findstr /C:"(VST3)" >nul 2>&1
IF %errorlevel% EQU 0 (
  echo "Do something with VST3"
)

echo %projectname%|findstr /C:"(AAX)" >nul 2>&1
IF %errorlevel% EQU 0 (
  echo "Do something with AAX"
)

verify >nul

Then in the Post-build Command field in the Projucer, I have this:
call "path\to\xxx.bat" "$(ProjectName)" "$(OutDir)$(TargetFileName)"

(EDITED: to use verify >nul to reset %errorlevel% since exit 0 prevents any subsequent post-build events from running, which essentially breaks AAX builds!)

2 Likes

I did something similar to this part for many years, but over time my post-build script grew in complexity and so did the number of arguments to it, so much that it became a pain to keep track of them.

To resolve that problem, I resorted to setting appropriate environment vars (with self-explaining names) prior to the "call " statement in the post-build phase of Visual Studio.

Basically, you could simply SET PROJECT_NAME to the same value that’s in $(ProjectName) for Visual Studio, and then use it as %PROJECT_NAME% in your post-build xxx.bat file. And obviously the same is true for the other vars as well. That makes it a much more maintainable script for me.

Bonus content: to retain spaces without adding “” in the var values when using SET, use:

SET "projectname=%1"

This will set projectname to the exact same value as %1, even when it contains spaces.

It is different from the outcome of

SET projectname="%1"

because in that case the double quotes will be found inside the value of projectname, making it tricky if you want to concatenate in a longer var multiple values that are already quoted that same way.

4 Likes

Another new problem with the multi-target exporters on VS, it seems the VS2015 quick-refactoring functions “move definition location” does not work, IMHO because the source-files are not directly added to a project.

“… failed because the file is not in the current project”

EDIT:
I have to correct myself, it seems that the reason for this behavior is maybe something different, because it is working with a few files.

I wish, there would be second kind of exporter format, just a project and a solution for every output format.
Somehow i get consistent issues errors, with the shared solution based source files.
I just switched to using Visual Studio because it much more productive especially for C++.

1 Like

+1. I get annoying issues with Intellisense. It seems to get confused by the new structure and sometimes it’ll just not find symbols and that is a bad productivity killer (F12 saves me a lot of searching and browsing every day). One of the reasons I started preferring Visual Studio over XCode was that I was seeing similar problems there… where XCode wouldn’t find definitions or Juce symbols. Seems now both IDEs struggle in a similar way with the JUCE project/solution structure.

2 Likes

I’ve noticed since moving to VS 2017 that the intellisense auto-complete doesn’t seem to function with Juce. Anyone else finding that? Any solutions?

Edit: Should have googled a bit more before posting… There is a new predictive intellisense feature in 2017 which I’ve disabled now and I can see the juce classes appear as before.

I also get “file is already open in another project” and don’t quite know why. Do you get this too? Has anyone found a fix for that as well?

2 Likes

I get this too.
20 characters

Not getting that particular issue.

A smaller note, does anyone else notice that the Standalone Plugin project takes a long time to build/link in comparison to the other projects?

If i now edit files, and i think this is somehow related to the “file is already open in another project”-problem, the changes will not affect into other plugin format projects. So i have different versions of the same-files in one solution. This is highly confusing. We need a single Solution for every Plugin Export Format.

Now i get awkward messages like

A copy of myfile.h was found in
c:\etc\etc\myfile.h,
but the current source code is different from the version built into
c:\etc\etc\myfile.h,

Please help, the generated VS Projects are not unusable.