Hide <project>_automoc targets in CMake - c++

I am trying to use the CMAKE_AUTOMOC property to automatically find and compile mocable files.
However, the command set( CMAKE_AUTOMOC ON ) also includes the generated _automoc.cpp file in the Visual Studio "Source Files" filter. This is a problem for two reasons :
It creates the filter even if it was not used before, and therefore pollutes VS explorer.
It adds an additionnal file that should not be manually modified to the solution, in the middle of other source files.
I would like to know if it possible to :
1) Prevent CMake from including this file to the Visual Studio filters. I searched and found https://cmake.org/Bug/print_bug_page.php?bug_id=13788.
However using
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
SET_PROPERTY(GLOBAL PROPERTY AUTOMOC_FOLDER automoc)
did not change anything to my problem.
2) Remove a given entry from the .vcxproj.filters file using CMake, using a command similar to
source_group( "Source Files" FILES "filepath" )
which is used to add the entry "filepath" to the "Source Files" filter.
I am currently using CMake 3.5, VS 2015 and Qt 5.6. Here is a shortened version of the CMake that reproduces the problem :
project( myproj )
# Some stuff to include Qt libraries
# ...
set( CMAKE_AUTOMOC ON )
# These 2 lines don't change anything
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
SET_PROPERTY(GLOBAL PROPERTY AUTOMOC_FOLDER automoc)
# Create project
add_executable( ${PROJECT_NAME} "main.cpp" )
In the VS filter named "Source Files", I can see main.cpp and myproj_automoc.cpp, which does not even exist before the first compilation (trying to open it with VS sends an error "Cannot open the file"). In myproj.vcxproj.filters there is an entry :
Include="C:\pathto\build\myproj_automoc.cpp">
<Filter>Source Files</Filter>
which shouldn't be here since I did not ask for it.
Am I missing something ?
Thank you for your help!

I've had trouble getting this to work as documented as well. It looks like they renamed the variable in one of the releases. As of Cmake 3.0.2, you can do the following:
cmake_minimum_required(VERSION 3.0.2)
project(MyProj CXX)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER MyAutoMocFolder)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
add_executable(${PROJECT_NAME}
${MyProj_HEADERS}
${MyProj_SRCS}
${MyProj_QRC}
${MyProj_UI})
Note that you have to use set_property and the property name is now AUTOGEN_TARGETS_FOLDER.
In Xcode, this puts the generated _automoc folders in the "MyAutoMocFolder" instead of littering the parent folders with them. In Visual Studio the automoc folders in the folder as well.
It doesn't however hide the project_automoc.cpp files that are generated. To move those you have to define a source group, as Armand pointed out:
source_group( MyAutoMocFolder FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_automoc.cpp )

As of CMake 3.9, you can use AUTOGEN_SOURCE_GROUP to filter MOC files.
set(CMAKE_AUTOMOC ON)
set_property(GLOBAL PROPERTY AUTOGEN_SOURCE_GROUP "Generated Files")

Related

Do I need a Shared library in a CMAKE project with several subdirectories? How do I do it?

