Enable WPP tracing in a CMake generated Visual Studio project - cmake

I have a C++ dll project, that is generated from a CmakeLists.txt file, that looks something like this (using Visual Studio 2019):
cmake_minimum_required (VERSION 3.23)
include(CMakeParseArguments)
project(test_sln)
set(CMAKE_GENERATOR_TOOLSET "Visual Studio 16 2019")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#add files to project
...
#
add_library(test_proj SHARED ${SOURCES})
set_target_properties(test_proj PROPERTIES
LINKER_LANGUAGE CXX
VS_PLATFORM_TOOLSET "WindowsApplicationForDrivers10.0"
)
I need to enable the WPP tracing setting in the generated .vcxproj file by setting the following options:
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>$(ProjectDir)\trace.h</WppScanConfigurationData>
I have tried setting the VS_SETTINGS property the following way:
set_property(TARGET test_proj PROPERTY VS_SETTINGS "WppEnabled=True")
But it ha no effect on the file, as it seems to be able to set metadata only for individual files?
Is there a way to easily set other settings in a .vcxproj file?

Related

CMake conditional for Release,Debug and Etc

I am working on a CMake project that need to set specific paths for each configuration type (e.g., RELEASE, DEBUG, MINSIZEREL and RELWITHDEBINFO) for a static library in linking process. Because I have different versions of my static libraries that is used on Debug and Release versions.
So far, I have done this below in order to set the folder "release" or "debug" for my static library that I am try to link:
# Here we need to determine our build type and set the each one specific 3rd library for our binary
if( CMAKE_BUILD_TYPE STREQUAL "Debug")
#set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install)
#message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
set(THIRDLIBS_BUILD_TYPE "debug")
elseif( CMAKE_BUILD_TYPE STREQUAL "Release")
#SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install.deb)
#message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
set(THIRDLIBS_BUILD_TYPE "release")
elseif( CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
#SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install.deb)
#message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
set(THIRDLIBS_BUILD_TYPE "debug")
elseif( CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
#SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install.deb)
#message( STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" )
set(THIRDLIBS_BUILD_TYPE "release")
else()
MESSAGE( STATUS "CMAKE_BUILD_TYPE not set yet ${CMAKE_BUILD_TYPE}" )
endif()
if (WIN32)
set(THIRD_LIBS
../external_libs/mylibalpha/win64/${THIRDLIBS_BUILD_TYPE}/libalpha
../external_libs/mylibbeta/win64/${THIRDLIBS_BUILD_TYPE}/libbeta
)
endif(WIN32)
However, in my Visual Studio, I noticed that on each project build type (RELEASE, DEBUG, MINSIZEREL and RELWITHDEBINFO) the ${THIRDLIBS_BUILD_TYPE} variable is empty and not getting properly set. I am basically getting an error on linking showing that cannot find the external_libs/mylibalpha/win64//libalpha.lib and I should be getting something like this external_libs/mylibalpha/win64/release/libalpha.lib
What is wrong with my CMakeLists.txt script?
Variable CMAKE_BUILD_TYPE has no sense with multiconfiguration generators, and Visual Studio is one of such generators.
Canonical way for define in CMake a pre-built library which have different locations for different configuration is to create IMPORTED library target with several properties IMPORTED_LOCATION_<CONFIG> to be set:
add_library(thirdPartyLib IMPORTED UNKNOWN)
set_target_properties(thirdPartyLib PROPERTIES
IMPORTED_LOCATION_RELEASE
${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/release/libalpha.a
IMPORTED_LOCATION_DEBUG
${CMAKE_CURRENT_SOURCE_DIR}/external_libs/mylibalpha/win64/debug/libalpha.a
)
Then you need to create a mapping between build types of the main project and build types of the IMPORTED target.
Such mapping could be created either on per-target basis, by setting properties MAP_IMPORTED_CONFIG_<CONFIG>:
set_target_properties(thirdPartyLib PROPERTIES
# For Debug version of the project use DEBUG-suffixed library location
MAP_IMPORTED_CONFIG_DEBUG DEBUG
# For Release version of the project use RELEASE-suffixed library location
MAP_IMPORTED_CONFIG_RELEASE RELEASE
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed library location
MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG
# For MinSizeRel version of the project use RELEASE-suffixed library location
MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE
)
Alternatively, the mapping could be created for all IMPORTED targets by setting variables CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>. Note, that these variables should be set before creation of IMPORTED target(s).
# For Debug version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG DEBUG)
# For Release version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE RELEASE)
# For ReleaseWithDebInfo version of the project use DEBUG-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO DEBUG)
# For MinSizeRel version of the project use RELEASE-suffixed locations of IMPORTED targets
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE)
Having IMPORTED libraries and configurations mapping, using these libraries is quite straightforward:
target_link_libraries(my_exe PRIVATE thirdPartyLib)
Depending on the build type of the project, CMake will automatically select proper library for linking.

Cmake library outdir

I cant output my lib to my lib folder , I tried this , and it outputs to lib/debug
but I need output mylib.lib exactly to ${CMAKE_CURRENT_SOURCE_DIR}/lib
add_library(mylib STATIC ${SOURCES} ${HEADERS})
set_target_properties(mylib PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
)
In CMake, Visual Studio is a multiconfiguration generator. Such generators have a specific when interpret ARCHIVE_OUTPUT_DIRECTORY property for the target:
Multi-configuration generators (Visual Studio, Xcode, Ninja Multi-Config) append a per-configuration subdirectory to the specified directory unless a generator expression is used.
If you want to use ${CMAKE_CURRENT_BINARY_DIR}/lib as output directory for the library only for Debug build, and Release build is not interesting for you, then set ARCHIVE_OUTPUT_DIRECTORY_DEBUG property instead:
set_target_properties(mylib PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib
)
If you want to specify different output directories for Debug and Release builds, then set both properties:
set_target_properties(mylib PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib-release
)
Setting the same directory for both Debug and Release builds is discouraged: That way Release build will overwrite library created in Debug and vise versa.
Placing build artifacts (e.g. libraries and executables created by the project) in the source directory, as implied by ${CMAKE_CURRENT_SOURCE_DIR}/lib output directory, is discouraged too.
Usually, build artifacts are placed in the build directory and its descendant directories. So, deleting build directory completely removes the build.
If you want to store some build artifacts for use even when build directory is remove, then install those artifacts. CMake provides the functionality for installing libraries, executables and other files.
The documentation of ARCHIVE_OUTPUT_DIRECTORY presents you with a possible solution (emphasis mine):
Multi-configuration generators (Visual Studio, Xcode, Ninja Multi-Config) append a per-configuration subdirectory to the specified directory unless a generator expression is used.
You can use a generator expression not changing anything about the value to prevent the config based suffix. You should modify the archive name accordingly to allow for output files of different configurations to coexist in the same directory.
set_target_properties(mylib PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib$<0:>"
OUTPUT_NAME "mylib-$<CONFIG>"
)
Try this code:
set_target_properties(mylib PROPERTIES CMAKE_ARCHIVE_OUTPUT_DIRECTORY " ${CMAKE__BINARY_DIR}/lib")

CMakeLists is not generating so file

Following is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp )
find_library(
log-lib
log )
target_link_libraries(
native-lib
${log-lib} )
I have specified, SHARED in add_library since I want a shared object library.
But it is not giving me the so file.
what am I missing?
You know that CMake doesn't compile anything ? It just configures a Makefile (or IDE project's files) for you.
Generate your Makefile / Visual Studio / What ever you use file project via CMake and then compile.
You will have your library then ;)

