CMAKE - setting compile flags for libraries - c++

I have a CMakeLists.txt script to compile my libraries.
The problem is I cannot set the compile flags for the libraries.
I've tried
SET(CMAKE_CXX_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_CXX_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_C_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_C_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_C_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_EXE_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_MODULE_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_SHARED_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
SET(CMAKE_STATIC_LINKER_FLAGS "/W3 /nologo /EHsc")
SET(CMAKE_STATIC_LINKER_FLAGS_DEBUG "/MTd /Od /Ob0 /Zi /RTC1 /DDEBUG /D_DEBUG")
SET(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
None of those have effect...
The only way I can change flags for a library is like this.
SET_TARGET_PROPERTIES(MyLib PROPERTIES COMPILE_FLAGS "/W3 /nologo /EHsc")
and this will change the flags for both Debug and Release
How in the world can I set the Release and Debug flags separately for a library using CMake?

Those are globally cached variables you are trying overwrite in your first approach.
Changing those compiler/linker options locally you need config-specific target properties or generator expressions. So taking your second approach and How can I set specific compiler flags for a specific target in a specific build configuration using CMake? I would get:
target_compile_options(
MyLib PRIVATE
/W3 /nologo /EHsc
"$<$<CONFIG:Debug>:/MTd;/Od;/Ob0;/Zi;/RTC1;/DDEBUG;/D_DEBUG>"
"$<$<CONFIG:Release>:/MT;/O2;/Ob2;/DNDEBUG>"
)
or for CMake versions <= 2.8.12 (see also policy CMP0043):
set_target_properties(
MyLib PROPERTIES
COMPILE_FLAGS
"/W4 /nologo /EHsc"
COMPILE_FLAGS_DEBUG
"/MTd /Od /Ob0 /Zi /RTC1"
COMPILE_FLAGS_RELEASE
"/MT /O2 /Ob2"
COMPILE_DEFINITIONS_DEBUG
"DEBUG;_DEBUG"
COMPILE_DEFINITIONS_RELEASE
"NDEBUG"
)
I personally like the "OLD" way of doing it better, because it replaces the default options in Visual Studio's project properties. Whatever is passed via target_compile_options() will end up in Configuration Properties / C/C++ / Command Line / Additional Options.
Some background information why your first approach didn't work:
CMake's generator takes whatever is set for CMAKE_<LANG>_FLAGS at the end of any CMakeLists.txt file and applies it to all library and executable targets in the same CMakeLists.txt file as the default compiler options when generating the build environment.
If you set the linker variables for you main CMakeLists.txt targets in subdirectories CMakeLists.txt it won't help (wrong scope). If I take your above code into the main CMakeLists.txt it does work and I get the following warnings (because you used compiler options for the linker):
1>LINK : warning LNK4044: unrecognized option '/W3'; ignored
1>LINK : warning LNK4044: unrecognized option '/EHsc'; ignored
1>LINK : warning LNK4044: unrecognized option '/MTd'; ignored
1>LINK : warning LNK4044: unrecognized option '/Od'; ignored
1>LINK : warning LNK4044: unrecognized option '/Ob0'; ignored
1>LINK : warning LNK4044: unrecognized option '/Zi'; ignored
1>LINK : warning LNK4044: unrecognized option '/RTC1'; ignored
1>LINK : warning LNK4044: unrecognized option '/DDEBUG'; ignored
1>LINK : warning LNK4044: unrecognized option '/D_DEBUG'; ignored
I'm now hiding the cached variables of the same name set by CMake during the compiler detection. For more details see:
What's the CMake syntax to set and use variables?
CMake: In which order are files parsed (cache, toolchain, etc.)?

Related

How to enable static analysis with custom ruleset in MSVC via CMakeLists.txt?

I use cmake (3.23+) to generate solution files for MSVC (via CMakeLists.txt).
I'd like to enable static analysis for generated projects, and make it use my custom ruleset. I am aware that MSVC supports a CmakeSettings.json file that can do this, but I don't understand how it relates to CMakeLists.txt/how it should be included here.
I've tried to do it via command line parameters:
target_compile_options ( ${PROJECT_NAME}
PRIVATE /MP /analyze /analyze:ruleset ${CMAKE_CURRENT_SOURCE_DIR}/use-after-move.ruleset
)
But the compiler treats the ruleset as another .cpp file to compile. The generated command line looks like this:
CL.exe /c ...list of include directories... /Zi /nologo /W1 /WX- /diagnostics:column /MP /Od /Ob0 /D _MBCS /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR=\"Debug\"" /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++latest /Fo"editor-lib.dir\Debug\\" /Fd".\vsbuild\lib\Debug\editor-lib-d.pdb" /external:W1 /Gd /TP /analyze /errorReport:prompt path/to/use-after-move.ruleset ...list of source files...
I tried wrapping the /analyze:ruleset into double quotes, but with the same outcome. I also tried to wrapping it with single quotes which made it show up in the compile options, however like this:
'/analyze:ruleset' path/to/ruleset
I also might be using these options wrong as the analysis is not performed when I manually plug them in project properties. Analysis is only performed when I drop the /analyze:ruleset and keep in just /analyze (but then it defaults to Microsoft's All Rules).
I found an answer in this SO thread: How to add Property to Affect Code Analysis in CMake
Create user property sheet (saved as EnableUseAfterMoveAnalysis.props):
<Project>
<PropertyGroup>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleset>path/to/use-after-move.ruleset</CodeAnalysisRuleset>
</PropertyGroup>
</Project>
And then in CMakeLists.txt bind it to the project using set_property:
set_property(
TARGET ${PROJECT_NAME}
PROPERTY VS_USER_PROPS "path/to/EnableUseAfterMoveAnalysis.props"
)

CMake + Visual Studio 2019: error invalid argument '/Wno-narrowing'

I downloaded the source code for a library that resembles the processing library but for c++ called libxd. I used CMake to generate project files for Visual Studio 2019 which worked successfully. When trying to compile the solution for all of the provided build modes, I get the following errors:
The first error invlaid numeric argument '/Wno-narrowing' is what I'm concerned about for now. I'm trying to figure out why this argument is being provided to the compiler. When looking in the properties window for the xd project in the solution I can see the command line arguments that are supposed to be provided to the compiler in the C/C++ > Command Line tab. I verified that there is no /Wno-narrowing option provided. When looking at the build output it can be seen that the option -Wno-narrowing is being provided to the compiler. Can someone help me figure out why this argument is being passed? I looked throughout the compiler properties window to see if I could see anything that would be affecting it but I can't see anything that would affect this.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\bin\HostX64\x64\CL.exe /c /IC:\dev\libxd\include /IC:\dev\libxd\lib\glad\include /IC:\dev\libxd\lib\glm /IC:\dev\libxd\lib\stb\include /IC:\dev\libxd\lib\glfw\include /Zi /nologo /W3 /WX- /diagnostics:column /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /Fo"xd.dir\Debug\\" /Fd"xd.dir\Debug\xd.pdb" /Gd /TP /errorReport:prompt -Wno-narrowing C:\dev\libxd\src\opensans.cpp
Tracking command:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Tracker.exe /d "C:\Program Files (x86)\MSBuild\15.0\FileTracker\FileTracker32.dll" /i C:\dev\libxd\build\xd.dir\Debug\xd.tlog /r C:\DEV\LIBXD\SRC\OPENSANS.CPP /b MSBuildConsole_CancelEventfa83e1bb599743cfa0c02eb67d579e28 /c "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\bin\HostX64\x64\CL.exe" /c /IC:\dev\Users\olive\Downloads\libxd\include /IC:\dev\libxd\lib\glad\include /IC:\dev\libxd\lib\glm /IC:\dev\libxd\lib\stb\include /IC:\dev\libxd\lib\glfw\include /Zi /nologo /W3 /WX- /diagnostics:column /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /Fo"xd.dir\Debug\\" /Fd"xd.dir\Debug\xd.pdb" /Gd /TP /errorReport:prompt -Wno-narrowing C:\dev\libxd\src\opensans.cpp
cl : command line error D8021: invalid numeric argument '/Wno-narrowing'
The command exited with code 2.
The error is caused because that's not a valid MSVC flag. The flag is there because the CMakeLists.txt file demands it:
set_source_files_properties(src/opensans.cpp PROPERTIES COMPILE_FLAGS -Wno-narrowing)
That project specifies what it supports for building under Windows and it's not MSVC.
Windows Prerequisites: mingw-w64 version >= 4.8.1
So you either need to build it in the supported way, or modify the build scripts to allow for MSVC.
That would entail figuring out what the flag does in gcc (disables diagnostic messages about narrowing issues) and finding the equivalent in MSVC, probably a /disable:nnnn variant, once you figure out the nnnn. Figuring that out should be relatively painless since MSVC will tell you that when you compile it - lots of Cnnnn - something to do with narrowing warning messages.
Or you could just disable the line that adds the flag (for MSVC builds only) and see if it still builds. Of course, in the spirit of open source, you should then notify the author what it took to get it going, they may be happy to support MSVC if the effort is not too high.

How to create Visual Studio 2015 solution from CMake

We have a CMakeList.txt prepared to work with IDE's like QT Creator, so some team members are using two different solutions, one for Release and a different one for Debug, respectively.
I would like to use Visual Studio 2015, so I need to create one single solution considering both configurations (Release & Debug). How can I set the different configuration flags properly?
Now, CMakeList file looks like this:
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Debug Build")
set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /W3 /wd4996 /wd4251 /wd4275 /wd4267 /GR /EHsc /MP")
else()
message("Release Build")
set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /WX /W3 /wd4996 /wd4251 /wd4275 /wd4267 /GR /EHsc /MP /Ox")
endif()
So I just can create one single solution adding -D CMAKE_BUILD_TYPE = Release or Debug.
I would like to generate a single solution and then, from VS decide to compile as Debug or Release.
Visual Studio is a multi-configuration generator, so you can easily switch between Release and Debug. No need to use a CUSTOM_BUILD_TYPE argument. In addition, CMake provides generator expressions (e.g. $<$<CONFIG:Debug>: ... >) for setting configuration-specific options such as those in your example. The flags look very similar between Release and Debug, so you can use a generator expression to simply add the extra Release flags.
Also, manually manipulating the CMAKE_CXX_FLAGS variable is discouraged. It is much safer and cleaner to set these flags using target_compile_options():
target_compile_options(YourTarget PRIVATE
/DWIN32 /D_WINDOWS W3 /wd4996 /wd4251 /wd4275 /wd4267 /GR /EHsc /MP
$<$<CONFIG:Release>:/WX;/Ox>
)

Getting irelevant warning about option 'Gm' is deprecated

Options I use to compile my project:
/JMC /GS /analyze- /Wall /Zc:wchar_t /ZI /Od /sdl /Fd"Dev\Project.pdb" /Zc:inline /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MTd /FC /Fa"Dev\" /EHsc /nologo /Fo"Dev\" /Fp"Dev\Project.pch" /diagnostics:classic
As you can see, there is not any Gm option. Anyways I'm getting this warning every time:
1>cl : Command line warning D9035: option 'Gm' has been deprecated and will be removed in a future release
1>cl : Command line warning D9007: '/Gm' requires '/Zi or /ZI'; option ignored
Problem is that Gm is disabled on every configuration. How can I solve this issue?
The problem was in UI. There was <MinimalRebuild Condition="'$(Configuration)|$(Platform)'=='Dev|Win32'">true</MinimalRebuild> in the .vcxproj file, but UI have been showing that field is blank. The warning is not there once I have deleted this from .vcxproj.

How do I do "Edit and Continue" builds with cmake projects in Visual Studio 2019?

I want to do "Edit and Continue" in my Visual studio cmake C++ projects.
I know I have to change /Zi to /ZI, but where?
This is C++
The easiest way is to insert the following commands before the definition of your first target:
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(CMAKE_CXX_FLAGS_DEBUG "/ZI")
set(CMAKE_SHARED_LINKER_FLAGS "/SAFESEH:NO")
set(CMAKE_EXE_LINKER_FLAGS "/SAFESEH:NO")
endif()
If you prefer to set the options for a specific target, use
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(${PROJECT_NAME} PRIVATE "/ZI")
target_link_options(${PROJECT_NAME} PRIVATE "/SAFESEH:NO")
endif()
Warning: as of the latest version of Visual Studio at the time of writing (16.4.2), Visual Studio cannot deal with changes to lambda functions.
The options must be set as follows:
CMAKE_C_FLAGS_DEBUG: /MDd /ZI /Ob0 /Od /RTC1
CMAKE_CXX_FLAGS_DEBUG: /MDd /ZI /Ob0 /Od /RTC1
CMAKE_EXE_LINKER_FLAGS_DEBUG: /debug /INCREMENTAL /LTCG:OFF
CMAKE_MODULE_LINKER_FLAGS_DEBUG: /debug /INCREMENTAL /LTCG:OFF
CMAKE_SHARED_LINKER_FLAGS_DEBUG: /debug /INCREMENTAL /LTCG:OFF