I need to implement a StatisticsLogger library on to a C++/C solution built with cmake and compiled with VS#2010. The project uses the ADTF API, since is built for the ADTF framework.
The solution is composed by different modules/projects, which include their own CMakeLists.txt.
My doubt/problem is regarding the library and Cmake, I need it to be accesible to every single module, but it can't be copied, them all should access the same StatisticsLogger library, that I have implemented with a Singleton.
When I run the framework, the concurrent execution accesses StatsLogger constructor once on each module, like if I had created one StatsLogger on each module, making it unable to trace together all the data I want to log and difficulting file handling.
This is how I added the library in CMakeLists.txt:
add_library(loggerModule
${DSTD_DIR}/dstdfloat.h
${DSTD_DIR}/dstdint.h
${DSTD_DIR}/dstdbool.h
${SUPT_DIR}/logg/statslogger.h
${SUPT_DIR}/logg/statslogger_c_connector.h
${SUPT_DIR}/logg/statslogger_c_connector.cpp
${SUPT_DIR}/logg/statslogger.cpp
)
#set_target_properties(loggerModule PROPERTIES VERSION ${PROJECT_VERSION})
#set_target_properties(loggerModule PROPERTIES PUBLIC_HEADER include/mylib.h)
link_libraries(loggerModule)
It would seem that adding SHARED property to the command add_library would do the job, but Im not capable of getting it working. It returns several link problems.
So, regarding my doubt, Is this the way to get the desired funcionality, to make the library SHARED? What am I doing wrong?
Main CMakeLists.txt:
# CMAKE for test filter build
cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
# Set default install prefix
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR})
# Set project name
project(${PROJECT_NAME})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Environment checks
find_package(ADTF 2.14.2 REQUIRED)
IF (NOT DEFINED ADTF_FOUND)
MESSAGE( FATAL_ERROR "ADTF was NOT found!!!")
ENDIF()
find_package(ADTF_DISPLAY_TOOLBOX REQUIRED)
IF (NOT DEFINED ADTF_DISPLAY_TOOLBOX_FOUND)
MESSAGE( FATAL_ERROR "ADTF_DISPLAY_TOOLBOX was NOT found!!!")
ENDIF()
set(COMPLETE_PROJECT_BINARY_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/${PROJECT_BINARY_OUTPUT_DIRECTORY})
# Set path to sw module dependencies
set(COMMON_DIR ${CMAKE_SOURCE_DIR}/common)
set(DSTD_DIR ${CMAKE_SOURCE_DIR}/common/dstd)
set(INTF_DIR ${CMAKE_SOURCE_DIR}/common/intf)
set(SUPT_DIR ${CMAKE_SOURCE_DIR}/common/supt)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
#option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
include_directories(${DSTD_DIR})
include_directories(${SUPT_DIR}/logg)
add_library(loggerModule SHARED
${DSTD_DIR}/dstdfloat.h
${DSTD_DIR}/dstdint.h
${DSTD_DIR}/dstdbool.h
${SUPT_DIR}/logg/statslogger.h
${SUPT_DIR}/logg/statslogger_c_connector.h
${SUPT_DIR}/logg/statslogger_c_connector.cpp
${SUPT_DIR}/logg/statslogger.cpp
)
#set_target_properties(loggerModule PROPERTIES VERSION ${PROJECT_VERSION})
#set_target_properties(loggerModule PROPERTIES PUBLIC_HEADER include/mylib.h)
link_libraries(loggerModule)
# Set commands for BB nodes generation
# ...and dependencies for generation
# Go into sub-directory with filter sources
add_subdirectory(${CMAKE_SOURCE_DIR}/tool/adtf/af_acca)
#[33 other add_subdirectories commands]
Example subdirectory CMakeLists.txt:
# External required components have to be provided with path variables
# Internal required components have to be connected to the source file list
if(NOT DEFINED DSTD_DIR)
message( FATAL_ERROR "AF_CDAS requires DSTD_DIR" )
endif()
if(NOT DEFINED INTF_DIR)
message( FATAL_ERROR "AF_CDAS requires INTF_DIR" )
endif()
if(NOT DEFINED SUPT_DIR)
message( FATAL_ERROR "AF_CDAS requires SUPT_DIR" )
endif()
set(CDAS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../)
include_directories(${COMMON_DIR})
[some more includes]
#
# CDAS FILES
#
set(CDAS_FILES
${CDAS_DIR}/src/cdas/cdas.c
${CDAS_DIR}/src/cdas/cdas.h)
source_group("cdas\\files" FILES ${CDAS_FILES})
#
# CDAS ADTF WRAPPER
#
set(CDAS_ADTF_WRAPPER
${CDAS_DIR}/tool/adtf/af_cdas/af_cdas_conf.h
${CDAS_DIR}/tool/adtf/af_cdas/af_cdas.h
${CDAS_DIR}/tool/adtf/af_cdas/af_cdas.cpp)
source_group("cdas\\adtf" FILES ${CDAS_ADTF_WRAPPER})
adtf_add_filter(CDAS
# List source and header files of your filter and its required components
# ${MAIN_FILES}
${CDAS_FILES}
${CDAS_ADTF_WRAPPER}
)
# stdafx.h workaround
if (MSVC)
set_target_properties(CDAS PROPERTIES COMPILE_FLAGS "/Y-")
endif(MSVC)
# MANDATORY PATH SETTING !!!
install (TARGETS CDAS DESTINATION ${COMPLETE_PROJECT_BINARY_OUTPUT_DIR}/debug CONFIGURATIONS Debug)
install (TARGETS CDAS DESTINATION ${COMPLETE_PROJECT_BINARY_OUTPUT_DIR}/release CONFIGURATIONS Release)
adtf_set_folder(CDAS filter)
When using this files, I get the following error:
LINK : fatal error LNK1181: cannot open input file '......\Release\loggerModule.lib' [C:\Users\inno\Desktop\rad
ar_processing\test\adtf\build\win64_vc100\tool\adtf\af_aoca\AOCA.vcxproj]
There isn't any loggerModule.lib in the Release folder, but a loggerModule.dll. In the Debug folder there is a .lib, but copying it to Release won't solve the problem.
I never got too familiar with Cmake, and I am trying to learn it, so I don't know what is going on here, if I am doing something wrong, or my approach wasn't good from the beggining.

