0

I have a cmake project with qml (qt) as gui and itk and opencv for image processing tasks. The program runs fine from visual studio, but i need to deploy it as exe for others, that want to use it.

+---build
|   |   ALL_BUILD.vcxproj
|   |   ...
|   |   INSTALL.vcxproj
|   |   INSTALL.vcxproj.filters
|   |   ...
|   |   Qt dlls
|   |   ...
|   |   VisuRysm.sln
|   |   
|   +---cmake
|   |       
|   +---CMakeFiles
|   |           
|   +---Contents
|   |   \---Resources
|   +---Debug
|   +---ITKIOFactoryRegistration
|   |       itkImageIOFactoryRegisterManager.h
|   |       itkTransformIOFactoryRegisterManager.h
|   |       
|   +---VisuRysm.dir
|   |   \---Debug
|   |       |   App.obj
|   |       |   AppConfig.obj
|   |       |   AppController.obj
|   |       |   AppWindow.obj
|   |       |   Image.obj
|   |       |   ImageProvider.obj
|   |       |   main.obj
|   |       |   vc120.pdb
|   |       |   VideoService.obj
|   |       |   VisuRysm.log
|   |       |   VisuRysm_automoc.obj
|   |       |   ZProjectionService.obj
|   |       |   
|   |       \---VisuRysm.tlog
|   |               
|   +---VisuRysm_automoc.dir
|   |       
|   \---x64
|       \---Debug
|           +---ALL_BUILD
|           |   |   ALL_BUILD.log
|           |   |   
|           |   \---ALL_BUILD.tlog
|           |           
|           +---INSTALL
|           |   |   INSTALL.log
|           |   |   
|           |   \---INSTALL.tlog
|           |           
|           \---ZERO_CHECK
|               |   ZERO_CHECK.log
|               |   
|               \---ZERO_CHECK.tlog
|                       
\---source
    |   CMakeLists.txt
    |   
    +---build
    |   |   ITKIOBioRad-4.6.dll
    |   |   ITKIOBMP-4.6.dll
    |   |   ITKIOGIPL-4.6.dll
    |   |   ITKIOHDF5-4.6.dll
    |   |   QT5Concurrent.dll
    |   |   QT5Concurrentd.dll
    |   |   Qt5Core.dll
    |   |   Qt5Cored.dll
    |   |   Qt5Gui.dll
    |   |   Qt5Guid.dll
    |   |   QT5Network.dll
    |   |   QT5Networkd.dll
    |   |   Qt5PrintSupport.dll
    |   |   Qt5PrintSupportd.dll
    |   |   Qt5Qml.dll
    |   |   Qt5Qmld.dll
    |   |   Qt5Quick.dll
    |   |   Qt5Quickd.dll
    |   |   Qt5Widgets.dll
    |   |   Qt5Widgetsd.dll
    |   |   VisuRysm.exe
    |   |   VisuRysm.exp
    |   |   VisuRysm.ilk
    |   |   VisuRysm.lib
    |   |   VisuRysm.pdb
    |   |   
    |   \---Contents
    |       \---Resources
    |           +---fonts
    |           |   +---font-awesome
    |           |   |       fontawesome-webfont.ttf
    |           |   |       
    |           |   \---roboto
    |           |           
    |           +---icons
    |           |   |   VisuRysm.icns
    |           |   |   
    |           |   +---develop
    |           |   |       Icon.icns
    |           |   |       VisuRysm.icns
    |           |   |       
    |           |   \---release
    |           |           Icon.icns
    |           |           VisuRysm.icns
    |           |           
    |           \---qml
    |               +---App
    |               |       Magic.qml
    |               |       Main.qml
    |               |       
    |               \---Lib
    |                       icon.qml
    |                       icons.js
    |                       label.qml
    |                       qmldir
    |                       Video.qml
    |                       
    +---cmake
    |       
    +---install
    |   +---bin
    |   |   |   VisuRysm.exe
    |   |   |   
    |   |   \---Contents
    |   |       \---Resources
    |   |           +---fonts
    |   |           |   +---font-awesome
    |   |           |   |       fontawesome-webfont.ttf
    |   |           |   |       
    |   |           |   \---roboto
    |   |           |           
    |   |           +---icons
    |   |           |   |   VisuRysm.icns
    |   |           |   |   
    |   |           |   +---develop
    |   |           |   |       Icon.icns
    |   |           |   |       VisuRysm.icns
    |   |           |   |       
    |   |           |   \---release
    |   |           |           Icon.icns
    |   |           |           VisuRysm.icns
    |   |           |           
    |   |           \---qml
    |   |               +---App
    |   |               |       Magic.qml
    |   |               |       Main.qml
    |   |               |       
    |   |               \---Lib
    |   |                       icon.qml
    |   |                       icons.js
    |   |                       label.qml
    |   |                       qmldir
    |   |                       Video.qml
    |   |                       
    |   \---Contents
    |               
    +---Resources
    |   +---fonts
    |   |   +---font-awesome
    |   |   |       fontawesome-webfont.ttf
    |   |   |       
    |   |   \---roboto
    |   |           
    |   +---icons
    |   |   |   VisuRysm.icns
    |   |   |   
    |   |   +---develop
    |   |   |       Icon.icns
    |   |   |       VisuRysm.icns
    |   |   |       
    |   |   \---release
    |   |           Icon.icns
    |   |           VisuRysm.icns
    |   |           
    |   \---qml
    |       +---App
    |       |       Magic.qml
    |       |       Main.qml
    |       |       
    |       \---Lib
    |               icon.qml
    |               icons.js
    |               label.qml
    |               qmldir
    |               Video.qml
    |               
    \---src
            App.cpp
            App.h
            AppConfig.cpp
            AppConfig.h
            AppController.cpp
            AppController.h
            AppWindow.cpp
            AppWindow.h
            Image.cpp
            Image.h
            ImageProvider.cpp
            ImageProvider.h
            main.cpp
            VideoService.cpp
            VideoService.h
            ZProjectionService.cpp
            ZProjectionService.h

