CMake Visual Studio 'Debug' Folder - visual-studio

Visual Studio insists that it has to create executables in bin/Debug/ instead of just bin/, when using CMake.
Is there a way to fix this?

Yes, but is not really pretty...
You will need to update the RUNTIME_OUTPUT_DIRECTORY, LIBRARY_OUTPUT_DIRECTORY and ARCHIVE_OUTPUT_DIRECTORY properties on ALL your targets. And you will need to do this for every configuration (Debug, RelWithDebInfo, etc.)
The easiest way is to do this "globally" with their CMAKE_... equivalents. E.g. check the following sample which sets bin/ and lib/ as the "global" binary/library output-directories:
# First for the generic no-config case (e.g. with mingw)
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
# Second, for multi-config builds (e.g. msvc)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/lib )
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
Alternatively, you can try to run through all the available targets and modify its properties afterwards...
Note that this does not set the location of your .pdb files. I still have not found a satisfying way to put all the relevant .pdb files in the bin/ directory.

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

Can't have CMake property ADDITIONAL_CLEAN_FILES delete a simple file

My build system manually generates some files from others. It's using Visual Studio 2015 with CMake 3.11.4. It uses ADD_CUSTOM_TARGET to invoke some internal scripts. Those scripts end up creating a file containing the timestamp when files where generated and this file is later used to only generate what needs to be.
I want this file containing the timestamp to be deleted when we clean the solution (In Visual Studio, "Build" -> "Clean solution"). I tried to add some CMake instruction:
SET_TARGET_PROPERTIES( MY_TARGET PROPERTIES ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
SET_PROPERTY( TARGET MY_TARGET APPEND PROPERTY ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
SET_PROPERTY( GLOBAL APPEND PROPERTY ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
SET_DIRECTORY_PROPERTIES( PROPERTIES ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
But none of them makes the file be deleted when I clean.
Is this doable and if so, what am I doing wrong?

Visual Studio 15 2017 and cmake release builds

I am try to convert our visual studio builds to use cmake. For the most part it's working; the debug build works like a champ! But when I try to create a "release" build, a "Debug" directory is created inside the build/release directory.
C:\repos\source\build\Release\Debug>ls
dep1.dll dep1.ilk dep1.pdb test.pdb dep2.pdb
dep1.exp dep1.lib test.lib dep2.lib
Why is the compiler creating a Debug directory inside the release directory? It looks bad, I don't want there to be any confusion between debug and release! Putting a "Debug" directory inside the release directory looks "hacky" to me.
The first dependency and test library are built successfully but the libraries and test executables are dumped inside "release/Debug" directory, not inside the "build/release" directory. Because upper level dependencies are linking inside the "build/release", I expect to find all build artifacts in the "build/release" directory.
In my CMakeLists.txt, I set the CMAKE_LIBRARY_OUTPUT_DIRECTORY to build/Release. This is created and used, but like I said earlier, a Debug directory is created and is used to put all built targets. See snippet of proj1.cmake
function(SET_OUTPUT_DIRECTORIES build_path build_type)
MESSAGE ( "SET_OUTPUT_DIRECTORIES: building as ${build_type}")
if( build_type STREQUAL "Debug" )
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${build_path}/${build_type} PARENT_SCOPE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${build_path}/${build_type} PARENT_SCOPE)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${build_path}/${build_type} PARENT_SCOPE)
SET(VS_INTERMEDIATE_DIRECTORY_DEBUG} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} )
elseif( build_type STREQUAL "Release" )
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${build_path}/${build_type} PARENT_SCOPE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${build_path}/${build_type} PARENT_SCOPE)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${build_path}/${build_type} PARENT_SCOPE)
SET(VS_INTERMEDIATE_DIRECTORY_RELEASE} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} )
endif()
endfunction( SET_OUTPUT_DIRECTORIES )
function(SET_OUTPUT_DIRECTORIES_1 build_path build_type)
MESSAGE ( "SET_OUTPUT_DIRECTORIES: building as ${build_type}")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${build_path}/${build_type} PARENT_SCOPE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${build_path}/${build_type} PARENT_SCOPE)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${build_path}/${build_type} PARENT_SCOPE)
SET(CONFIG_DIR ${build_path}/${build_type} PARENT_SCOPE)
endfunction( SET_OUTPUT_DIRECTORIES )
Snippets of CMakeLists.txt
SET_OUTPUT_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BUILD_TYPE})
SET_OUTPUT_DIRECTORIES_1(${CMAKE_BINARY_DIR} ${CMAKE_BUILD_TYPE})
# Executable we want cmake to build
add_executable(proj1 ${SRC} ${HDR} )
ADD_DEPENDENCIES( proj1 dep1 dep4)
TARGET_LINK_LIBRARIES( proj1 ${dep1} ${dep2} ${dep3} ${dep4} )
SET_TARGET_PROPERTIES( proj1 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
TARGET_LINK_LIBRARIES( proj1 debug ${LIBD} optimized ${LIB} )
TARGET_LINK_LIBRARIES(proj1 debug ${Boost_FILESYSTEM_LIBRARY_DEBUG} optimized ${Boost_FILESYSTEM_LIBRARY_RELEASE})
TARGET_LINK_LIBRARIES( proj1 debug ${Boost_DATE_TIME_LIBRARY_DEBUG} optimized ${Boost_DATE_TIME_LIBRARY_RELEASE} )
TARGET_LINK_LIBRARIES( proj1 debug ${Boost_SYSTEM_LIBRARY_DEBUG} optimized ${Boost_SYSTEM_LIBRARY_RELEASE} )
TARGET_LINK_LIBRARIES( proj1 debug ${Boost_THREAD_LIBRARY_DEBUG} optimized ${Boost_THREAD_LIBRARY_RELEASE} )
TARGET_LINK_LIBRARIES( proj1 debug ${Boost_CHRONO_LIBRARY_DEBUG} optimized ${Boost_CHRONO_LIBRARY_RELEASE} )
TARGET_LINK_LIBRARIES( proj1 debug ${Boost_REGEX_LIBRARY_DEBUG} optimized ${Boost_REGEX_LIBRARY_RELEASE} )
Has anyone ever experienced this? I googled stuff for cmake and visual studio, and set vs_intermediate_directory_release to the same path as cmake_library_output_directory. But it doesn't do anything different; It still creates this debug directory inside the build/release directory.
Is this something we cannot change via cmake? Why is this so hard to do, I've been banging my head against this problem for a really long time...any help is help! Thanks in advance.

msvc not generate moc file with CMake automoc

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)

