Visual Studio ignoring CMake linker flags for profile guided optimization - visual-studio

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?

Related

ThreadSanitizer in Visual Studio 2019

I am trying to build my project and run an executable in a different machine where I can see thread related issues (if exist). I am using VS2019 and providing -fsanitize=thread -fPIE -pie -g options in the Configuration Properties->Debugging->Command Arguments.
When I run the .exe file, I don't see any generated file which I suppose should have been generated.
Am I providing wrong arguments to the compiler or what is wrong here?
Configuration Properties->Debugging->Command Arguments is a wrong place for compiler options. They should go to Configuration Properties->C/C++->Command Line->Additional options
These options you want to pass are not supported neither by MSVC compiler (Visual C++), nor by clang-cl (Clang under Windows that mimic MSVC)
MSVC does not have ThreadSanitizer at all. (-fsanitize=address is available though)

Windos export/import symbols under MinGW vs MSVS; CMake's WINDOWS_EXPORT_ALL_SYMBOLS ignored

To build a C library with Visual Studio, the CMake command
set(WINDOWS_EXPORT_ALL_SYMBOLS ON)
saves me from adding __declspec(dllexport) or __declspec(dllimport) in front of function declarations; explicit import/export symbols are only required for global variables.
Under MinGW (read: either MinGW or its recommendable replacement Mingw-w64) this does not work. Linking applications (also built with MinGW) to my library failed until I had pasted import/export symbols in front of each function. Whereas the long answer https://stackoverflow.com/a/32284832/1017348 suggests the contrary: no need for import/export symbols under MinGW. Is that answer right? How then to get rid of the need for import/export symbols?
I just encountered the same problem. After poking through CMake source code, the fix that worked for me was to also add:
set( CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1 )
CMake says:
This property is implemented only for MS-compatible tools on Windows.
CMake enables this capability by setting CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS in each "Platform" file in <cmake install>/Modules/Platform that they know supports it. However, CMake doesn't model MinGW as a "Platform". Instead you just pick "Windows Makefile", "Windows Ninja", etc. and manually set the C/C++/Fortran compilers to point to the MinGW gcc compilers. Ideally CMake should recognize when the OS is Windows and the compiler is gcc and set this for us, but for now we can help it by setting it ourselves.
Incidentally CMake implements this feature with a hidden cmake -E __create_def <output-def> <input-list-of-obj-files> command. I previously thought of adding a custom rule to run that command. Though as it starts with __, it's meant for internal use and might change from one release to the next.

CMake warnings under OS X: MACOSX_RPATH is not specified for the following targets

I try to build a CMake-based software under OS X (Yosemite) which can be built successfully under Fedora 21. It uses a bunch of libraries. Both, big open ones like Boost and some self-written ones lying in /installation_folder/lib. I use CMake version 3.3.0.
After executing
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=/usr/local/Cellar/gcc/5.2.0/bin/gcc-5 -DCMAKE_CXX_COMPILER=/usr/local/Cellar/gcc/5.2.0/bin/g++-5 -DCMAKE_MODULE_PATH=${PWD}/../external/install/share/llvm/cmake
I get the following warnings:
CMake Warning (dev):
Policy CMP0042 is not set: MACOSX_RPATH is enabled by default. Run "cmake
--help-policy CMP0042" for policy details. Use the cmake_policy command to
set the policy and suppress this warning.
MACOSX_RPATH is not specified for the following targets:
ClangWrapper
Structure
WCETXML
This warning is for project developers. Use -Wno-dev to suppress it.
The CMakeLists.txt contains the following lines regarding RPATH:
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
IF("${isSystemDir}" STREQUAL "-1")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
ENDIF("${isSystemDir}" STREQUAL "-1")
All I can say is that ${CMAKE_INSTALL_PREFIX}/lib is indeed the correct path, and that other libraries like Boost are found correctly.
Ignoring the warnings and continuing with "make" in the build directory results in a linking error.
I read the CMake Wiki RPATH handling article, but I am still not able to distinguish between these path variables and their correct use on OS X.
Adding set(CMAKE_MACOSX_RPATH 1) into CMakeLists.txt, before the above written statements, lets the warnings disappear. The linking problem after executing make stays. This brings me to the assumption that my RPATH setup has nothing to do with my linking problem.
Nevertheless, this thread's problem is solved. An explanation about the correct use of the RPATH options inside CMakeLists.txt is still very welcome!
Well, I'll just go one step forward from #fotinsky's answer. (Feel free to incorporate this into your answer.)
The output of the warning's suggestion to run cmake-policy --help-policy CMP0042 is:
CMake 2.8.12 and newer has support for using ``#rpath`` in a target's install
name. This was enabled by setting the target property
``MACOSX_RPATH``. The ``#rpath`` in an install name is a more
flexible and powerful mechanism than ``#executable_path`` or ``#loader_path``
for locating shared libraries.
CMake 3.0 and later prefer this property to be ON by default. Projects
wanting ``#rpath`` in a target's install name may remove any setting of
the ``INSTALL_NAME_DIR`` and ``CMAKE_INSTALL_NAME_DIR``
variables.
This policy was introduced in CMake version 3.0. CMake version
3.1.3 warns when the policy is not set and uses OLD behavior. Use
the cmake_policy command to set it to OLD or NEW explicitly.
This simply means that in later cmake versions, the user is required to explicitly enable or disable CMAKE_MACOSX_RPATH.
There's also more background info on the introduction of this variable in this CMake blog entry.
As mentioned in a comment above, if you don't need to target older versions of cmake, you can simply set:
cmake_minimum_required (VERSION 3.0)
This removes the ambiguity of default values between major versions and simply enables runtime path behaviors by default.

