Skip to content

Commit

Permalink
ENH: Build SlicerApp-real.exe as a console application to enable cons…
Browse files Browse the repository at this point in the history
…ole output

If SlicerApp-real.exe is built as a console application then it is possible to capture and redirect its output (to files, display, any other software), and test outputs also become visible on dashboard builds.

If the launcher is still built as a Windows GUI application then no command console is displayed when Slicer is started.

Added instructions (in Docs\developer_guide\debugging\overview.md) for accessing the console output when launcher is a Windows GUI application.

re #2934
  • Loading branch information
lassoan committed Sep 10, 2021
1 parent 0adca4c commit 2d7cb88
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Base/QTCore/qSlicerCoreCommandOptions.h
Expand Up @@ -25,7 +25,7 @@
#include <ctkCommandLineParser.h>

#include "qSlicerBaseQTCoreExport.h"
#include "vtkSlicerConfigure.h" // For Slicer_USE_PYTHONQT, Slicer_BUILD_WIN32_CONSOLE
#include "vtkSlicerConfigure.h" // For Slicer_USE_PYTHONQT

class QSettings;
class qSlicerCoreCommandOptionsPrivate;
Expand Down
5 changes: 4 additions & 1 deletion CMake/SlicerApplicationOptions.cmake
Expand Up @@ -44,11 +44,14 @@ endforeach()
# Terminal support
#-----------------------------------------------------------------------------
if(WIN32)
option(Slicer_BUILD_WIN32_CONSOLE "Build ${PROJECT_NAME} executable as a console app on windows (allows debug output)" ON)
option(Slicer_BUILD_WIN32_CONSOLE "Build ${PROJECT_NAME} executable as a console app on windows (allows capturing console output)" ON)
option(Slicer_BUILD_WIN32_CONSOLE_LAUNCHER "Build ${PROJECT_NAME} launcher executable as a console app on windows (displays console at application start)" ON)
else()
set(Slicer_BUILD_WIN32_CONSOLE OFF)
set(Slicer_BUILD_WIN32_CONSOLE_LAUNCHER OFF)
endif()
mark_as_superbuild(Slicer_BUILD_WIN32_CONSOLE:BOOL)
mark_as_superbuild(Slicer_BUILD_WIN32_CONSOLE_LAUNCHER:BOOL)

#-----------------------------------------------------------------------------
# Organization name
Expand Down
20 changes: 16 additions & 4 deletions CMake/SlicerDashboardDriverScript.cmake
Expand Up @@ -59,14 +59,21 @@ else()
endif()

if(WIN32)
# By default, build a console application so that console output can be capture
# by the launcher; but make the launcher a non-console application application
# when creating packages to avoid popping up a console window when running Slicer.
if(NOT DEFINED Slicer_BUILD_WIN32_CONSOLE)
set(Slicer_BUILD_WIN32_CONSOLE ON)
endif()
list(APPEND expected_variables Slicer_BUILD_WIN32_CONSOLE)
if(NOT DEFINED Slicer_BUILD_WIN32_CONSOLE_LAUNCHER)
if(WITH_PACKAGES)
set(Slicer_BUILD_WIN32_CONSOLE OFF)
set(Slicer_BUILD_WIN32_CONSOLE_LAUNCHER OFF)
else()
set(Slicer_BUILD_WIN32_CONSOLE ON)
set(Slicer_BUILD_WIN32_CONSOLE_LAUNCHER ON)
endif()
endif()
list(APPEND expected_variables Slicer_BUILD_WIN32_CONSOLE)
list(APPEND expected_variables Slicer_BUILD_WIN32_CONSOLE_LAUNCHER)
endif()

if(NOT DEFINED Slicer_USE_VTK_DEBUG_LEAKS)
Expand Down Expand Up @@ -104,7 +111,7 @@ if(NOT DEFINED CTEST_BUILD_NAME)
set(name "${name}-NoCLI")
endif()
if(WIN32)
if(NOT Slicer_BUILD_WIN32_CONSOLE)
if(NOT Slicer_BUILD_WIN32_CONSOLE_LAUNCHER)
set(name "${name}-NoConsole")
endif()
endif()
Expand Down Expand Up @@ -467,6 +474,11 @@ CMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}")
Slicer_BUILD_WIN32_CONSOLE:BOOL=${Slicer_BUILD_WIN32_CONSOLE}")
endif()

