I have a problem that in my project I have multiple libraries who all link eachother differently.
And then there is one executable that links to only one library.
Now there are two problems:
1) The linked libraries are not showing up in the librarian of the static libraries.
2) the librarires are all showing up at the executable.
So here is my project order
Game|- Engine|--Core|---Graphics|----Libpng|---Platform
so Graphic links Libpng
Core links Graphics and Platform
Engine links Core
Game links Engine
Utilities is an interface library so headers only
what happens is that all Additional dependencies are at Game
The librarian of Core, Engine and Graphic containts no additional dependencies.
This is the Root CMake
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_GENERATOR "Visual Studio 14 2015")
project(EngineOnly)
set(CMAKE_SUPPRESS_REGENERATION true)
if(WIN32)
set(PLATFORM WIN32)
else()
set(PLATFORM LINUX)
endif (WIN32)
add_subdirectory(UTILITIES)
add_subdirectory(PLATFORM)
add_subdirectory(GRAPHICS)
add_subdirectory(CORE)
add_subdirectory(Engine)
add_subdirectory(Game)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Trinity.Game)
This is game
#UTILITIES LIB
include_directories(../UTILITIES/INCLUDE)
include_directories(../ENGINE/INCLUDE)
#SOURCE
file(GLOB SOURCES "SOURCE/*.cpp")
file(GLOB INCLUDES "INCLUDE/*.h")
#PROJECTNAME
set(PROJECTNAME "Trinity.Game")
#LINK ALL
add_executable(${PROJECTNAME} ${SOURCES} ${INCLUDES})
set_target_properties(${PROJECTNAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/../BIN/${PLATFORM}/DEBUG"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/../BIN/${PLATFORM}/RELEASE"
)
target_link_libraries(${PROJECTNAME}
LINK_PRIVATE Trinity.Engine
)
Engine
#UTILITIES LIB
include_directories(../UTILITIES/INCLUDE)
include_directories(../CORE/INCLUDE)
#SOURCE
file(GLOB SOURCES "SOURCE/*.cpp")
file(GLOB INCLUDES "INCLUDE/*.h")
#PROJECTNAME
set(PROJECTNAME "Trinity.Engine")
#LINK ALL
add_library(${PROJECTNAME} ${SOURCES} ${INCLUDES})
set_target_properties(${PROJECTNAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/LIB/${PLATFORM}/DEBUG"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_BINARY_DIR}/LIB/${PLATFORM}/RELEASE"
)
target_link_libraries(${PROJECTNAME}
LINK_PRIVATE Trinity.Core
)
Core
#UTILITIES LIB
include_directories(../UTILITIES/INCLUDE)
include_directories(../GRAPHICS/INCLUDE)
include_directories(../PLATFORM/INCLUDE)
#SOURCE
file(GLOB SOURCES "SOURCE/*.cpp")
file(GLOB INCLUDES "INCLUDE/*.h")
#PROJECTNAME
set(PROJECTNAME "Trinity.Core")
#LINK ALL
add_library(${PROJECTNAME} ${SOURCES} ${INCLUDES})
set_target_properties(${PROJECTNAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/LIB/${PLATFORM}/DEBUG"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_BINARY_DIR}/LIB/${PLATFORM}/RELEASE"
)
target_link_libraries(${PROJECTNAME}
LINK_PRIVATE Trinity.Graphics
LINK_PRIVATE Trinity.Platform
)
The other look the same.
I've tried PRIVATE instead of LINK_PRIVATE but the result is the same.
You can't link static libraries against each other and it is normal that they only showing up at the executable. Does your code not compiling?
For more information about static and dynamic libraries I suggest this article.
If you want to change the library type in cmake specify the add_lib command:
add_library(${LIB_NAME} ${LIB_TYPE} ${SOURCE})
# with ${LIB_TYPE} = STATIC or SHARED
more informations about cmake
If you have more problems or my answer answer to you is not enough please specify your question.
Related
I followed the asssimp library's installation guide, which used Visual Studio and did all the necessary steps to include it in the project through the GUI when I did everything through pure CMake and MinGW.
I need to include headers and two library files in my project: assimp-[...].dll and assimp-[...].lib
My assimp proj hierarchy
I started to figure out how to write my own CMakeLists.txt and came up with this:
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
project(Assimp)
add_library(assimp SHARED IMPORTED GLOBAL)
file(GLOB_RECURSE ROOT_SOURCE "./assimp/*.cpp")
file(GLOB_RECURSE ROOT_INLINE "./assimp/*.inl")
file(GLOB_RECURSE ROOT_HPP "./assimp/*.hpp")
file(GLOB_RECURSE ROOT_HEADER "./assimp/*.h")
file(GLOB_RECURSE COMPILER_HEADER "./assimp/Compiler/*.h")
file(GLOB_RECURSE PORT_HEADER "./assimp/port/AndroidJNI/*.h")
source_group("Compiler Files" FILES ${COMPILER_HEADER})
source_group("Port Files" FILES ${PORT_HEADER})
include(GNUInstallDirs)
if(BUILD_STATIC_LIBS)
add_library(assimp_static STATIC
${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HPP}
${ROOT_HEADER} ${COMPILER_HEADER} ${PORT_HEADER}
)
target_link_libraries(assimp_static PUBLIC assimp)
add_library(assimp::assimp_static ALIAS assimp_static)
endif()
if(BUILD_SHARED_LIBS)
add_library(assimp_shared SHARED
${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HPP}
${ROOT_HEADER} ${COMPILER_HEADER} ${PORT_HEADER}
)
target_link_libraries(assimp_shared PUBLIC assimp)
add_library(assimp::assimp_shared ALIAS assimp_shared)
endif()
set_property(TARGET assimp PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/external/assimp/lib/assimp-vc143-mtd.dll")
set_property(TARGET assimp PROPERTY IMPORTED_IMPLIB "${PROJECT_SOURCE_DIR}/external/assimp/lib/assimp-vc143-mtd.lib")
After that I'm linking it in the main CMakeLists.txt:
add_executable(${PROJECT_NAME} [src code files here])
add_subdirectory(external/assimp)
target_link_libraries(${PROJECT_NAME} PRIVATE assimp)
But after that, I can't see any header from this library, as well as its directory, and I'm not even sure if the dynamic libraries from the "lib" folder are included correctly.
What am I doing wrong?
Trying to package an application with Microsoft Visual Studio 2022 and qt6 libraries I do not no were to start from. I've done a bit of research most people used qt5 and when I replace the text with qt6 it doesn't seem to work. I used dependency walker to find the necessary libraries and I seem to have achieved a way to add the Visual Studio libraries but not qt and VTK.
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
foreach(p
CMP0071 # 3.10: Let AUTOMOC and AUTOUIC process GENERATED files
)
if(POLICY ${p})
cmake_policy(SET ${p} NEW)
endif()
endforeach()
PROJECT( QtVTKExample )
#set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
if (MSVC_VERSION EQUAL 1930 AND MSVC_TOOLSET_VERSION EQUAL 142)
cmake_host_system_information(RESULT VS_DIR QUERY VS_17_DIR)
file(GLOB MSVC_REDIST_LIBRARIES "${VS_DIR}/VC/Redist/MSVC/*/${MSVC_C_ARCHITECTURE_ID}/Microsoft.VC143.CRT/*.dll")
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${MSVC_REDIST_LIBRARIES}")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE)
endif()
include(InstallRequiredSystemLibraries)
# Add to top of file CPACK stuff
include(CTest)
if(WIN32)
set(CPACK_GENERATOR "NSIS")
else()
set(CPACK_GENERATOR "ZIP")
endif()
include(CPack)
find_package(VTK COMPONENTS
vtkCommonColor
vtkCommonCore
vtkCommonDataModel
vtkInteractionStyle
vtkRenderingContextOpenGL2
vtkRenderingCore
vtkRenderingFreeType
vtkRenderingGL2PSOpenGL2
vtkRenderingOpenGL2
QUIET
)
# The CMake build process might generate some new files in the current
# directory. This makes sure they can be found.
set( CMAKE_INCLUDE_CURRENT_DIR ON )
# This allows CMake to run one of Qt's build tools called moc
# if it is needed. moc.exe can be found in Qt's bin directory.
# We'll look at what moc does later.
set( CMAKE_AUTOMOC ON )
set( CMAKE_AUTOUIC ON )
# Find the Qt widgets package. This locates the relevant include and
# lib directories, and the necessary static libraries for linking.
find_package( Qt6Widgets )
set( UIS mainwindow.ui )
qt6_wrap_ui( UI_Srcs ${UIS} )
set( ICONS Icons/icons.qrc )
qt6_add_resources( QRC_Srcs ${ICONS} )
# Also link to VTK
find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )
# Define the executable output and its sources
add_executable( QtVTKExample MACOSX_BUNDLE
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
tabcontent.cpp
tabcontent.h
tabcontent.ui
currentstl.cpp
currentstl.h
recentstl.cpp
recentstl.h
${UI_Srcs}
${QRC_Srcs}
)
# Tell CMake that the executable depends on the Qt::Widget libraries.
target_link_libraries( QtVTKExample Qt6::Widgets )
# Tell CMake that the executable depends on the VTK libraries
target_link_libraries( QtVTKExample ${VTK_LIBRARIES} )
# /calc_cmake/CMakeLists.txt
install(TARGETS QtVTKExample
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
I have a cmake project which is a static library that i have to share with other teams in my company but just the .lib file and not the source code.
This library depends on Boost.
Now i build the library and transfer the install folder onto another pc (exe_pc) and use it in a exe project (this exe also depends on boost).
Now at compile time i get a linking error saying that E:/Development/vcpkg/installed/x64-windows/lib/boost_system-vc140-mt.lib cannot be opened.
so i open and check the generated LibTargets.cmake and it contains absolute paths of boost library for pc on which the library was built.
# The installation prefix configured by this project.
set(_IMPORT_PREFIX "C:/Program Files/cpp_licensing")
# Create imported target Licensing::liblicensing
add_library(Licensing::liblicensing STATIC IMPORTED)
set_target_properties(Licensing::liblicensing PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "_LICENSING_DEBUG=0"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "\$<\$<NOT:\$<CONFIG:DEBUG>>:E:/Development/vcpkg/installed/x64-windows/lib/boost_system-vc140-mt.lib>;\$<\$<CONFIG:DEBUG>:E:/Development/vcpkg/installed/x64-windows/debug/lib/boost_system-vc140-mt-gd.lib>;\$<\$<NOT:\$<CONFIG:DEBUG>>:E:/Development/vcpkg/installed/x64-windows/lib/boost_filesystem-vc140-mt.lib>;\$<\$<CONFIG:DEBUG>:E:/Development/vcpkg/installed/x64-windows/debug/lib/boost_filesystem-vc140-mt-gd.lib>;cryptopp-static;wbemuuid"
)
LibLicensingTargets-release.cmake
et_target_properties(Licensing::liblicensing PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "C:/Program Files/cpp_licensing/lib/licensing.lib"
)
list(APPEND _IMPORT_CHECK_TARGETS Licensing::liblicensing )
list(APPEND _IMPORT_CHECK_FILES_FOR_Licensing::liblicensing "C:/Program Files/cpp_licensing/lib/licensing.lib" )
The user is supposed to have boost installed, the only problem i have is that because absolute paths are used in targets file user has to manually change them on his pc in the targets file.
what changes do i make to cmake so that the libraries built folder can be shared. How do i distribute a library built using cmake ??
Here is the cmake for the library project
cmake_minimum_required(VERSION 3.10)
project(liblicensing)
message("~~ Project: " ${PROJECT_NAME})
set(LIB_NAME "${PROJECT_NAME}")
set(PROJECT_VERSION 1.0)
include_directories(
${PROJECT_SOURCE_DIR}/include
)
if (WIN32)
find_package(Boost REQUIRED system filesystem)
find_package(cryptopp REQUIRED)
find_package(unofficial-date REQUIRED)
include_directories(
${Boost_INCLUDE_DIR}
)
else()
find_package(date REQUIRED)
endif ()
file(GLOB_RECURSE HEADER_FILES include/*.h include/*.hpp)
file(GLOB_RECURSE SOURCES src/*.cpp)
add_library(${LIB_NAME} STATIC ${SOURCES} ${HEADER_FILES} )
set_target_properties(
${LIB_NAME}
PROPERTIES
OUTPUT_NAME "licensing"
POSITION_INDEPENDENT_CODE ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
LINKER_LANGUAGE CXX
)
if (MSVC)
set_target_properties(${LIB_NAME} PROPERTIES DEBUG_POSTFIX "_d")
endif()
add_library(Licensing::liblicensing ALIAS ${LIB_NAME})
set(INSTALLATION_DIR "${CMAKE_INSTALL_PREFIX}")
set(CMAKE_INSTALL_LIBDIR "${INSTALLATION_DIR}/lib")
set(CMAKE_INSTALL_BINDIR "${INSTALLATION_DIR}/bin")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME})
target_include_directories(${LIB_NAME}
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
if (WIN32)
target_link_libraries(
${LIB_NAME}
${Boost_LIBRARIES}
cryptopp-static
wbemuuid
)
else()
target_link_libraries(
${LIB_NAME}
cryptopp
boost_system
boost_filesystem
)
endif ()
if(CMAKE_BUILD_TYPE MATCHES Debug)
target_compile_definitions(${LIB_NAME} PUBLIC _LICENSING_DEBUG=1)
elseif(CMAKE_BUILD_TYPE MATCHES Release)
target_compile_definitions(${LIB_NAME} PUBLIC _LICENSING_DEBUG=0)
endif()
# Expose Projects's public includes to other subprojects through cache variable.
set(${PROJECT_NAME}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
###############
# Installation
##
install(TARGETS ${LIB_NAME}
EXPORT LibLicensingTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
# INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${LIB_NAME}
FILES_MATCHING PATTERN "*.h*")
install(EXPORT LibLicensingTargets
FILE LibLicensingTargets.cmake
NAMESPACE Licensing::
DESTINATION ${INSTALL_CONFIGDIR}
)
#####################
# ConfigVersion file
##
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/CMake/LibLicensingConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfig.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)
## Install all the helper files
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfigVersion.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)
Not an entire answer but too much for a comment:
If you inspect your file LibLicensingTargets.cmake closely, you see that cryptopp-static and wbemuuid are not resolved down to the library level.
Looking at how you reference Boost you use the oldstyle version (${Boost_LIBRARIES}) that resolves down to the library level.
Try instead to use the targets provided by FindBoost.cmake module as follows:
if (WIN32)
target_link_libraries(
${LIB_NAME}
Boost::system
Boost::filesystem
cryptopp-static
wbemuuid
)
else()
target_link_libraries(
${LIB_NAME}
cryptopp
Boost::system
Boost::filesystem
)
endif()
Another thing that puzzles me is why you added the ALIAS:
add_library(Licensing::liblicensing ALIAS ${LIB_NAME})
This ALIAS is properly created in the LibLicensingTargets.cmake file, so you do not need to create it on your own.
Another thing is, that you are giving your INSTALL command absolute paths. To make the package entirely relocatable you need to use relative paths (relative to the CMAKE_INSTALL_PREFIX, the installation directory).
The following commands should therefore be changed to:
set(CMAKE_INSTALL_LIBDIR "lib")
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME})
If you further add the line:
export(TARGETS liblicensing NAMESPACE LibLicensing:: FILE LibLicensingTargets.cmake)
to your CMakeLists.txt, outside projects are able to import target from your build tree folder as of liblicensing was installed therein. See the CMake documentation of the export command.
I have cli wrapper function which i am trying to configure in cmake. After i generate the project with cmake the generated .proj file does not have the property of clr support is set to no common languaage runtime support. below is my cmake file
# This is the root ITK CMakeLists file.
cmake_minimum_required(VERSION 2.8.9)
if(COMMAND CMAKE_POLICY)
cmake_policy(SET CMP0003 NEW)
endif()
set_target_properties(${TargetName} PROPERTIES COMPILE_FLAGS "/clr")
SET(LINK_LIBRARIES
D:\\2016\\RandomSlicing\\Processing\\lib\\obliquePlane.lib
)
# The header files
SET(HEADERS
ObliquePlaneWrapper.h
obliquePlane.h
)
# The implementation files
SET(SOURCES
ObliquePlaneWrapper.cpp
)
# Find ITK.
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
# Add this as include directory
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}
${SOURCE_PATH}
${VXL_INCLUDE_DIRS}
)
# Main library
#ADD_EXECUTABLE(obliquePlane ${HEADERS} ${SOURCES})
ADD_LIBRARY(ObliquePlaneWrapper SHARED ${HEADERS} ${SOURCES})
TARGET_LINK_LIBRARIES(ObliquePlaneWrapper ${LINK_LIBRARIES} ${ITK_LIBRARIES})
I manually set this property in the All_build project and the corresponding .proj file. When i build the project it is searching for the ObliquePlaneWrapper.dll which it should be generating. Is this a problem because of some flag not set for common language runtime support
You can manually supply Compile Flags to specific sources to be compiled with specific flags. This includes \CLR for Visual C++. See example here.
https://cmake.org/pipermail/cmake/2011-April/043773.html
My program uses giblib and Imlib2 library and it is built with cmake.
It works perfectly in my computer but not in other's.
I guess the reason is I installed every library what my program needs but other's doesn't.
My goal is making standalone program. (don't need to install any other library addtionally)
What should I add in cmake file?
projectDef.cmake source code
file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
X11/[^.]*.cpp
X11/[^.]*.h
X11/[^.]*.cmake
)
SOURCE_GROUP(X11 FILES ${PLATFORM})
add_definitions(
)
set (SOURCES
${SOURCES}
${PLATFORM}
)
add_x11_plugin(${PROJECT_NAME} SOURCES)
target_link_libraries(${PROJECT_NAME}
${PLUGIN_INTERNAL_DEPS}
)
include_directories(/usr/include/giblib)
include_directories(/usr/include/X11)
target_link_libraries(MyProject X11)
target_link_libraries(MyProject Imlib2)
target_link_libraries(MyProject giblib)
CMakeList.txt source code
cmake_minimum_required (VERSION 2.6)
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6)
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
Project(${PLUGIN_NAME})
file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
[^.]*.cpp
[^.]*.h
[^.]*.cmake
)
include_directories(${PLUGIN_INCLUDE_DIRS})
SET_SOURCE_FILES_PROPERTIES(
${GENERATED}
PROPERTIES
GENERATED 1
)
SOURCE_GROUP(Generated FILES
${GENERATED}
)
SET( SOURCES
${GENERAL}
${GENERATED}
)
include_platform()
Try starting with this options in your root CMakeLists.txt:
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
BUILD_SHARED_LIBS is only needed if your project has its own libraries (add_library).
With the -static linker flag, you need static libs for ALL your additional libraries too! One common problem when static linking is to avoid circular dependencies.