clang in neovim giving pp_file_not_found error for c++/pytorch basic example

I'm following this very basic c++/pytorch example:
pytorch_installing
And I can walk through this example with no errors. However, when creating the example-app.cpp file (or editing it at any point in time) with neovim, clang throws an error 'torch/torch.h' file not found [clang: pp_file_not_found]. My CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)
find_package(Torch REQUIRED)
include_directories(SYSTEM /home/username/Downloads/libtorch/)
set(CMAKE_PREFIX_PATH "/home/username/Downloads/libtorch/share/cmake/Torch")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
This isn't a big issue for me with this small of a project. But I will be working on a larger project with libtorch and would like clang to recognize <torch/torch.h>. There were a couple similar Stackoverflow questions, but no answers.
Update:
I believe this is happening because clang is not seeing torch/torch.h because it is not part of the include paths. I printed the include paths for clang and it was not list. So I tried adding the include paths of libtorch to /usr/include/ but then it has issues seeing other header files referenced by header files I added. So I added the libtorch/include/torch/csrc/api/include/torch/ directory to /usr/include so that it can read #include <torch/torch.h. But then other header files are referenced in those header files with specified directory paths outside of the libtorch/include/torch/csrc/api/include/torch/ path.
For example, libtorch/include/torch/csrc/ contains WindowsTorchApiMacro.h. There are other paths within the libtorch directory that contain more header files. I tried to add all header files to \usr\include but still received an error. I'm sure the package as a whole needs to be used. The original cmake file looks like this:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
So cmake is able to find and reference all of those header files properly, and I know you can compile it at the command line with clang, but how can clang within neovim (during editing) see this package without error? I thought about using a package manager like vcpkg, but they do not have libtorch available, unfortunately. I can include output from a verbose and successful cmake run if needed.
Since the compilation succeeds with cmake-make, it is possible to ask CMake to generate the compilation database (typically a compile_commands.json file) with cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1.
Once the file is available, it can be read by the autocompletion compiler (clang in this case), which prevents the autocompleter from being lost in the filesystem, because all flags and headers are specified for all compilation units.
The compilation database just needs to be put where the autocompletion plugin expects it to be.

CMake qt input library postfix for custom debug build