Building Clang on Windows

I'm trying to build LLVM/Clang on Windows 7 with Microsoft C++ 2013. Building LLVM spat out a few error messages along the way but mostly seemed to be succeeding and did end up creating a folder full of exe's so that part seems to have worked. When I try to build Clang:
C:\clang>\CMake\bin\cmake.exe ..\clang-3.4 -DCLANG_PATH_TO_LLVM_BUILD=/llvm
CMake Error at CMakeLists.txt:29 (message):
Please set CLANG_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.
And I get the same error message whether I omit CLANG_PATH_TO_LLVM_BUILD, define it in CMakeLists.txt or an environment variable instead of the command line, set it to possibly relevant subdirectories of /llvm etc.
What am I missing?
You're not following the instructions on this page correctly, under "Using Visual Studio". You will end up with
/
/llvm
/llvm/CMakeLists.txt
/llvm/tools/clang
/llvm/tools/clang/CMakeLists.txt
Step 4, repeated here for clarity:
Run CMake to generate the Visual Studio solution and project files:
cd ..\.. (back to where you started)
mkdir build (for building without polluting the source dir)
cd build
If you are using Visual Studio 2012: cmake -G "Visual Studio 11" ..\llvm
That last bit needs to be run from inside the VS Command Prompt, but you seem to have that sorted out. You can also generate "NMake makefiles" if you don't use the IDE to build. Anyways, the point is that you should call cmake on the toplevel CMakeLists.txt file, not on the clang one directly. Clang will be built as part of the build process. You can even add libc++ and compiler-rt to the llvm/projects directory to have these built automatically on platforms that support them.
What you are doing is building clang "out of tree". Which is possible and even supported, but only really useful in certain circumstances. You'll need a previously built build of LLVM in some directory. You then set CLANG_PATH_TO_LLVM_BUILD to the directory containing the built LLVM files (this is not the source directory). But as I said, that's making things needlessly difficult.

Recompiled Qt libraries with VS, now why won't Qt Creator compile?

My initial goal was to get Qt Creator and Visual Studio 2008 to create compatible libraries, so what I've done so far was open a VS command prompt, go to my Qt folder and then run configure.exe followed by nmake to recompile the Qt libraries with VS. The problem is that now Qt creator won't compile anything. The compiler output shows that it is now using cl instead of gcc, which is what I wanted, but anytime I try to compile anything I get the following warnings:
:-1: warning: unrecognized option '/MANIFEST'; ignored
:-1: warning: unrecognized option '/MANIFESTFILE:debug\HelloQt.intermediate.manifest'; ignored
:-1: warning: unrecognized option '/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*''; ignored
I'm not sure if it makes a difference, but when I ran configure.exe I didn't set any command line parameters. I've noticed that references I've found have use different command line parameters when running configure.exe (although no two references use the same parameters), I'm not sure if running it from a VS command line was enough or if I was supposed to manually set some options.
This website uses a very long command line for configure.exe
configure -no-sql-sqlite -no-qt3support -no-opengl -platform win32-msvc2005 -no-libtiff -no-dbus -no-phonon -no-phonon-backend -no-webkit
although it appears he's disabling some options that I will need for my projects, and he didn't run it from a VS command prompt.
EDIT: recompiled with the -platform win32-msvc2008 parameter for configure.exe and it made no difference
My question is, what should I do about these "unrecognized options," and more generally is there anything else I need to do to get Qt creator to compile Qt projects with cl?
UPDATE
So I've tried recompiling the Qt libraries and upon actually reading the output from the 45+ minutes of compilation, I see that nmake is exiting with an error. I get eight "unresolved external symbol" errors from QNetworkReplyHandler.obj and FrameLoaderClientQt.obj before the compilation process is aborted. This doesn't seem like it would be causing the unrecognized option errors I've been receiving but it explains why the Qt libraries seem to run buggy when I'm using them with the Visual Studio Qt Plug-in. This problem is relatively unrelated so I've posted it in another question, here is the link just in case anyone has an answer for that problem.
The goal is to ensure you have a properly compiled QTDIR. In your case one for VS and one for gcc (if you want the two).
Depending on what you downloaded Qt Creator uses gcc but you can specify alternative QT directories under Options > Qt4 > Qt Versions. The path and version will show in the dialog box.
Go to the VS command line and run configure.exe & nmake with a clean source repository. Then add this QTDIR to you Qt Creator. I suggest you run make clean before.
Then make sure qmake and nmake can be run from the Qt command-line without errors. You should have a Qt Command line icon installed if you used Qt installer. If not, make sure you have QTDIR environment variable set, with %QTDIR%/bin in the path.
Do step 1 again, but this time do not use VS but make sure gcc is in the path. Run configure.exe etc again but in a separate directory specially for gcc. Add this version to your Qt Creator.
When compiling your project, run qmake first. You can change Qt versions, but do not forget to run qmake.
Hope this helps.
also, remember that QT Creator does not support debugging using CL
-- Lior

Resources