Note: The final solution was given in the edition, added to the end of this
answer.
I kind of figured out what's going on. : / The error is in the copy made by BundleUtilities
in the script of CMake (not that it is wrong, maybe it is that I did not know how to use correctly).
As the error complains that the binary image (in this case, the DLL) is inappropriate, I used the dumpbin
utility (installed along with Visual Studio on C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\
path) and executed:
dumpbin Qt5Widgets.dll /headers
The result indicated that the image was actually , compiled to 64 bits (line marked with an arrow):
Microsoft (R) COFF/PE Dumper Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file Qt5Widgets.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
8664 machine (x64) <==========================
8 number of sections
56F5814D time date stamp Fri Mar 25 15:19:57 2016
0 file pointer to symbol table
0 number of symbols
F0 size of optional header
2022 characteristics
Executable
Application can handle large (>2GB) addresses
DLL
[...]
But as I said, I've confirmed that my Qt installation is 32-bit. Then I re-run the installation inscript and paid attention to the Visual Studio output:
1>------ Build started: Project: INSTALL, Configuration: Release Win32 ------
1> -- Install configuration: "Release"
1> -- Installing: C:/temp/Data/bin/teste.exe
1> -- fixup_bundle
1> -- app='C:/temp/Data/bin/teste.exe'
1> -- libs=''
1> -- dirs=''
1> -- ignoreItems=''
1> -- fixup_bundle: preparing...
1> -- fixup_bundle: copying...
1> -- 1/28: *NOT* copying 'C:/temp/Data/bin/teste.exe'
1> -- 2/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/Qt5Core.dll'
1> -- 3/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/Qt5Gui.dll'
1> -- 4/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/Qt5Widgets.dll'
1> -- 5/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-environment-l1-1-0.dll'
1> -- 6/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-filesystem-l1-1-0.dll'
1> -- 7/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-heap-l1-1-0.dll'
1> -- 8/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-locale-l1-1-0.dll'
1> -- 9/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-math-l1-1-0.dll'
1> -- 10/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-runtime-l1-1-0.dll'
1> -- 11/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-stdio-l1-1-0.dll'
1> -- 12/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-string-l1-1-0.dll'
1> -- 13/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-time-l1-1-0.dll'
1> -- 14/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-utility-l1-1-0.dll'
1> -- fixup_bundle: fixing...
1> -- 15/28: fix-up not required on this platform 'C:/temp/Data/bin/teste.exe'
1> -- 16/28: fix-up not required on this platform 'C:/temp/Data/bin/Qt5Core.dll'
1> -- 17/28: fix-up not required on this platform 'C:/temp/Data/bin/Qt5Gui.dll'
1> -- 18/28: fix-up not required on this platform 'C:/temp/Data/bin/Qt5Widgets.dll'
1> -- 19/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-environment-l1-1-0.dll'
1> -- 20/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-filesystem-l1-1-0.dll'
1> -- 21/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-heap-l1-1-0.dll'
1> -- 22/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-locale-l1-1-0.dll'
1> -- 23/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-math-l1-1-0.dll'
1> -- 24/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-runtime-l1-1-0.dll'
1> -- 25/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-stdio-l1-1-0.dll'
1> -- 26/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-string-l1-1-0.dll'
1> -- 27/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-time-l1-1-0.dll'
1> -- 28/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-utility-l1-1-0.dll'
1> -- fixup_bundle: cleaning up...
1> -- fixup_bundle: verifying...
1> -- ===========================================================================
1> -- Analyzing app='C:/temp/Data/bin/teste.exe'
1> -- bundle='C:/temp/Data/bin'
1> -- executable='C:/temp/Data/bin/teste.exe'
1> -- valid='1'
1> -- executable file 1: C:/temp/Data/bin/teste.exe
1> -- verified='1'
1> -- info='Verified 1 executable files in 'C:/temp/Data/bin''
1> --
1> -- verified='1'
1> -- info=''
1> --
1> -- fixup_bundle: done
1> -- Installing: C:/temp/Data/bin/msvcp140.dll
1> -- Installing: C:/temp/Data/bin/vcruntime140.dll
========== Build: 1 succeeded, 0 failed, 3 up-to-date, 0 skipped ==========
Well, then I had the displeasure to realize that CMake was copying dependencies from the wrong source : it is copying from C:/Program Files/MiKTeX 2.9/miktex
, which is a Miktex installation (LaTex compiler for Windows ) that I have installed here (and that also uses Qt to develop its own graphical interfaces).
I will re-edit this answer in the future. I'm still trying
understand why it copied from the wrong source. My suspicion is that
it looks for the dependencies in the environment variable PATH
and copies the
first thing to find - though from the documentation say nothing to
this respect (at least not clearly).
EDITION (Final Solution)
First, it happens that the QT_LIBRARY_DIRS
variable does not exist in Qt5. Apparently, it existed in Qt4, but was deprecated in the new version since targets (such as Qt5::Core
) make it unnecessary to access the directory libraries directly (yet each target has the path of its CMake set in the variable <target>_DIR
). So, since this variable did not have the directory where BundleUtilities
should get the DLLs, it simply followed some arbitrary order.
I tested changing the order in the variable PATH
, but it did not change anything (continued picking up Miktex erroneously). After spending all day studying the problem, I came to the conclusion that using BundleUtilities
does not help much. The way it finds the dependencies of an executable is not clear (from what I read in the documentation it uses dumpbin
itself, among other tools), and even though I reported in a hardcoded ) the directories from where he needed to get the dependencies, I found out afterwards that he simply ignored many of them.
For example, he did not copy the plugin qwidows.dll
, and even forcing the copy of that file he did not copy it to the correct folder ( ./bin/platforms
). It also did not copy some of the C Runtime DLLs (which changed in the Windows 10 version and needs to be distributed - #bummer).
So I opted to manually copy the files myself, in order to guarantee their source without problems . The CMake script below makes this copy without using BundleUtilities
. I know the ideal would be to auto-identify, but the directory from where to fetch the C Runtime DLLs needs to be set up and, for ease, I have chosen to simply send all of them (even if only a few are being used in the code).
cmake_minimum_required(VERSION 2.8.11)
project(Teste)
#############################################
# Configuração
#############################################
# Tipos de build
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif()
# Configuração do Qt
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5 REQUIRED Core Widgets)
# Arquivos de código
file(GLOB SRC *.cpp *.h)
# Prepara o executável
if(WIN32)
add_executable(Teste WIN32 ${SRC})
else()
add_executable(Teste ${SRC})
endif()
# Configura nome do target
set_target_properties(Teste PROPERTIES OUTPUT_NAME teste)
# Configura libs linkadas
target_link_libraries(Teste Qt5::Core Qt5::Widgets)
#############################################
# Instalação
#############################################
get_filename_component(QT_BIN_DIR "${Qt5_DIR}/../../../bin" ABSOLUTE)
get_filename_component(QT_PLUGIN_DIR "${Qt5_DIR}/../../../plugins" ABSOLUTE)
# Instala o executável
install(TARGETS Teste DESTINATION bin)
# Instala as dependências do Qt5
install(FILES "${QT_BIN_DIR}/Qt5Core.dll" DESTINATION bin)
install(FILES "${QT_BIN_DIR}/Qt5Gui.dll" DESTINATION bin)
install(FILES "${QT_BIN_DIR}/Qt5Widgets.dll" DESTINATION bin)
install(FILES "${QT_PLUGIN_DIR}/platforms/qwindows.dll" DESTINATION bin/platforms)
# Instala as dependências do Windows 10 CRT
if(WIN32)
set(WIN10_CRT_REDIST_DIR "C:/Program Files (x86)/Windows Kits/10/Redist/ucrt/DLLs/x86" CACHE STRING "Path of the Windows 10 Universal C Runtime DLLs." FORCE)
file(GLOB CRTFiles "${WIN10_CRT_REDIST_DIR}/*.dll")
foreach(CRTFile ${CRTFiles})
install(FILES ${CRTFile} DESTINATION bin)
endforeach()
endif()
# Instala demais dependências
include(InstallRequiredSystemLibraries)
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin)