Visual Studio project references in CMake - visual-studio

First I want to say this is not a duplicate to Make References like Visual Studio in CMake
I look over the internet and i cant see what maps to Visual Studio project refereces in CMake. I found this page CMake and Visual Studio but references is not there. So this is my folder config:
- CMakeLists.txt
- demo/
----CMakeLists.txt
- engine/
----CMakeLists.txt
- bin/
----[config]/
------[target_name]
The demo project is a dll and the engine project is an exe and i want to add the engine as a reference in the dll so when i compile the dll it compiles the exe if changes were made.
Main CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
cmake_policy(SET "CMP0079" NEW)
# set configuration types and make them advanced option on cmake.
mark_as_advanced(CMAKE_INSTALL_PREFIX)
set(CMAKE_CONFIGURATION_TYPES Release Debug Release_Asserts)
set(CMAKE_CXX_FLAGS_RELEASE_ASSERTS ${CMAKE_CXX_FLAGS_RELEASE})
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE_ASSERTS ${CMAKE_SHARED_LINKER_FLAGS_RELEASE})
# set c++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# set the project/solution name
project("Llamathrust Engine"
VERSION 1.0
DESCRIPTION "Game engine Win32"
LANGUAGES C CXX)
# use folders for ZERO_CHECK and BUILD_ALL
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# add glad library
add_subdirectory("${CMAKE_SOURCE_DIR}/external/glad")
# add glm library
add_subdirectory("${CMAKE_SOURCE_DIR}/external/glm")
# add the engine to the solution
add_subdirectory("${CMAKE_SOURCE_DIR}/llamathrust/")
target_include_directories("llamathrust" PRIVATE "${CMAKE_SOURCE_DIR}/external/opengl/include")
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT llamathrust)
# link llamathrust to GLAD
target_link_libraries("llamathrust" "glad")
# link llamathrust to GLM
target_link_libraries("llamathrust" "glm")
target_include_directories("llamathrust" PUBLIC "${CMAKE_SOURCE_DIR}/external/glm")
# add the demo code to the solution
add_subdirectory("${CMAKE_SOURCE_DIR}/demo/")
# link demo and llamathrust
# link llamathrust to GLM
target_link_libraries("demo" "glm")
target_include_directories("demo" PUBLIC "${CMAKE_SOURCE_DIR}/external/glm")
# remove ...
remove_definitions(/CMAKE_INTDIR)
# adding options
# option to include a blank screen game
#if (BLANK_TARGET)
#endif()
# option to include the demo game
#if (DEMO_TARGET)
#add_subdirectory("${CMAKE_SOURCE_DIR}/demo/")
#endif()
Demo CMakeLists
cmake_minimum_required(VERSION 3.10)
# set the target/project name
set(TARGET_NAME "demo")
# set c++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# set output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${TARGET_NAME}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${TARGET_NAME}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${TARGET_NAME}")
# add preprocessor definitions
add_definitions(-DLT_DYNAMIC_LIB)
# set sources
set(Demo_SRC
main/main_local.hpp
main/main_local.cpp
main/local_imports.hpp
platform/main.cpp
games/game_demo.hpp
games/game_demo.cpp
)
# executable name
add_library(${TARGET_NAME} SHARED ${Demo_SRC})
# set filters
foreach(_source IN ITEMS ${Demo_SRC})
# Get the directory of the source file
get_filename_component(_source_path "${_source}" PATH)
# Make sure we are using windows slashes
string(REPLACE "/" "\\" _group_path "${_source_path}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
set_target_properties(${TARGET_NAME} PROPERTIES PROJECT_LABEL ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
# set include directory to itself
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(${TARGET_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/llamathrust/include")
# make a reference to the engine
Engine CMakeLists
cmake_minimum_required(VERSION 3.1)
set(TARGET_NAME "llamathrust")
# set output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${TARGET_NAME}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${TARGET_NAME}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${TARGET_NAME}")
# set sources
set(Llamathrust_SRC
...
)
find_package(OpenGL REQUIRED)
# executable name
add_executable(${TARGET_NAME} ${Llamathrust_SRC})
# set filters
foreach(_source IN ITEMS ${Llamathrust_SRC})
# Get the directory of the source file
get_filename_component(_source_path "${_source}" PATH)
# Make sure we are using windows slashes
string(REPLACE "/" "\\" _group_path "${_source_path}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
# find and link to opengl
target_link_libraries(${TARGET_NAME} ${OPENGL_LIBRARY})
target_include_directories(${TARGET_NAME} PRIVATE "${OPENGL_INCLUDE_DIR}")
set(LIBS XInput)
target_link_libraries(${TARGET_NAME} ${LIBS})
# set include directory to itself
target_include_directories(${TARGET_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
# target name label
set_target_properties(${TARGET_NAME} PROPERTIES PROJECT_LABEL ${TARGET_NAME})
#preprocessor definitions
# DEBUG
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:LT_DEBUG>)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:LT_ENABLE_ASSERTS>)
#RELEASE_ASSERT
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Release_Asserts>:LT_RELEASE>)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Release_Asserts>:LT_ENABLE_ASSERTS>)
#RELEASE
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Release>:LT_RELEASE>)
Thanks in advance!

Well this is embarrassing, I just found out the answer on my own looking similar words to reference like dependency.
The answer is add_dependencies("demo" "llamathrust")
I'll keep this question since is a lot clear for visual studio developers to find the answer but final moderators have the final word.

Related

cmake import exist SimpleAmqp library

Now my CMakeList.txt looking like this.
cmake_minimum_required(VERSION 3.6)
project(RabbitMQClient)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
include_directories(src)
include_directories(dependentFile)
add_executable(RabbitMQClient ${SOURCE_FILES})
find_library(SimpleAmqpClient SimpleAmqpClient.2.lib PATHS ./SimpleAmqpClientLib/SimpleAmqpClient.2.lib)
set(IMPORTED_IMPLIB ./SimpleAmqpClientLib)
target_link_libraries(RabbitMQClient PUBLIC SimpleAmqpClient)
when Linking the RabbitMQClient it complains.
cannot find -lSimpleAmqpClient
I want to use the SimpleAmqpClient library in the project,however not quite familiar with cmake not sure the find_library,IMPORTED_IMPLIB,PUBLIC in target_link_libraries was correctly used.Any help would be appreciate.
You have messed up with variables, targets and properties.
Proper usage of IMPORTED libraries for linking would be:
# This command sets *variable* SimpleAmqpClient_LIBRARY
find_library(SimpleAmqpClient_LIBRARY SimpleAmqpClient.2.lib
PATHS ${CMAKE_SOURCE_DIR}/SimpleAmqpClientLib # Specify a *directory*, not a library *file*
)
# Next, create an IMPORTED *target*
add_library(SimpleAmqpClient SHARED IMPORTED)
# And set IMPORTED_LIB *property* for this target
set_target_properties(SimpleAmqpClient PROPERTIES IMPORTED_LIB ${SimpleAmqpClient_LIBRARY})
# Then use library *target* for linking with
target_link_libraries(RabbitMQClient PUBLIC SimpleAmqpClient)
However, there some simplifications which could be done:
Normally, find_library is used when you don't know complete path to the library file. E.g., its directory may be different on different machines, or its prefix/extension may be different on different plaforms.
If you know complete path to the library, just use this path directly (e.g., assign it to the variable).
Normally, property IMPORTED_LOCATION is used for specify library to link with. Property IMPORTED_LIB is specific for Windows .dlls, when linking requires not a library file (.dll), but some other one (.lib).
However, CMake perfectly understands .lib file in IMPORTED_LOCATION property even for Windows .dlls, so your code need not distinguish SHARED Windows libraries from others: just use IMPORTED_LOCATION property in all cases.
Simplified version of the code:
# Create an IMPORTED library *target*
add_library(SimpleAmqpClient IMPORTED)
# Set IMPORTED_LOCATION *property* for this target
set_target_properties(SimpleAmqpClient PROPERTIES
IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/SimpleAmqpClientLib/SimpleAmqpClient.2.lib)
# Then use library *target* for linking with
target_link_libraries(RabbitMQClient PUBLIC SimpleAmqpClient)

Adding headers to Cmake

I am trying to run the examples from VTK and modify them to get to what I want to render on screen.
I am currently trying to add a server application running in parallel to the VTK rendering. I already have my code written for the server but I was wondering how I could add these headers and cpp to CMakeLists.txt.
Indeed, this is the CMakeLists.txt I have so far:
cmake_minimum_required(VERSION 2.8)
PROJECT(RotateActor)
option(INCLUDE_SERVER
"Use the server implementation" ON)
# add the Server library?
if (INCLUDE_SERVER)
include_directories({${CMAKE_CURRENT_SOURCE_DIR}/Server/})
set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Server/tcp_server.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Server/tcp_server.h)
endif (INCLUDE_SERVER)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(RotateActor MACOSX_BUNDLE RotateActor ${SOURCES})
if(VTK_LIBRARIES)
target_link_libraries(RotateActor ${VTK_LIBRARIES})
else()
target_link_libraries(RotateActor vtkHybrid vtkWidgets)
endif()
I then generate using CMake and VS2012. When opening the sln file and trying to generate I get the following error so I'm guessing my integration of the headers is not correct.
C:\...\RotateActor.cxx(12): fatal error C1083: Impossible d'ouvrir le fichier include : 'tcp_server.h' : No such file or directory
I don't think you need the RotateActor.cxx file, but if you do let me know.
Thanks in advance for the help.
I see some problems in your CMake file. First of all, your *.h files musn't be given in the add_executable command. Try something like that :
cmake_minimum_required(VERSION 2.8)
project(RotateActor)
option(INCLUDE_SERVER "Use the server implementation" ON)
# Manage your libraries before your sources
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
# add the Server library ?
# Here, maybe use the path from the root, and not from the local dir ?
# Don't add the .h in the sources
if(INCLUDE_SERVER)
include_directories({${CMAKE_SOURCE_DIR}/Server})
set(RotateActor_CPP_SOURCES
${RotateActor_CPP_SOURCES}
${CMAKE_SOURCE_DIR}/Server/tcp_server.cpp
)
endif()
if(NOT VTK_LIBRARIES)
set(VTK_LIBRARIES vtkHybrid vtkWidgets)
endif()
add_executable(RotateActor ${RotateActor_CPP_SOURCES})
target_link_libraries(RotateActor ${VTK_LIBRARIES})

Building a library with an executable that uses it

I have a library "lib" and an executable "demo".
The issue I'm having is that "demo" can't get lib_INCLUDES and lib_LIBS lib variables, set by "lib". I want them set because in demo.h I do #include <lib.h> and it fails to find the include. I want CMake to make lib.h a global include, i.e. pass -I /path/to/the/dir/with/lib.h/ to the compiler.
Source tree:
- src/
- CMakeLists.txt
- lib/
- CMakeLists.txt
- lib.cpp
- lib.h
- demo/
- CMakeLists.txt
- demo.cpp
- demo.h
src/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(test)
add_subdirectory(lib)
add_subdirectory(demo)
src/lib/CMakeLists.txt
add_library(lib SHARED lib.h lib.cpp)
target_include_directories(lib ${CMAKE_CURRENT_SOURCE_DIR})
# defined for later use in src/demo/CMakeLists.txt
set(lib_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
set(lib_LIBS lib)
src/demo/CMakeLists.txt
include_directories(${lib_INCLUDES})
add_executable(demo demo.h demo.cpp)
target_link_libraries(demo ${lib_LIBS})
# empty! why?
message(STATUS ${lib_INCLUDES})
Tell me how "demo" can access lib_INCLUDES and lib_LIBS libraries set by "lib", they seem to be empty in src/demo/CMakeLists.txt.
I don't want src/demo/CMakeLists.txt contain paths to "lib", only src/lib/CMakeLists.txt should know details of "lib" and it should define nice variables for use in src/demo/CMakeLists.txt that hide all those details.
Please include a working CMakeLists.txt in your answer, if possible.
Please read carefully documentation of SET command. Your variable lib_INCLUDES has local scope to lib\CMakeLists.txt, so for example you can CACHE it.
Better way is to populate INTERFACE_INCLUDE_DIRECTORIES of lib by
target_include_directories(lib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
so the target_link_libraries automatically appends lib's include directories.

using xib in firebreath plugin

I've created a firebreath plugin on mac os which HAVE TO pop up a window to get user input(just a text field and two buttons).
This is my current projectDef.cmake for testing.
file (GLOB XIB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
Mac/bundle_template/input.xib
)
# Make sure we can find the 'ibtool' program. If we can NOT find it we
# skip generation of this project
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND")
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin")
endif()
# make the compiled nib file to desktop for testing
set (NIBFILE /Users/develop/Desktop/input.nib)
add_custom_command (TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text --compile ${NIBFILE} ${XIB}
COMMENT "Compiling input.xib")
set (SOURCES
${SOURCES}
${PLATFORM}
${XIB}
)
the add_custom_command block takes no effect from cmake, no nib file compiled when my plugin target build successfully, but ibtool works from command line in terminal.
Looks like what you need to do is compile the .xib file to a .nib file. There is an example of how to do that here:
http://www.cmake.org/Wiki/CMake:OSX_InterfaceBuilderFiles
basically you'll do something similar to this:
# Make sure we can find the 'ibtool' program. If we can NOT find it we
# skip generation of this project
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND")
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin")
endif()
set (NIBFILE ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/input.nib)
add_custom_command (TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
--compile ${NIBFILE} ${XIB}
COMMENT "Compiling input.xib")
set (SOURCES
${SOURCES}
${PLATFORM}
${XIB}
${NIBFILE}
)
set_source_files_properties(${NIBFILE}
PROPERTIES
MACOSX_PACKAGE_LOCATION "Resources/English.lproj"
GENERATED 1
)
You need to set the location for the NIB file, but remember that you also need to set it to GENERATED because it won't be there when the prep script is run for the first time.
Problem solved. See this link. That method works. My final solution is as follows:
//projectDef.cmake
set(XIB "Mac/bundle_template/input.xib")
add_mac_plugin(${PROJECT_NAME} ${PLIST} ${STRINGS} ${LOCALIZED} SOURCES ${XIB})
//Mac.cmake in "add_mac_plugin" macro
if (${ARGC} GREATER 5)
add_library( ${PROJECT_NAME} MODULE
${SOURCES}
${ARGN}
)
else()
add_library( ${PROJECT_NAME} MODULE
${SOURCES}
)
endif()
if (${ARGC} GREATER 5)
set_target_properties(${PROJECT_NAME} PROPERTIES
BUNDLE 1
BUNDLE_EXTENSION plugin
XCODE_ATTRIBUTE_WRAPPER_EXTENSION plugin #sets the extension to .plugin
XCODE_ATTRIBUTE_MACH_O_TYPE mh_bundle
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/bundle/Info.plist
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/bundle/Info.plist
RESOURCE ${ARGN}
LINK_FLAGS "-Wl,- exported_symbols_list,${FB_ESC_ROOT_DIR}/gen_templates/ExportList_plugin.txt")
else()
set_target_properties(${PROJECT_NAME} PROPERTIES
BUNDLE 1
BUNDLE_EXTENSION plugin
XCODE_ATTRIBUTE_WRAPPER_EXTENSION plugin #sets the extension to .plugin
XCODE_ATTRIBUTE_MACH_O_TYPE mh_bundle
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/bundle/Info.plist
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/bundle/Info.plist
LINK_FLAGS "-Wl,-exported_symbols_list,${FB_ESC_ROOT_DIR}/gen_templates/ExportList_plugin.txt")
endif()
My modification seems not so beautiful, I don't understand cmake very well. hi taxilian, can you update the macro to support external resources like xib? By the way, thanks a lot, man.

How to Generate Windows DLL versioning information with CMake

I'm using CMake to build a shared library, however for the Windows DLL I need the versioning information, like:
FileDescription
FileVersion
InternalName
LegalCopyright
OriginalFilename
ProductName
ProductVersion
So far, all I have are the VERSION and SOVERSION properties, but these don't seem to correlate to the FileVersion information I was expecting.
set(LIC_TARGET MySharedLib)
add_library(${LIC_TARGET} SHARED ${SOURCES} )
SET_TARGET_PROPERTIES(${LIC_TARGET}
PROPERTIES
VERSION ${MY_PRODUCT_NUMBER}.${MY_PRODUCT_VERSION}.${MY_BUILD_NUMBER}
SOVERSION ${MY_PRODUCT_NUMBER})
I've found manual methods (see example at the bottom) but would prefer to contain this within CMake.
Help?
You could use your CMake variable values in conjunction with a version.rc.in file and the configure_file command.
// version.rc.in
#define VER_FILEVERSION #MY_PRODUCT_NUMBER#,#MY_PRODUCT_VERSION#,#MY_BUILD_NUMBER#,0
#define VER_FILEVERSION_STR "#MY_PRODUCT_NUMBER#.#MY_PRODUCT_VERSION#.#MY_BUILD_NUMBER#.0\0"
#define VER_PRODUCTVERSION #MY_PRODUCT_NUMBER#,#MY_PRODUCT_VERSION#,#MY_BUILD_NUMBER#,0
#define VER_PRODUCTVERSION_STR "#MY_PRODUCT_NUMBER#.#MY_PRODUCT_VERSION#.#MY_BUILD_NUMBER#\0"
//
// ...along with the rest of the file from your "manual methods" reference
And then, in your CMakeLists.txt file:
# CMakeLists.txt
set(MY_PRODUCT_NUMBER 3)
set(MY_PRODUCT_VERSION 5)
set(MY_BUILD_NUMBER 49)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in
${CMAKE_CURRENT_BINARY_DIR}/version.rc
#ONLY)
set(LIC_TARGET MySharedLib)
add_library(${LIC_TARGET} SHARED ${SOURCES}
${CMAKE_CURRENT_BINARY_DIR}/version.rc)
# Alternatively you could simply include version.rc in another rc file
# if there already is one in one of the files in ${SOURCES}
I'm had same problem and have automated version generation for my projects.
You need three files from github:
generate_product_version.cmake
VersionInfo.in
VersionResource.rc
Put it in cmake subdirectory of your project and make sure to include it to CMAKE_MODULE_PATH like:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
Then before add_executable() or add_library(SHARED) your target, use:
include(generate_product_version)
generate_product_version(
VersionFilesOutputVariable
NAME "My Great Project"
ICON ${PATH_TO_APPLICATION_ICON}
VERSION_MAJOR 1
VERSION_MINOR 3
VERSION_PATCH ${BUILD_COUNTER}
VERSION_REVISION ${BUILD_REVISION}
)
Full list of supported resource strings see in generate_product_version.cmake.
VersionInfo.h and VersionResource.rc will be generated to cmake binaries folder. Variable VersionFilesOutputVariable will hold paths to these files. Just add this list to your target:
add_executable(MyGreatProject ${your-target-sources} ${VersionFilesOutputVariable})
UPDATE: Corrected generate_product_version script parameters from VERSION_PATH
to VERSION_PATCH.
There is an even easier way than the accepted answer. It does not involve transforming an input resource.rc.in. Simply create a generic version.rc file as described here and then from your CMakeLists.txt do this:
#CMakeLists.txt
add_definitions(-DVER_COMPANYNAME_STR="MyCompany")
add_definitions(-DVER_FILEVERSION_STR="1,1,0.0")
# ...
# add all the other defines here
set(LIC_TARGET MySharedLib)
add_library(${LIC_TARGET} SHARED ${SOURCES} version.rc)
This has the added benefit that the defines are accessible from your source code as well, so you have programmatic access to your version.

Resources