I'm stuck with writing a cmake file for multiconfiguration IDE (Visual Studio).
My goal is to add a custom configuration and tell Visual Studio that I want to use debug libs of Qt (qtcored.lib) as it is done when I pick Debug configuration. With code below, I have release libraries in a linker input when I pick CustomDebug configuration
Does anyone know how to achieve that?
Thanks
cmake_minimum_required(VERSION 3.12.0)
project(custom-conf)
find_package(Qt5Core CONFIG REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(SRC main.cpp)
set(QT_LIBS Qt5::Core)
add_executable(custom-conf WIN32 ${SRC})
target_link_libraries(custom-conf ${QT_LIBS})
#
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
set(CMAKE_CONFIGURATION_TYPES "CustomDebug;Debug;Release" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_CUSTOMDEBUG "/debug")
endif()
I want to use debug libs of Qt (qtcored.lib) as it is done when I pick Debug configuration.
With the IMPORTED target this can be easiliy achieved by using MAP_IMPORTED_CONFIG<CONFIG> target property:
# For CustomDebug configuration of the main project
# use Debug configuration of the IMPORTED target
set_target_properties(Qt5::Core PROPERTIES
MAP_IMPORTED_CONFIG_CUSTOMDEBUG DEBUG)
With setting CMAKE_MAP_IMPORTED_CONFIG<CONFIG> variable you may automatically set the property for all IMPORTED targets:
set(CMAKE_MAP_IMPORTED_CONFIG_CUSTOMDEBUG DEBUG)
#...
# This call will create IMPORTED target Qt5::Core which
# MAP_IMPORTED_CONFIG_CUSTOMDEBUG property is already set.
find_package(Qt5Core CONFIG REQUIRED)
(The variable assignment should come before any call like find_package which creates IMPORTED target.)

Visual studio project for header only library

I'm creating a CMake project whose two main files are:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(CPP_Algorithms_and_Data_Structures)
set( CMAKE_CXX_STANDARD 11 )
#add_subdirectory(./ElementaryAlgorithms)
add_subdirectory(./ElementaryDataStructures)
#add_subdirectory(./AdvancedDataStructures)
#add_subdirectory(./GraphAlgorithms)
#set(INCLUDE_FOLDERS
# ./
# ./ElementaryAlgorithms
# ./ElementaryDataStructures
# ./AdvancedDataStructures
# ./GraphAlgorithms)
set(INCLUDE_FOLDERS ./ ./ElementaryDataStructures)
set(HEADER_FILES alg-and-ds.h)
set(SRC_FILES main.cpp alg-and-ds.cpp)
add_executable(alg-and-ds ${SRC_FILES} ${HEADER_FILES})
target_include_directories(alg-and-ds PUBLIC ${INCLUDE_FOLDERS})
target_link_libraries(alg-and-ds elementary-data-structures)
#target_link_libraries(alg-and-ds
# graph-algorithms
# elementary-data-structures
# elementary-algorithms
# advanced-data-structures)
and
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(ElementaryDataStructures)
set( CMAKE_CXX_STANDARD 11 )
if(WIN32)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS YES CACHE BOOL "Export all symbols")
endif()
add_library(elementary-data-structures INTERFACE)
target_include_directories(elementary-data-structures INTERFACE ./)
target_sources(elementary-data-structures INTERFACE
"${CMAKE_CURRENT_LIST_DIR}/list.h"
"${CMAKE_CURRENT_LIST_DIR}/list.tcc")
#set_target_properties(elementary-data-structures PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
I'm using these to generate a visual studio solution, however what I would like to do is to generate a separate project for the header only library.
Basically I had a small list library that I converted to an header only library, by using templates, before such change I was able to generate separate visual studio projects but in the same solution, in this case instead I can see something like this:
But what I'd like to see, assuming this is possible is a separate project for the ElementaryDataStructures.
I'm not an expert in CMake and all the setups, but I would be great if you could help me to figure out how to do it.
Update:
Following suggestion on the comment I got a new project in VS, however there's still a tiny bit that bothers me.
In the picture below I can see both alg-and-ds and ElementaryDataStructures_ referencing the same sources. Is there a way to avoid the alg-and-ds project to show such files?
The update CMakeLists.txt
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(ElementaryDataStructures)
set( CMAKE_CXX_STANDARD 11 )
if(WIN32)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS YES CACHE BOOL "Export all symbols")
endif()
add_library(elementary-data-structures INTERFACE)
target_include_directories(elementary-data-structures INTERFACE ./)
target_sources(elementary-data-structures INTERFACE
"${CMAKE_CURRENT_LIST_DIR}/list.h"
"${CMAKE_CURRENT_LIST_DIR}/list.tcc")
add_custom_target(ElementaryDataStructures_ SOURCES ${CMAKE_CURRENT_LIST_DIR}/list.h ${CMAKE_CURRENT_LIST_DIR}/list.tcc)
As far as I know there is no normal way to do it. Only a hackish one. So you create a custom target which will force MSVC to show the project in the solution tree. Something like this:
add_custom_target(${PROJECT_NAME}_ SOURCES ${PROJECT_SOURCES})
Note the underscore in the name: it is there to differentiate it from the name in the add_library command. Of course you need to replace the variables in my example to yours actual ones.
Another solution is to declare static library with stub source file:
file(TOUCH ${CMAKE_BINARY_DIR}/stub.cpp)
add_library(elementary-data-structures STATIC
"${CMAKE_BINARY_DIR}/stub.cpp"
"${CMAKE_CURRENT_LIST_DIR}/list.h"
"${CMAKE_CURRENT_LIST_DIR}/list.tcc"
)
target_include_directories(elementary-data-structures INTERFACE ./)

