Building a Windows application for Console subsystem


#1

I have noticed that JUCE doesn't support building for the Console subsystem by default anymore. Is that an intentional change?

Our product can be built in a few different ways, one way is the usual way with GUI, but another way is as a command line application. It still runs the event loop for timers and such, but it needs to work as a console application (i.e. it displays stdout and stderr on the console and it usually doesn't display a GUI).

The reason why it doesn't build is that if you build a console application, the linker expects int main(int, char**) rather than WinMain(....) as your entry point (as on the UNIX platforms).

I got it working by changing the preprocessor checks in juce_Initialisation.h:95 and juce_ApplicationBase.cpp:141 to check if _CONSOLE is not defined:

 #if JUCE_WINDOWS && !defined(_CONSOLE)

and to add

#ifdef _CONSOLE
const char* const* juce_argv = nullptr;
int juce_argc = 0;
#endif

somewhere in the native windows code (I put it in juce_win32_Files.cpp for consistency).

--
Roeland


#2

Have a look here: http://www.juce.com/forum/topic/basic-command-line-app-testing

[Haven't checked it on the *very* latest Introjuce, but OK last week]


#3

Yes - I was under the impression that this was already working fine without any changes needed?


#4

It will work if we write the main() function ourself for the console builds, and use the START_JUCE_APPLICATION for the other builds, but I thought it'd be nice if the START_JUCE_APPLICATION macro also works in console builds.

--
Roeland


#5

In that case, how is what you're doing different from just writing a normal app and invoking it from the command line?


#6

We have

// This macro creates the application's main() function..
START_JUCE_APPLICATION(OurJuceApp)

in our main.cpp file, rather than

int main(int argc, char *argv[])
{
    // code goes here....
}

The former will always generate a WinMain() function on Windows, even if building for the console subsystem.

I saw the Introjucer will just put the latter into your main.cpp file if you generate a console app, which will build correctly. But it won't work on Windows if you make a build for the Windows subsystem.

I guess since we make builds for both the console and windows subsystems from the same source tree, we are a bit of a corner case here.

--
Roeland


#7

Sorry, my question wasn't very clear - I meant: if you need an event loop, then what exactly is wrong with just building a normal Windows app and then invoking it from the command-line? I do that all the time (e.g. the introjucer itself can be run as a command-line app with arguments) and AFAIK the only difference is that you write your main function differently.


#8

Sorry, to jump into the discussion, but I wrote that particular mode. The reason why we want to use the CONSOLE sub-system is because it is supposed to behave like a terminal application. I.e. if you start it from the command line, it will block the command line and key presses can be read via stdin/cin and stdout/stderr/cout/cerr go to the terminal. It also allows us to hook up sigints to catch the CTRL-C event etc.. All these things are not possible in the normal WINDOWS sub-system.

I hope that explains it.

Cheers,

Marcus


#9

Gotcha.

Ok, well I've no objections to making it handle the _CONSOLE flag as described in the original post. I'll make those changes shortly - let me know if it's enough to get you running!


#10

Not yet, you also need to change the START_JUCE_APPLICATION macro in juce_Initialisation.h (line 95). After that change it will work.

--
Roeland


#11

Ah yes, missed that one.. Done now, thanks!


#12

A bit late to the party, but I need to have a console in my Windows code as well. Using the _CONSOLE preprocessor flag works, but only if I also change the linker SubSystem to Console in the Visual Studio project. This adds

<SubSystem>Console</SubSystem>

to the *.vcxproj file for the selected build. This change is overwritten by Introjucer, however, so my question is: is there a way to add this to the Introjucer? If so, where and how? If not, what is the best workaround?


#13

I believe I did this by adding the text below in the [size=16]Extra linker flags[/size] section of the Visual Studio configuration.

[font=Consolas][size=20]/SUBSYSTEM:CONSOLE [/size][/font]

#14

The introjucer will set this stuff for you if you set your project type to "Application (Non-GUI)"


#15

Cool, setting it in the Introjucer works fine. Missed that one.