if(DEFINED Slicer_BUILD_WIN32_CONSOLE_LAUNCHER)
set(OPTIONAL_CACHE_CONTENT "${OPTIONAL_CACHE_CONTENT}
Slicer_BUILD_WIN32_CONSOLE_LAUNCHER:BOOL=${Slicer_BUILD_WIN32_CONSOLE_LAUNCHER}")
endif()

if(DEFINED Slicer_USE_PYTHONQT)
set(OPTIONAL_CACHE_CONTENT "${OPTIONAL_CACHE_CONTENT}
Slicer_USE_PYTHONQT:BOOL=${Slicer_USE_PYTHONQT}")
Expand Down
8 changes: 5 additions & 3 deletions CMake/SlicerMacroBuildApplication.cmake
Expand Up @@ -405,14 +405,16 @@ macro(slicerMacroBuildApplication)
# --------------------------------------------------------------------------
# Build the executable
# --------------------------------------------------------------------------
set(Slicer_HAS_CONSOLE_IO_SUPPORT TRUE)
set(Slicer_HAS_CONSOLE_IO_SUPPORT TRUE) # SlicerApp-real is a console application
set(Slicer_HAS_CONSOLE_LAUNCHER TRUE) # Slicer launcher is a console application
if(WIN32)
set(Slicer_HAS_CONSOLE_IO_SUPPORT ${Slicer_BUILD_WIN32_CONSOLE})
set(Slicer_HAS_CONSOLE_LAUNCHER ${Slicer_BUILD_WIN32_CONSOLE_LAUNCHER})
endif()

set(SLICERAPP_EXE_OPTIONS)
if(WIN32)
if(NOT Slicer_HAS_CONSOLE_IO_SUPPORT)
if(NOT Slicer_HAS_CONSOLE_LAUNCHER)
set(SLICERAPP_EXE_OPTIONS WIN32)
endif()
endif()
Expand Down Expand Up @@ -677,7 +679,7 @@ macro(slicerMacroBuildApplication)
set_target_properties(${SLICERAPP_APPLICATION_NAME}ConfigureLauncher PROPERTIES FOLDER ${SLICERAPP_FOLDER})

if(NOT APPLE)
if(Slicer_HAS_CONSOLE_IO_SUPPORT)
if(Slicer_HAS_CONSOLE_LAUNCHER)
install(
PROGRAMS "${Slicer_BINARY_DIR}/${SLICERAPP_APPLICATION_NAME}${CMAKE_EXECUTABLE_SUFFIX}"
DESTINATION "."
Expand Down
1 change: 1 addition & 0 deletions CMake/vtkSlicerConfigure.h.in
Expand Up @@ -47,6 +47,7 @@

#define VTKSLICER_CONFIGURATION_TYPES "@CMAKE_CONFIGURATION_TYPES@"
#cmakedefine Slicer_BUILD_WIN32_CONSOLE
#cmakedefine Slicer_BUILD_WIN32_CONSOLE_LAUNCHER

#define Slicer_MAIN_PROJECT_APPLICATION_NAME "@Slicer_MAIN_PROJECT_APPLICATION_NAME@"
#define Slicer_BIN_DIR "@Slicer_BIN_DIR@"
Expand Down
27 changes: 23 additions & 4 deletions Docs/developer_guide/debugging/overview.md
Expand Up @@ -369,9 +369,28 @@ It may help pinpointing issues if Slicer is started with as few features as poss

## Console output on Windows

On Windows, the application is built with no console output. A workaround for this issue is described in the following bug reports:
On Windows, by default the application launcher is built as a Windows GUI application (as opposed to a console application) to avoid opening a console window when starting the application.

- <https://github.com/Slicer/Slicer/issues/2376>
- <https://github.com/Slicer/Slicer/issues/2917>
If the launcher is a Windows GUI application, it is still possible to show the console output by using one of these options:

To add console output, you need to compile Slicer application with `Slicer_BUILD_WIN32_CONSOLE` set to ON at the configure time (uninitialized/OFF by default).
Option A. Run the application with capturing and displaying the output using the `more` command (this captures the output of both the launcher and the launched application):

```shell
Slicer.exe --help 2>&1 | more
```

The `2>&1` argument redirects the error output to the standard output, making error messages visible on the console, too.

Option B. Instead of `more` command (that requires pressing space key after the console window is full), `tee` command can be used (that continuously displays the output on screen and also writes it to a file). Unfortunately, `tee` is not a standard command on Windows, therefore either a third-party implementation can be used (such as [`wtee`](https://github.com/gvalkov/wtee/releases/tag/v1.0.1)) or the built-in `tee` command in Windows powershell:

```shell
powershell ".\Slicer.exe 2>&1 | tee out.txt"
```

Option C. Run the application with a new console (the launcher sets up the environment, creates a new console, and starts the SlicerApp-real executable directly, which can access this console):

```shell
Slicer.exe --launch %comspec% /c start SlicerApp-real.exe
```

To add console output permanently, the application launcher can be switched to a console application by setting `Slicer_BUILD_WIN32_CONSOLE_LAUNCHER` CMake variable to ON when configuring the application build.

0 comments on commit 2d7cb88

Please sign in to comment.