How to add CMake includes and libraries to Visual Studio Solution?

I use CMake to generate a Visual Studio 2010 project and solution file. Actually I could set different settings,
like warning level, incremental building flag ect. from CMake. But I can't set additional includes and libraries,
listed in the VC++ Directory configuration tab. Actually I've to set up those directories manually. This is stupid
and boring...
I tried to set the following CMake variables: CMAKE_INCLUDE_PATH, INCLUDE_DIRECTORY
but nothing happend. If i open the project, the additional include directory of the solution is always empty (only standard MSVE settings are given).
I also tired to set this variables after executable creation, but this has also no effect.
This is what i do directly in the header of the cmake
file:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(${MODULE_NAME})
IF (MSVC)
# Activate C++ exception handling
IF (NOT CMAKE_CXX_FLAGS MATCHES "/EHsc")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
ENDIF ()
# Set Warning level always to 4
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
ELSE ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
ENDIF ()
#read path of dependency modules
file(READ "msvc.deps" MSVC_PROPERTIES)
STRING(REGEX REPLACE ";" "\\\\;" MSVC_PROPERTIES "${MSVC_PROPERTIES}")
STRING(REGEX REPLACE "\n" ";" MSVC_PROPERTIES "${MSVC_PROPERTIES}")
FOREACH(e ${MSVC_PROPERTIES})
SET(INCLUDE ${INCLUDE} ${e})
MESSAGE(STATUS "[INFO]: Value ${e}")
ENDFOREACH(e)
INCLUDE_DIRECTORIES(${INCLUDE})
ENDIF ()
In the .deps file I've added to path of my dependeny modules,
line separated:
c:\binrev\development\boost\1.47\includes
c:\binrev\repository\modules\brCore\trunk\includes
Both are read successfully but couldn't be set as additional
include directory in my MSVC solution.
Best regards,
Hellhound
CMake is pretty well documented, if I have understood your question then the commands I think you're looking for are
include_directories(...),
link_directories(...) and
target_link_libraries(...).
Although some configuration is done by setting variables, most of it is done using commands to add certain information to parts of the build and slightly less frequently by setting properties on targets.
I believe that include_directories ("path") somewhere in the CMakeLists.txt does add the path to C++ includes path.
Yes. Although it does not appear in "Include Directories" under the "VC++ Directories" tab, it does show up in the "Additional Include Directories" under C/C++ -> General.