I'm using CMake 2.8.1 (tried this on CMake 2.8.5 too). I'm using the Visual Studio generator for VS2008. I would like to selectively apply compile flags on some some source files differently than for other files, and all of these files are going into the same static library (splitting the library into two different targets is not an option at this time). I cannot use set_target_properties in this case because the compile flags must be different. However I discovered something quite odd. The following works (works being defined that I see the /flubber option show up in the AdditionalOptions fields in the .vcproj file CMake generates):
set_property(SOURCE file1.cpp file2.cpp
PROPERTY COMPILE_FLAGS /flubber
)
But this does not work:
set_property(SOURCE file1.cpp file2.cpp
PROPERTY COMPILE_FLAGS /GR
)
Why is CMake filtering out or ignoring the /GR option? Is that a CMake bug or intentional?
Now this question is a bit contrived given that, circa VS2005, the /GR option was defined to be on by default (gives RTTI), so I really don't have to specify it. But that isn't the point because there are other flags that start with "/G" that are perfectly valid to want to specify on one source file, but not another, and in the same static library target.
Visual Studio provides special option for /GR flag:
cmake knows that and transforms your /GR flag into that option. If you open your cmake-generated project file (.vcproj) with notepad, then you can see additional RuntimeTypeInfo="TRUE" attribute inside your file configuration:
/flubber flag added:
<Tool Name="VCCLCompilerTool" AdditionalOptions="/flubber" />
/GR flag added:
<Tool Name="VCCLCompilerTool" RuntimeTypeInfo="TRUE" />
Related
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?
I am using cmake + qt + visual studio to work on a project. Problem I am having it that I would like visual studio to create new moc objects if I modify the QT ui files. If I just do a full build everything works file, but if I just modify something on the ui file it does not "auto moc" and I have to rebuild the whole project.
The cmake file I have is pretty simple:
cmake_minimum_required(VERSION 3.2)
set(CMAKE_VERBOSE_MAKEFILE ON)
project(main)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets)
file(GLOB CPP_FILES *.cpp)
add_executable(main ${CPP_FILES})
target_link_libraries(main Qt5::Widgets)
target_compile_features(main PUBLIC cxx_nullptr)
Does anyone know a way to get this to work (having visual studio to detect ui file modifications and "auto moc" the modified ui file)?
Start by replacing your file(GLOB ...) with explicitly listing out the files you want to include if you want proper dependency handling. This will also ensure the build is creating dependencies for the set of files you are expecting it to. This answer has more details about why you probably want to do this, aside from the reasons below.
The CMake documentation for AUTOUIC includes this statement:
If a preprocessor #include directive is found which matches
ui_<basename>.h, and a <basename>.ui file exists, then uic will be
executed to generate the appropriate file.
Can you confirm that your .cpp sources have #include directives that follow this pattern? In your file(GLOB ...) you are only capturing the .cpp files and not the .h files, so if you've only got the #include directives in the headers, AUTOUIC may not pick them up properly. It's been a while since I've used this and I can't recall if AUTOUIC would still find them if you only list the .cpp files and not the headers too in your add_executable() call, but it's something for you to try. You also may be facing a similar situation with AUTOMOC if you have headers which use the Q_OBJECT and Q_GADGET macros. So just explicitly list out your .cpp and .h files you give to add_executable() and see if that addresses your problem.
Using Cmake, we use the following command
cmake CMakeLists.txt -G "Visual Studio 11"
to generate a Visual Studio 2012 solution file, which by-default uses /fp:precise as floating point option. Is there any way to change this to /fp:fast in CMake?
You can specify options with various CMake variables, e.g. CMAKE_CXX_FLAGS, CMAKE_CXX_FLAGS_RELEASE, CMAKE_CXX_FLAGS_DEBUG for C++ compiler options. Try set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast"). I think you can also change them from within the GUI (tick the Advanced checkmark). For C you'd have to use the CMAKE_C_FLAGS... variants.
I have a CMakeLists.txt that specifies multiple executables. For only one of these projects, I'm wanting to use the Static Runtime.
I found this solution here: Setting the MSVC runtime in CMake
This involves changed the CMAKE_CXX_FLAGS and CMAKE_C_FLAGS (as well as others).
However, doing something like this will change the runtime library for every project. With my testing, doesn't matter where you set these, it changes it for everything.
Is there any way to do this for just one project?
You'd be able to do this if you give your "Static Runtime" executable its own CMakeLists.txt file and include it from the parent one via add_subdirectory.
Variables set in the subdirectory CMakeLists.txt don't affect similar ones in the parent scope, so you can have the /MD or /MDd flags in the parent CMAKE_<LANG>_FLAGS_<BUILD>, and replace these with /MT or /MTd in the subdirectory.
Note that even though the command is called add_subdirectory, it need not refer to an actual subdirectory in the filesystem sense - just some other directory with its own CMakeLists.txt.
vcproj files for Visual Studio contain various settings or properties which affect the build. For instance, a few of the ones that a project that I'm trying to convert to cmake uses are
StringPooling="true"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
There are of course plenty of others that could be set. The question is how to set them when the project is generated using cmake. Does anyone have any idea how to set these sort of properties when using cmake other than editing the vcproj file after the fact? I can't find anything explaining how these sort of properties might be set via cmake. The only ones that I know how to set are ones that cmake specifically has cross-platform stuff for (e.g. PreprocessorDefinitions or AdditionalIncludeDirectories). But I need to be able to set ones that are specific to Visual Studio.
For the flags you've listed, you'd add the following to your CMakeLists.txt:
if(MSVC)
# StringPooling: true == /GF false == /GF-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GF")
# RuntimeLibrary
# 0 (MultiThreaded) == /MT
# 1 (MultiThreadedDebug) == /MTd
# 2 (MultiThreadedDLL) == /MD
# 3 (MultiThreadedDebugDLL) == /MDd
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
# TreatWChar_tAsBuiltInType: true == /Zc:wchar_t false == /Zc:wchar_t-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:wchar_t")
# WarningLevel: /W<level 0 to 4> or /Wall
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
# Detect64BitPortabilityProblems: /Wp64 - Deprecated since VC++ 2010
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wp64")
endif()
You can group these in one call if you want:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GF /Zc:wchar_t /W3 /Wp64")
If you only need to add a flag to a single target (say, MyTestExe), you can do:
set_target_properties(MyTestExe PROPERTIES COMPILE_FLAGS "/GF- /W2")
Options set via this target-specific method will override any conflicting ones in the general CMAKE_CXX_FLAGS variable.
For further info on these commands do:
cmake --help-variable "CMAKE_<LANG>_FLAGS_DEBUG"
cmake --help-command set_target_properties
cmake --help-property COMPILE_FLAGS
The Visual Studio compiler options are listed here.
Each of these properties corresponds to a command-line option of the compiler (cl). You set these command line options in your CMakeList (using variables like CMAKE_CXX_FLAGS, commands like add_definitions() and properties like COMPILE_FLAGS) and CMake automatically translates them to the settings in .vc[x]proj files when generating them. Those it does not understand are just added as "Additional command-line options".
In general, you can do it like this:
set_target_properties(target_name
PROPERTIES VS_GLOBAL_CAExcludePath "....")
"VS_GLOBAL_ can be set to add a Visual Studio project-specific global variable. Qt integration works better if VS_GLOBAL_QtVersion is set to the Qt version FindQt4.cmake found. For example, “4.7.3”" source: https://cmake.org/cmake/help/v3.20/prop_tgt/VS_GLOBAL_variable.html