CMake Install target missing when generating VS2013 build

I'm using CMake Guid 3.0.0 and Visual Studio Express 2013 (64-bit). My CMakeLists.txt file does not generate an INSTALL target for my visual studio build. I can compile by building the ALL_BUILD project. I can then run the executable that's left in the Debug and Release folders. What do I need to add in order for the INSTALL target to build?
project(intraoperative_adjustments)
cmake_minimum_required(VERSION 2.8)
if(POLICY CMP0020)
cmake_policy(SET CMP0020 NEW)
endif()
find_package(VTK COMPONENTS
vtkCommonCore
vtkFiltersCore
vtkInfovisCore
vtkInteractionStyle
vtkRenderingFreeTypeOpenGL
vtkIOGeometry
vtkViewsQt
)
include(${VTK_USE_FILE})
if("${VTK_QT_VERSION}" STREQUAL "")
message(FATAL_ERROR "VTK was not built with Qt")
endif()
# Use the include path and library for Qt that is used by VTK.
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
# Set your files and resources here
set( Srcs main.cxx SimpleView.cxx )
set( Hdrs SimpleView.h )
set( MOC_Hdrs SimpleView.h )
set( UIs SimpleView.ui )
set( QRCs Icons/icons.qrc )
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# The rest should just work (sure...)
if(VTK_QT_VERSION VERSION_GREATER "4")
# We have ui files, this will bring in the macro: qt5_wrap_ui
find_package(Qt5Widgets REQUIRED QUIET)
qt5_wrap_ui(UI_Srcs ${UIs})
qt5_add_resources(QRC_Srcs ${QRCs} )
source_group("Resources" FILES
${UIs}
${QRCs}
${EXE_ICON} # Not present
)
source_group("Generated" FILES
${UI_Srcs}
${MOC_Srcs}
${QRC_Srcs}
${QRC_Srcs}
)
add_executable(intraoperative_adjustments
${Srcs} ${Hdrs} ${UI_Srcs} ${MOC_Hdrs} ${QRC_Srcs})
qt5_use_modules(intraoperative_adjustments Core Gui Widgets)
target_link_libraries(intraoperative_adjustments ${VTK_LIBRARIES})
else()
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
# Use what VTK built with
set(QT_QMAKE_EXECUTABLE ${VTK_QT_QMAKE_EXECUTABLE} CACHE FILEPATH "")
set(QT_MOC_EXECUTABLE ${VTK_QT_MOC_EXECUTABLE} CACHE FILEPATH "")
set(QT_UIC_EXECUTABLE ${VTK_QT_UIC_EXECUTABLE} CACHE FILEPATH "")
qt4_wrap_ui(UI_Srcs ${UIs})
qt4_wrap_cpp(MOC_Srcs ${MOC_Hdrs} )
qt4_add_resources(QRC_Srcs ${QRCs})
source_group("Resources" FILES
${UIs}
${QRCs}
${EXE_ICON} # Not present
)
source_group("Generated" FILES
${UI_Srcs}
${QRC_Srcs}
${QRC_Srcs}
)
add_definitions(-DQT_GUI_LIBS -DQT_CORE_LIB -DQT3_SUPPORT)
add_executable(intraoperative_adjustments
${Srcs} ${Hdrs} ${UI_Srcs} ${MOC_Hdrs} ${QRC_Srcs})
target_link_libraries(intraoperative_adjustments
${QT_LIBRARIES}
${VTK_LIBRARIES}
)
endif()
You have to create the INSTALL target using CMake's install command. See the according CMake documentation for more details.

Resources