msvc not generate moc file with CMake automoc - visual-studio

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(source_files
a.cpp
b.cpp
...
)
set(header_files
a.hpp
b.hpp
...
)
set(Qt_libs
Qt5::Core
Qt5::Gui
Qt5::Widget
...
)
add_library(demo SHARED ${header_files} ${source_files})
target_link_libraries(demo ${Qt_libs} ...)
set_properties(TARGET demo PROPERTY FOLDER "somewhere")
install(...)
I have a sample CMakeLists.txt shows above.
The most weird thing is, it won't generate those moc files until I manually modified (like adding a empty line to the file) those header files (where Q_OBJECT presents).
The situation not happen every time. But, once it happens, clean build nor deleting whole project file won't help.
I'm using qt 5.11, CMake 3.7, Visual Studio 2015.

You are setting the global setting with set() which could be overwritten.
Please use set_target_properties, for example
project(exampleProj)
add_executable(exampleProj main.cpp)
set_target_properties(exampleProj
PROPERTIES
CMAKE_INCLUDE_CURRENT_DIR ON
CMAKE_AUTOMOC ON)

Related

Cmake : Dependency to run if there's any change

I'm new to Cmake and I have a main output named TARGET. I'm trying to add custom target named _COPY_ASSETS_TARGET as a dependency to main TARGET. I want TARGET to rebuild _COPY_ASSETS_TARGET automatically if there's any change in _COPY_ASSETS_TARGET. _COPY_ASSETS_TARGET should depend on change in folders.
Here's the code I tried to implement:
if (NOT TARGET ${_COPY_ASSETS_TARGET})
add_custom_target(${_COPY_ASSETS_TARGET})
add_dependencies(${_ARGS_PROJECT_TARGET} ${_COPY_ASSETS_TARGET})
set_property(TARGET ${_COPY_ASSETS_TARGET} PROPERTY FOLDER "Targets")
endif()
add_custom_command(TARGET ${_COPY_ASSETS_TARGET}
${_COMMANDS}
VERBATIM
)
I'm trying visual studio to debug and if I rebuild _COPY_ASSETS_TARGET then only I can see the updated output. I would like to know how I can link my folders to _COPY_ASSETS_TARGET so that TARGET automatically builds new code
add_custom_command(OUTPUT ${OUTPUT_DIRECTORY} ${_COMMANDS}
DEPENDS ${DEPENDENT_DIRECTORY}
VERBATIM
)
add_custom_target(${_COPY_ASSETS_TARGET} ALL
DEPENDS ${OUTPUT_DIRECTORY}
)
add_dependencies(${_ARGS_PROJECT_TARGET} ${_COPY_ASSETS_TARGET})
set_property(TARGET ${_COPY_ASSETS_TARGET} PROPERTY FOLDER "Targets")
I found this to be working for my project

cmake cannot open file optimized.lib when trying to add Boost Process