CMake not able to find Debug Library

I am a CMake noob trying to put together a package installer so i can move between my windows development machine and my cluster.
I have the following directory tree for my files (an example)
-Primary
--Library Source
--CMakeLists.txt
--src1.cpp
--src1.h
--Application Source
--CMakeLists.txt
--src1.cpp
--src1.h
--CMakeLists.txt
Each CMakeLists.txt is
Primary/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(BloodVesselRadiationDamageSimulations CXX)
SET(FIND_LIBRARY_USE_LIB64_PATHS true)
SET(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}) #only for testing
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_ROOT}/ ${CMAKE_SOURCE_DIR}/cmake/Modules/")
FIND_PACKAGE(OpenMP)
FIND_PACKAGE(MPI)
FIND_PACKAGE(HDF5)
FIND_PACKAGE(GTest)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
SET(CMAKE_DEBUG_POSTFIX _d)
ADD_SUBDIRECTORY(Source)
ADD_SUBDIRECTORY(SourceUnitTest)
Library Source/CMakeLists.txt
ADD_LIBRARY(VesselProjectBaseLibrary STATIC Src1.cpp
Src1.h)
INSTALL(TARGETS VesselProjectBaseLibrary DESTINATION x64/Debug CONFIGURATIONS Debug)
INSTALL(TARGETS VesselProjectBaseLibrary DESTINATION x64/Release CONFIGURATIONS Release|RelWithDebInfo)
Application Source/CMakeLists.txt
INCLUDE_DIRECTORIES("${GTEST_INCLUDE_DIRS}")
ADD_EXECUTABLE (SourceUnitTests Src1.cpp
Src1.h)
TARGET_LINK_LIBRARIES(SourceUnitTests ${GTEST_LIBRARY})
TARGET_LINK_LIBRARIES(SourceUnitTests debug VesselProjectBaseLibrary_d optimized VesselProjectBaseLibrary)
I am able to generate the projects correctly; I see all the correct files in the projects. However, when i go to compile the debug build I get the following error:
1>ipo: : error #11018: Cannot open VesselProjectBaseLibrary_d.lib
1>LINK : fatal error LNK1104: cannot open file 'VesselProjectBaseLibrary_d.lib'
If i compile my release build everything works perfectly and compilation is successful. The library compiles successfully under both builds.
When you link against a library created within the project, you need to specify library target name, not a library file. CMake will care about proper filename, path and other things:
TARGET_LINK_LIBRARIES(SourceUnitTests VesselProjectBaseLibrary)
Variable CMAKE_DEBUG_POSTFIX affects on library's filename. While file VesselProjectBaseLibrary_d.lib is actually created in debug build, it cannot be found automatically by the linker. Again, use target name and let CMake do all other work.

cmake, fortran 2008, and .f08 file extension

I am trying to configure a Fortran 2008 project to use CMake; the files in the project have the ".f08" extension. However, I cannot get CMake to work even with a "hello world" example. Here are the relevant parts of my CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
project (hello)
enable_language (Fortran)
set (CMAKE_Fortran_SOURCE_FILE_EXTENSIONS ${CMAKE_Fortran_SOURCE_FILE_EXTENSIONS} "f08;F08")
add_executable ("hello-world" "hello-world.f08")
set_target_properties (hello-world PROPERTIES LINKER_LANGUAGE Fortran)
Three notes:
The Makefile generated does not compile "hello-world.f08" into an object file.
The "set_target_properties" is needed. Otherwise, CMake reports that it "can not determine linker language for target:hello-world".
Renaming the file to "hello-world.f95" along with the corresponding change in CMakeLists.txt makes things work. Even the "set_target_properties" command is no longer needed.
If you need to specify Fortran files with unrecognized extensions, you can set the source file's LANGUAGE property, e.g.:
set_source_files_properties(hello-world.f08 PROPERTIES LANGUAGE Fortran)