Until yesterday I used Visual Studio 2008 and CMake (in combination with CPack) to build my project under Windows - that worked fine. But now I switched to the 2010 edition and ran into a (an old) problem: The loved background console (Because Windows thinks we have a fancy console application):
I have a CMake decision to avoid this window:
if(MSVC)
target_link_libraries(client window core ${QT_QTMAIN_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
set_target_properties(client PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS")
else()
target_link_libraries(client window core ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
endif()
This works for Visual Studio 2008, but not for 2010 (The /SUBSYSTEM is useless). So my question is: Does anyone have experience with this or solved it in CMake ? I don't want to change my main function to WinMain (Have the same codebase for Unix/Linux/OS X and Windows) or change the SUBSYSTEM settings in Visual Studio (That's not the idea behind CMake)
So after a cup of coffee I came to the following solution. Debug and Release build don't open a background console. Take a look at the WIN32 tag and the LINK_FLAG for Debug/Release/RelWithDebugInfo:
if(MSVC)
add_executable(client WIN32 ${SRC_CLIENT} ${HDR_UI_CLIENT} ${HDR_RSC_CLIENT})
target_link_libraries(client server ${QT_QTMAIN_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
set_target_properties(client PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS")
set_target_properties(client PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:WINDOWS")
set_target_properties(client PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
set_target_properties(client PROPERTIES RELWITHDEBINFO "/SUBSYSTEM:WINDOWS")
set_target_properties(client PROPERTIES MINSIZEREL "/SUBSYSTEM:WINDOWS")
else()
add_executable(client ${SRC_CLIENT} ${HDR_UI_CLIENT} ${HDR_RSC_CLIENT})
target_link_libraries(client server ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
endif()
If you use a modern version of CMake (2.8.11 or later), the ${QT_QTMAIN_LIBRARY} library will automatically be linked in for WIN32 executables, and not otherwise, if you use the IMPORTED targets.
http://www.cmake.org/cmake/help/git-master/module/FindQt4.html
You should not need to add the /subsystem yourself at all. That's what WIN32 does. If you can produce a minimal testcase, it's a bug.
Related
Why do I have to set a source .asm file's Properties > General > Item Type to Microsoft Macro Assembler, even though I had already selected for the project node, the option Build dependencies > Build Customization > masm.
It may depend on which version of Visual Studio you are using, but I recall what seemed like a one time option to auto-select masm for .asm file with one of the versions. After dealing with multiple versions of Visual Studio and having issues with some versions, I manually set the properties for each .asm file to use a custom build tool (also turn off does not participate in build as commented by John Kalane), which is working for all the versions I have (VS2005, VS2010, VS2015, VS2019).
32 bit debug build, for release build /Zi is not needed:
command line: ml /c /Zi /Fo$(OutDir)\example.obj example.asm
outputs: $(OutDir)\example.obj
64 bit debug build, for release build /Zi is not needed:
command line: ml64 /c /Zi /Fo$(OutDir)\example.obj example.asm
outputs: $(OutDir)\example.obj
I'm trying to add an application icon to an application I'm writing, following what is described in https://doc.qt.io/qt-5/appicon.html
I'm using Qt Desktop 5.15.2 (64) and 6.1.2 (64) for both MinGW and MSVC, on Windows 10 64 bits. They all compile without error or warnings, but the icon doesn't show up.
My CMakeFile.txt:
cmake_minimum_required(VERSION 3.14)
project(MyApp VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check https://doc.qt.io/qt/deployment-android.html for more information.
# They need to be set before the find_package(...) calls below.
if(ANDROID)
set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
# if (ANDROID_ABI STREQUAL "armeabi-v7a")
# set(ANDROID_EXTRA_LIBS
# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
# endif()
endif()
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Quick LinguistTools REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick LinguistTools REQUIRED)
set(TS_FILES _pt_BR.ts)
set(PROJECT_SOURCES
main.cpp
qml.qrc
${TS_FILES}
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/MyApp.rc")
qt_add_executable(MyApp
MANUAL_FINALIZATION
${PROJECT_SOURCES}
${APP_ICON_RESOURCE_WINDOWS}
)
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
if(ANDROID)
add_library(MyApp SHARED
${PROJECT_SOURCES}
)
elseif(WIN32)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/windows/MyApp.rc")
add_executable(MyApp
${PROJECT_SOURCES}
${APP_ICON_RESOURCE_WINDOWS}
)
else()
add_executable(MyApp
${PROJECT_SOURCES}
)
endif()
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()
target_compile_definitions(MyApp
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(MyApp
PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick)
set_target_properties(MyApp PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_import_qml_plugins(MyApp)
qt_finalize_executable(MyApp)
endif()
MyApp.rc:
MyAppIcon ICON "MyApp.ico"
The .ico contains a single 256x256 32-bit RGBA image.
For what matters, after so many failures I tried creating a test project using qmake, and added the icon using RC_ICONS = QtTest.ico the .pro file, which worked (got the correct icon). When I tried using the RC_FILE = QtTest.rc instead it used the default icon, but without any warnings or errors.
Just in case I generated the .res file using windres, but to no avail. Changed QtTestIco ICON "QtTest.ico" and regenerated the .res, the same result.
Substituting the CMakeList.txt for a .pro file and using the RC_ICONS is not an option, sadly.
Somebody could help me, please?
Thanks in advance.
In order to add a Microsoft resources (RC) file, you need to tell CMake to support the "RC" language by enabling Microsoft's RC language. This will kick in the resource compiler when it detects a file with the *.rc extension in your project.
Here is a sample code snippet:
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
enable_language("RC")
set (WIN32_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/windows/MyApp.rc)
endif()
add_executable(MyApp WIN32
${PROJECT_SOURCES}
${WIN32_RESOURCES}
)
Build your project and Microsoft Explorer will then see your icon.
Suppose you have (core and myapp just as an example):
core/
CMakeLists.txt
myapp.ico
myapp.rc
...other dirs with your sources...
Your myapp.rc contains:
IDI_ICON1 ICON DISCARDABLE "myapp.ico"
Suppose you have MS VC Build Tools installed and you have x64 Native Tools Command Prompt open. And you build your project using cmake, etc. It means that there you also have rc cmd program there. So in your prompt do:
C:\Users\MyName\myapprepo\core> rc myapp.rc
Then you get a binary file myapp.res:
core/
CMakeLists.txt
myapp.ico
myapp.rc
myapp.res
So now, you need to link this binary file to our lib/app. In my case it was a lib I called core and I would link it to my executable myapp. It does not matter. The point is that you should link the file:
# core/CMakeLists.txt
target_link_libraries(${CORE_LIBRARY_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/myapp.res
Qt5::Widgets)
The MS VC compiler knows what to do when linking the res file to your lib/exe. So don't worry about the strange entity. In general, the whole procedure is exactly as it is described in the docs https://doc.qt.io/archives/qt-4.8/appicon.html:
If you do not use qmake, the necessary steps are: first, run the rc program on the .rc file, then link your application with the resulting .res file.
If any question, ask in comments. Good luck!
I have a C++ project which uses CMake as its build system in Visual Studio 2017 Enterprise. According to the documentation, I have to link using /LTCG and /GENPROFILE. In CMake, this seems to equate to setting the variable CMAKE_EXE_LINKER_FLAGS:
set(LINKER_FLAGS, "/LTCG /GENPROFILE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
Furthermore, since my application requires command line arguments, I had to define them in the launch.vs.json as seen in this answer.
Now if I run the application's x64-Release profile, it successfully completes in a normal, non-delayed Release build fashion. No .pgd has been generated which means that my passed linker flags probably have been ignored.
Another try was adding additional CMake linker flag variables:
set(LINKER_FLAGS, "/LTCG /USEPROFILE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${LINKER_FLAGS}")
This also didn't work. Specifying /USEPROFILE afterwards did not generate a different binary. Also, the runtimes are roughly equivalent. There is also no indication on the command line that a profile has been generated or used.
What am I doing wrong here?
The official LLVM 4.0 build for Windows integrates with Visual Studio up to Visual Studio 2015. Unfortunately it still doesn't support Visual Studio 2017.
When you try to set the Platform Toolset of a project to LLVM-vs2014, it pops up an error.
Do you know any way to make it work?
Update
In 2018, LLVM 6.0 officially still doesn't support integration with Visual Studio 2017 (version 15.X.X), only with the Visual Studio 2015 (version 14.X.X) toolset.
It requires some msbuild targets that only ship with the C++ v140 toolset, and VS 2017 only installs the v141 toolset by default. If you open the VS 2017 installer, find the checkbox for the v140 toolset and install that then the right C++ msbuild targets will be available and the thing will work.
Finally, I found a brilliant GitHub repo with the required MSBuild platform toolsets which integrates LLVM clang 5.0.0 into Visual Studio 2017. After following the instructions of the README file, you will have two new platform toolsets LLVM-vs2017 and LLVM-vs2017_xp. Problem solved.
Update
I made a fork which is updated for LLVM 6.0.0 and provides better integration by providing include and library paths of LLVM/clang.
Thanks to Royi, who realized that the original .prop files are explicitly tailored for LLVM 5.0 and it misses adding the proper lib (
$(LLVMInstallDir)\lib) and include ($(LLVMInstallDir)\lib\clang\6.0.0\include) folders.
The LLVM project now explicitly supports Visual Studio 2017 via https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain
I'm a newbie with the LLVM technology and I'm using a Visual Studio extension, Clang Power Tools. They have a settings page from where you can install LLVM (all versions >= 4.0). After that you are free to apply clang compile or tidy with code modernization(this is what I appreciate the most) by using the extension buttons from VS toolbar. In this way you don't need to configure anything.
Update
Open the extension settings and select the LLVM page from the top. On the LLVM page, you'll see all the supported LLVM versions and at the right of each version the install button. Install any version you need. On the bottom of the page is a dropdown that allows you to select what version to use in case you installed multiple versions.
The feature is explained step by step in this blog post
LLVM/Clang now has an updated patch that allows you to use it with VS2017. But they still don't directly support VS2017. I asked on the LLVM developer mailing list for them to update their support for VS2017, so hopefully they'll do it. If they listen to what I said.
I have figured out how to integrate LLVM Clang 7.0 with Visual Studio 2017 update 15.5.6. v1913 with full support for PDB based debugging using the latest LLVM builds.
i.e., lld-link /DEBUG:GHASH; clang-cl -mllvm -emit-codeview-ghash-section flag to clang-cl.
It is a three step process.
Install latest llvm
Update the toolset.props, toolset.targets in VS to support latest clang
Select the new toolset to use for building your C/C++ or other lang project
As of Visual Studio 2017 update 15.4.5 the Microsoft "experimental" Clang C2 no longer works. Thus, the above fixes are necessary to use clang to compile code that has full PDB (not just CodeView /Z7 limited) debuggability. This also now becomes a more complete suite for portability testing cross-platform builds since you can build and PDB debug for windows using all LLVM components from the clang compiler front end to the LLVM codegen backend and LLVM linker.
Cheers, David
Check out January 09, 2018 http://planet.clang.org/
Look at the "Try it out!" section:
If you're already using clang-cl and lld-link on Windows today, you can try this out. There are two flags needed to enable this, one for the compiler and one for the linker:
To enable the emission of a .debug$H section by the compiler, you will need to pass the undocumented -mllvm -emit-codeview-ghash-section flag to clang-cl (this flag should go away in the future, once this is considered stable and good enough to be turned on by default).
To tell lld-link to use this information, you will need to pass the /DEBUG:GHASH to lld.
You just need to pass the -mllvm -emit-codeview-ghash-section flags in either your c++ projects "Command Line:Additional Options" area, or place them directly in the "toolset.props" file that you created in C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\Platforms\Win32\PlatformToolsets\LLVM-vs2017 or
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\Platforms\x64\PlatformToolsets\LLVM-vs2017.
The key is that in adding those cli options you're telling clang to emit debug information that the lld (aka lld-link) will understand and use to produce fully populated PDB files. Not the limited ones it made prior to the Jan 09, 2018 drops of LLVM 7.0.
toolset.targets: (any version)
<Project ToolsVersion="14.1"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(VCTargetsPath)\Microsoft.CppCommon.targets" />
</Project>
toolset.props: (Win32 version)
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v141\Microsoft.Cpp.$(Platform).v141.props" Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v141\Microsoft.Cpp.$(Platform).v141.props')"/>
<Import Project="$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v141\Toolset.props" Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v141\Toolset.props')"/>
<PropertyGroup>
<LLVMInstallDir>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM)</LLVMInstallDir>
<LLVMInstallDir Condition="'$(LLVMInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM)</LLVMInstallDir>
<ExecutablePath>$(LLVMInstallDir)\msbuild-bin;$(ExecutablePath)</ExecutablePath>
<LibraryPath>$(LLVMInstallDir)\lib\clang\7.0\lib\windows;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<!-- remove the implicit vcxxx.pdb path to avoid rebuilds every time as clang-cl only supports /Z7 -->
<ProgramDataBaseFileName></ProgramDataBaseFileName>
<!-- Set the value of _MSC_VER to claim for compatibility -->
<AdditionalOptions>-m32 -fmsc-version=1913 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
</Project>
For x64, change -m32 to -m64
p.p.s., I have also enabled Microsofts ARM and ARM64 compilers for building native Windows-10-ARM apps (not UWP modern-com-junk). But, as yet, I have not done enough digging through the clang sources to properly configure something similar for ARM to what -m32 and -m64 do for Intel code-gen.
See these articles:
http://pete.akeo.ie/2017/05/compiling-desktop-arm-applications-with.html
https://www.theverge.com/2017/12/5/16737288/microsoft-windows-10-qualcomm-arm-laptops-launch
https://wiki.winehq.org/ARM
Could someone tell me a command line switch for bjam or something else that will make boost compile with VS2010 using the new Windows Platform SDK 7.1 toolchain? It's an option you can set in a normal visual studio project. The default is v100 a variant of the platform 7.0 toolchain. Thanks in advance.
Try this in your environment
set SdkTools=c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
call "%SdkTools%\SetEnv.Cmd" /xp /x86
assuming that's where you have the Windows SDK installed. Info is from here - there may be more to do, but this looks on the right track to me.
To build boost 1.43.0 libraries for VS 2010:
Download and extract to C:\Temp\boost_1_43_0
Start Visual Studio 2010 Command Prompt
Build BJam
cd C:\Temp\boost_1_43_0\tools\jam\src
build.bat
Build Boost using BJam
cd C:\Temp\boost_1_43_0
tools\jam\src\bin.ntx86\bjam.exe --with-regex link=static runtime-link=static threading=multi variant=debug,release address-model=32,64
Check bin.v2 or stage/lib for output. Note naming conventions.
May need to build in two phases with just address-model=32 then with just address-model=64. In this case we are choosing to build libs that statically link to the C runtime and to statically link to the boost lib itself.
Use --with to build non-header based libs like regex. Note stage/lib will be overwritten after each address-model build, but all libs are always kept in bin.v2.