I'm creating a C++ Windows service.
I would like to add Boost Process to my application, but for some reason I keep getting this error:
LINK : fatal error LNK1104: cannot open file 'optimized.lib'
Everything worked fine before I tried adding Boost. When I open my Visual Studio solution, I notice the application is trying to link with an optimized.lib and a debug.lib library that I am unfamiliar with. CMake only tries to link with these libraries when I try to add Boost.
My directory structure:
UpdateService/
CMakeLists.txt
app/
CMakeLists.txt
Driver.cpp
build/
include/
stdafx.h
UpdateService/
# a bunch of *.h files
src/
CMakeLists.txt
# a bunch of *.cpp files
My UpdateService/CMakeLists.txt file:
cmake_minimum_required(VERSION 3.12...3.14)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
project(UpdateService
VERSION 1.0
DESCRIPTION "Service that runs the update manager"
LANGUAGES CXX)
add_subdirectory(src)
add_subdirectory(app)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT UpdateService)
My UpdateService/src/CMakeLists.txt file:
cmake_minimum_required(VERSION 3.12...3.14)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
set(FMT_DIR "E:/Repositories/fmt-5.3.0")
set(FMT_INCLUDE "${FMT_DIR}/include")
set(SPDLOG_INCLUDE "E:/Repositories/spdlog/include")
set(Boost_DEBUG ON)
# set(Boost_USE_STATIC_LIBS ON)
# set(Boost_USE_STATIC_RUNTIME ON)
find_package(Boost 1.67 REQUIRED COMPONENTS system filesystem)
# Needed to suppress a warning in boost process.
add_compile_definitions(_SCL_SECURE_NO_WARNINGS)
add_library(UpdateServiceLib STATIC
"${CMAKE_SOURCE_DIR}/include/stdafx.h"
"${CMAKE_SOURCE_DIR}/include/UpdateService/CLI11.hpp"
"${CMAKE_SOURCE_DIR}/include/UpdateService/Config.h"
"${CMAKE_SOURCE_DIR}/include/UpdateService/CmdParams.h"
"${CMAKE_SOURCE_DIR}/include/UpdateService/LogUtils.h"
"${CMAKE_SOURCE_DIR}/include/UpdateService/ServiceBase.h"
"${CMAKE_SOURCE_DIR}/include/UpdateService/UpdateService.h"
"${FMT_DIR}/src/format.cc"
"Config.cpp"
"CmdParams.cpp"
"LogUtils.cpp"
"ServiceBase.cpp"
"UpdateService.cpp")
target_include_directories(UpdateServiceLib PUBLIC
"${Boost_INCLUDE_DIRS}"
"${CMAKE_SOURCE_DIR}/include"
"${FMT_INCLUDE}"
"${SPDLOG_INCLUDE}")
target_link_libraries(UpdateServiceLib PUBLIC "${Boost_LIBRARIES}")
My UpdateService/app/CMakeLists.txt file:
cmake_minimum_required(VERSION 3.12...3.14)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
add_executable(UpdateService "Driver.cpp")
target_include_directories(UpdateService
PRIVATE "${CMAKE_SOURCE_DIR}/include" "${FMT_INCLUDE}" "${SPDLOG_INCLUDE}")
target_link_libraries(UpdateService PRIVATE UpdateServiceLib)
I am building the project with something like this:
rmdir /S /Q build
mkdir build
mkdir build\x64
pushd build\x64
cmake -G "Visual Studio 14 2015 Win64" ..\..
cmake --build . --config Debug
popd
Remove double quotes around ${Boost_LIBRARIES}.
Double quotes tells CMake to treat enclosed value as a single parameter, but Boost_LIBRARIES is actually a list (multivalue variable).
Normally, double quotes are used only for:
"string literals" (when an argument contains no variables' dereferences), e.g.
"abc"
when it is definitely known that an argument represents a single value, e.g.
"${CMAKE_SOURCE_DIR}/include"
Plural number for "LIBRARIES" word implies that Boost_LIBRARIES variable may contain multiple values, so do not enclose it with double quotes.

CMake: How to show headers in "Header files" in Visual Studio project?

I have created a simple library project in C++ and added CMake file to automatically generate a Visual Studio project. My small project contains only 2 files:
include/
testproject/
testproject.h
src/
testproject.cpp
CMakeLists.txt
Header file now in External Dependencies (screenshot). How to display it in the section "Headers"? (or any other. Just not "External Dependencies")
CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(PROJECTNAME testproject)
PROJECT(${PROJECTNAME})
FILE(GLOB MY_HEADERS "include/*.h")
FILE(GLOB MY_SOURCES "src/*.cpp")
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
ADD_LIBRARY(
${PROJECTNAME} STATIC
${MY_HEADERS} ${MY_SOURCES}
)
Note: If change dirs struct to
include/
testproject.h
src/
testproject.cpp
CMakeLists.txt
result will be like on a screenshot. Header file in "Header files". But I need in previous project structure
Use GLOB_RECURSE:
GLOB_RECURSE will generate a list similar to the regular GLOB, except it will traverse all the subdirectories of the matched directory and match the files. Subdirectories that are symlinks are only traversed if FOLLOW_SYMLINKS is given or cmake policy CMP0009 is not set to NEW. See cmake –help-policy CMP0009 for more information.
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(PROJECTNAME testproject)
PROJECT(${PROJECTNAME})
FILE(GLOB_RECURSE MY_HEADERS "include/*.h")
FILE(GLOB MY_SOURCES "src/*.cpp")
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
ADD_LIBRARY(
${PROJECTNAME} STATIC
${MY_HEADERS} ${MY_SOURCES}
)

Multiple CMake Projects in one CMakeLists.txt

I want to have two projects that build off the same source files, with the second one just having a small subset, and a few different defines and build flags.
When I try something like this:
SET (this_target PROJECT1)
PROJECT(${this_target})
...
ADD_EXECUTABLE(#{this_target} ...)
SET (this_target PROJECT2)
PROJECT(${this_target})
...
add_definitions (-DMYDEFINE)
TARGET_LINK_LIBRARIES( ${this_target} -myflag )
ADD_EXECUTABLE(#{this_target} ...)
It ends up creating two projects, with seemingly the proper source files and the like, but for some reason, at least in Visual Studio 2010, both projects seem to get MYDEFINE defined and myflag in the linker flags.
I'm not sure why it seems to work for files, but not flags.
Firstly, you must use different names for your executables
If you want to add specific definitions to your targets, you may use set_target_properties, so each target will have their own properties (for example, compile definitions).
# compile and link first app
add_executable(prg1 ${CommonSources} ${Prg1SpecificSources})
target_link_libraries(prg1 lib1 lib2 lib3)
#set target-specific options
set_target_properties(prg1 PROPERTIES COMPILE_DEFINITIONS "FOO=BAR1")
#...
# compile and link second app
add_executable(prg2 ${CommonSources} ${Prg2SpecificSources})
target_link_libraries(prg2 lib1 lib2 lib3)
#set target-specific options
set_target_properties(prg1 PROPERTIES COMPILE_DEFINITIONS "FOO=BAR2")
If you want to override linking flags, you may use set_target_properties with LINK_FLAGS
I've found that putting multiple targets in one CMakeLists.txt causes intermittent build failure on Visual Studio 2010, due to colliding accesses to generate.stamp (though I can't rule out that I'm doing something wrong). Thus, you may have to put the targets in different CMakeLists.txt files, or find some other workaround.

Disabling a Visual Studio project for building using cmake

I'm generating a VS2010 solution with a few projects (currently 4, will be up to 10-20 in the end). I only want one of them to build; the rest should be disabled. I can do this manually by going into the configuration manager and unchecking the boxes I don't want, but obviously this isn't a good solution.
Is there something I can add to the CMakeLists.txt file for a project that will cause it to do this? Searching through the docs, google and SO yielded nothing.
Update: Here is my root CMakeLists.txt in case that helps:
cmake_minimum_required(VERSION 2.8)
add_definitions(-DCOMPILER_MSVC)
project (PDEngine)
set(LINKER_LANGUAGE CXX)
add_subdirectory (units/platform)
add_subdirectory (units/render_api)
add_subdirectory (units/memory)
add_subdirectory (units/game)
set(custom_exe "${CMAKE_CURRENT_BINARY_DIR}/units/Platform/Debug/Platform.lib2")
add_custom_command(OUTPUT ${custom_exe}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat -j $ENV{NUMBER_OF_PROCESSORS}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat
)
#add_custom_command(OUTPUT ${custom_exe_clean}
#COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat -c
#DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat
#)
add_custom_target(bam ALL DEPENDS ${custom_exe})
#add_custom_target(bamclean ALL DEPENDS ${custom_exe_clean}})
(The bam.bat stuff is based off of the answer I got here: How do I configure CMake to make the VS solution use a specific build commandline? )
And here's the CMakeLists.txt for the "platform" project:
cmake_minimum_required (VERSION 2.8)
project (Platform)
set (COMPILER_MSVC 1)
include_directories(${Platform_SOURCE_DIR}/include)
file(GLOB Project_HEADERS ${Platform_SOURCE_DIR}/include/platform/*.h)
source_group("Headers" FILES ${Project_HEADERS})
add_library(Platform STATIC EXCLUDE_FROM_ALL src/*.cpp ${Project_HEADERS})
So if what you want to do is not build something by default, you can remove it from the "ALL" target (which shows up in Visual Studio as ALL_BUILD). The way you do this is with the target property EXCLUDE_FROM_ALL, or by passing EXCLUDE_FROM_ALL to add_executable and add_library. (Custom targets default to EXCLUDE_FROM_ALL, so there, to do the reverse, you add ALL to the arguments to add_custom_target).
Then, all your targets will show up, but when clicking "build solution", only the ones you want will build. Others can be built by right clicking them and choosing "Build", like the built-in INSTALL project/target.
There is a EXCLUDE_FROM_DEFAULT_BUILD target property for that purpose.
See https://stackoverflow.com/a/14911387/594456.

Resources