So I have my source folder with the contents (qml stuff) and the actual code and i build it all with cmake:

cmake_minimum_required(VERSION 2.8)

project(VisuRysm)
set(TEMPLATE_NAME "VisuRysm" CACHE STRING "app name")

if(APPLE)
    set(EXECUTABLE "${TEMPLATE_NAME}.app")
endif()
if(WIN32)
    #set(EXECUTABLE "$(TEMPLATE_NAME}.exe")
    set(QT_USE_QMAIN TRUE)
endif()

# set the version number
set (VisuRysm_VERSION_MAJOR 2)
set (VisuRysm_VERSION_MINOR 0)

# configure a header file to pass some of the CMake settings to the     source code
configure_file (
  "${PROJECT_SOURCE_DIR}/cmake/VisuRysmConfig.h.in"
  "${PROJECT_BINARY_DIR}/cmake/VisuRysmConfig.h"
  )
include_directories("${PROJECT_BINARY_DIR}")
# ITK
# ***********************************************************************
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

# Qt
# ***********************************************************************
set(TEMPLATE_QT_VERSION "5.7.0" CACHE STRING "Qt Version")
set(TEMPLATE_QT_MODULES Core Gui Widgets Quick Qml Concurrent Multimedia     Network DBus PrintSupport)
set(QT_USE_QMAIN TRUE)

find_package(Qt5 ${TEMPLATE_QT_VERSION} EXACT CONFIG REQUIRED     ${TEMPLATE_QT_MODULES})


# OpenCV
# ***********************************************************************
#set(OpenCV_DIR "C:/opencv/build")
FIND_PACKAGE(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

# meta
# ***********************************************************************
set(TEMPLATE_VERSION_MAJOR 1 CACHE INT "Version Major")
set(TEMPLATE_VERSION_MINOR 0 CACHE INT "Version Minor")
set(TEMPLATE_VERSION_PATCH 0 CACHE INT "Version Patch")
set(TEMPLATE_ORGANIZATION "foo" CACHE STRING "Organization")
set(TEMPLATE_DOMAIN "" CACHE STRING "")

option(CMAKE_AUTOMOC "Use Automoc" ON)
option(TEMPLATE_USE_QT "Use Qt" ON)

set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER autogen)


# central paths
# **********************************************************************
SET(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_INSTALL_PREFIX ${ROOT_DIR}/install)

set(INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(BUILD_DIR ${ROOT_DIR}/build)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILD_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BUILD_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${BUILD_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${BUILD_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${BUILD_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${BUILD_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${BUILD_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${BUILD_DIR})

add_definitions(${QT_DEFINITIONS})

get_filename_component(Q_DIR_CONFIG ${Qt5_DIR} DIRECTORY)
get_filename_component(Q_DIR_LIB ${Q_DIR_CONFIG} DIRECTORY)
get_filename_component(Q_DIR_INSTALL ${Q_DIR_LIB} DIRECTORY)

set(QT_DIR_BIN ${Q_DIR_INSTALL}/bin)
set(QT_DIR_QML ${Q_DIR_INSTALL}/qml)
set(INSTALL_QML_DIR ${INSTALL_DIR}/${EXECUTABLE}/Contents/MacOS)


# setup os x bundle
# ***********************************************************************
set(MACOSX_BUNDLE_INFO_STRING ${TEMPLATE_BUNDLE_INFO})
set(MACOSX_BUNDLE_BUNDLE_VERSION ${TEMPLATE_BUNDLE_VERSION})
set(MACOSX_BUNDLE_LONG_VERSION_STRING        ${TEMPLATE_BUNDLE_VERSION_MAJOR}.${TEMPLATE_BUNDLE_VERSION_MINOR}.${TEMPLATE_    BUNDLE_VERSION_PATCH})
set(MACOSX_BUNDLE_SHORT_VERSION_STRING    ${TEMPLATE_BUNDLE_VERSION_MAJOR}.${TEMPLATE_BUNDLE_VERSION_MINOR}.${TEMPLATE_    BUNDLE_VERSION_PATCH})
set(MACOSX_BUNDLE_COPYRIGHT ${TEMPLATE_BUNDLE_COPYRIGHT})
set(MACOSX_BUNDLE_ICON_FILE ${TEMPLATE_NAME}.icns)
set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.${TEMPLATE_BUNDLE_VENDOR}")
set(MACOSX_BUNDLE_BUNDLE_NAME ${TEMPLATE_NAME})
set(MACOSX_BUNDLE_RESOURCES ${BINARY_DIR}/${EXECUTABLE}/Contents/Resources)
set(MACOSX_BUNDLE_ICON ${ROOT_DIR}/Resources/icons    /${MACOSX_BUNDLE_ICON_FILE})


# bundle directories & resources
# ***********************************************************************
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory     ${MACOSX_BUNDLE_RESOURCES})
#execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different     ${MACOSX_BUNDLE_ICON} ${MACOSX_BUNDLE_RESOURCES})

file(GLOB SOURCES
    src/*.h
    src/*.cpp
)
include_directories(${SOURCES})

# add executable
# ***********************************************************************
if(APPLE)
    add_executable(${TEMPLATE_NAME} MACOSX_BUNDLE ${SOURCES}     ${MACOSX_BUNDLE_ICON})
endif()
if(WIN32)
    add_executable(${TEMPLATE_NAME} ${SOURCES}) # WIN32
endif()

target_link_libraries(VisuRysm ${ITK_LIBRARIES} ${OpenCV_LIBS} Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Quick Qt5::Qml Qt5::Concurrent Qt5::PrintSupport Qt5::Multimedia)

# install
# ***********************************************************************
configure_file(${ROOT_DIR}/cmake/PostInstall.in.cmake     ${BINARY_DIR}/PostInstall.cmake)
install(TARGETS ${TEMPLATE_NAME} BUNDLE DESTINATION . COMPONENT Runtime     RUNTIME DESTINATION bin COMPONENT Runtime)
install(FILES ${MACOSX_BUNDLE_ICON} DESTINATION "${INSTALL_DIR}/${EXECUTABLE}/Contents/Resources")
if(WIN32)
    Set(DEPENDENCIES "${QT_DIR_BIN}/Qt5Core.dll"     "${QT_DIR_BIN}/Qt5Cored.dll" "${QT_DIR_BIN}/Qt5Widgets.dll"     "${QT_DIR_BIN}/Qt5Widgetsd.dll"
                     "${QT_DIR_BIN}/Qt5Gui.dll"     "${QT_DIR_BIN}/Qt5Guid.dll" "${QT_DIR_BIN}/Qt5Quick.dll"     "${QT_DIR_BIN}/Qt5Quickd.dll" 
                     "${QT_DIR_BIN}/Qt5Qml.dll"     "${QT_DIR_BIN}/Qt5Qmld.dll" "${QT_DIR_BIN}/QT5Concurrent.dll"     "${QT_DIR_BIN}/QT5Concurrentd.dll"
                     #"${QT_DIR_BIN}/icuin54.dll"     "${QT_DIR_BIN}/icuuc54.dll" "${QT_DIR_BIN}/icudt54.dll" 
                     "${QT_DIR_BIN}/QT5Networkd.dll" 
                     "${QT_DIR_BIN}/QT5Network.dll"     "${QT_DIR_BIN}/Qt5PrintSupport.dll" "${QT_DIR_BIN}/Qt5PrintSupportd.dll")
    file(COPY ${DEPENDENCIES} DESTINATION ${BUILD_DIR})
    file(COPY ${DEPENDENCIES} DESTINATION ${BINARY_DIR})
endif()
if(TEMPLATE_USE_QT)
    install(SCRIPT ${BINARY_DIR}/PostInstall.cmake)
endif()


# post-build: pack resources
# ***********************************************************************
add_custom_command(TARGET ${TEMPLATE_NAME} POST_BUILD COMMAND     ${CMAKE_COMMAND} -E copy_directory ${ROOT_DIR}/Resources     ${BUILD_DIR}/${EXECUTABLE}/Contents/Resources)
message((STATUS "> postbuild: ${PROJECT_SOURCE_DIR}/Resources} =>     ${BUILD_DIR}/Contents/Resources}"))

Is there an easy way to take my c++ program, all the neccessary dll's (ITK, openCV, Qt) and put it all in one exe file? And if so, how can i do this? Is there a way via visual studio?

I already tried copying the /source/build -folder (has all the dll's, the qml-contents and of course the exe) to another computer. But still, if I want to run the exe on another machine, some libraries are missing. And even if I copy those libraries into the folder manually, I still get errors, e.g. ITKSmartPointer error.

Sunny Onesotrue
  • 152
  • 3
  • 13
  • 1
    `Is there an easy way to take my c++ program, all the neccessary dll's (ITK, openCV, Qt) and put it all in one exe file?` - For doing that you need to build ITK, OpenCV, Qt as **static libraries**. When static libraries are linked into executable, code of that libraries becomes part of executable. With `.dll` (shared libraries) you cannot achive that. – Tsyvarev Feb 03 '17 at 08:29
  • thanks for the fast answer. i tried to google it, but apparently I'm too stupid. can you point me to a tutorial or something on how to achieve this? – Sunny Onesotrue Feb 03 '17 at 08:36
  • 1
    Each project/framework has its own way for compile libraries as static. E.g., [that question](http://stackoverflow.com/questions/7583172/opencv-as-a-static-library-cmake-options) is about building QT with static libraries. You may google similar info about ITK and OpenCV. – Tsyvarev Feb 03 '17 at 08:38
  • Note, that static libraries is not a cure for everything, and copiing dlls is not so bad as you think. `And even if I copy those libraries into the folder manually, I still get errors, e.g. ITKSmartPointer error.` - probably, it signals about incorrect application, and not about missed libraries or similar. – Tsyvarev Feb 03 '17 at 08:42

1 Answers1

2

To build ITK and OpenCV as static libraries, turn option BUILD_SHARED_LIBS to OFF when configuring them with CMake. This will produce static libraries which will be integrated into your executable, so no extra DLLs are needed.

For static link of Qt libs, there are tutorials, e.g. this.

Debug builds in Visual Studio are not supposed to work on another computer, even if you copy all the DLLs. Try compiling your application in Release mode, and then copy all the DLLs to a different computer.

I prefer building all my projects with static libraries, as it avoids problems of having to copy DLLs or adding conflicting versions to PATH. The only exception being Qt - I add the latest version to path.

Dženan
  • 3,329
  • 3
  • 31
  • 44