How to build a release version in CLion, c++ project - c++

I have the following CMake file that CLion picked up automatically and created a run-debug profile for:
cmake_minimum_required(VERSION 3.23)
project(shadowgate)
set(CMAKE_CXX_STANDARD 20)
include_directories(I:/onedrive/SDL2/include libs)
link_directories(I:/onedrive/SDL2/lib/x64 libs)
#lua54.dll needs to be copied to windows/system32 folder
add_library(Lua STATIC IMPORTED GLOBAL)
set_target_properties(Lua PROPERTIES
IMPORTED_LOCATION "I:/onedrive/lua4/liblua54.a"
INTERFACE_INCLUDE_DIRECTORIES "I:/onedrive/lua4/include"
)
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libs/imgui/*.cpp)
add_executable(${PROJECT_NAME} ${SRC_FILES} )
#looks for a file with .lib extension
target_link_libraries(${PROJECT_NAME} SDL2main SDL2 SDL2_ttf SDL2_image SDL2_mixer Lua)
#AssetManager
add_custom_target(copy_assets
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets
)
add_dependencies(${PROJECT_NAME} copy_assets)
I don't see any options in CLion to copy this debug profile to a 'release' profile. I tried moving the executable to a seperate folder and add the needed .dll files next to it, but then it's still not finding the dlls.
How can I make a proper release of this project, where it will look for the .dll files in it's own directory?

Related

CMake imported targets in add_subdirectory not available in main CMakeLists.txt

I want to build an application that depends on the OpenCV (version 3.4.6) viz module. This module has the VTK library (version 7.1.1) as dependency. I want to use ExternalProject to build both, the vtk library and the opencv viz module and subsequently want to build the main application, all in one cmake run.
.
├── CMakeLists.txt
├── deps
│   └── CMakeLists.txt
└── main.cpp
I am using the cmake ExternalProject module to build both opencv and vtk inside a subdirectory like this:
deps/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(dependencies)
include(ExternalProject)
ExternalProject_add(
vtklib
GIT_REPOSITORY https://github.com/Kitware/vtk
GIT_TAG v7.1.1
GIT_PROGRESS TRUE
UPDATE_COMMAND ""
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
-DBUILD_TESTING=OFF
-DBUILD_EXAMPLES=OFF
-DVTK_DATA_EXCLUDE_FROM_ALL=ON
-DVTK_USE_CXX11_FEATURES=ON
-Wno-dev
)
add_library(vtk INTERFACE IMPORTED GLOBAL)
add_dependencies(vtk vtklib)
ExternalProject_add(
ocv
GIT_REPOSITORY https://github.com/opencv/opencv
GIT_TAG 3.4.6
GIT_PROGRESS TRUE
UPDATE_COMMAND ""
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
-DWITH_VTK=ON
-Wno-dev
)
# ExternalProject_Get_Property(ocv install_dir)
# include_directories(${install_dir}/src/ocv/include)
include_directories(${CMAKE_INSTALL_PREFIX}/include)
set(ocv_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_VS_PLATFORM_NAME}/vc15)
set(OCV_VERSION 346)
add_dependencies(ocv vtklib)
add_library(opencv_core SHARED IMPORTED)
set_target_properties(opencv_core PROPERTIES
IMPORTED_IMPLIB "${ocv_libdir}/lib/opencv_core${OCV_VERSION}.lib"
IMPORTED_LOCATION "${ocv_libdir}/bin/opencv_core${OCV_VERSION}.dll"
)
add_library(opencv_viz SHARED IMPORTED)
set_target_properties(opencv_viz PROPERTIES
IMPORTED_IMPLIB "${ocv_libdir}/lib/opencv_viz${OCV_VERSION}.lib"
IMPORTED_LOCATION "${ocv_libdir}/bin/opencv_viz${OCV_VERSION}.dll"
)
the main CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.14)
project(cmaketest VERSION 0.1 DESCRIPTION "" LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_Flags "${CMAKE_CXX_FLAGS} -std=c++17")
# include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_subdirectory(deps)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} opencv_core opencv_viz)
install(
TARGETS ${PROJECT_NAME}
EXPORT "${PROJECT_NAME}-targets"
LIBRARY DESTINATION lib/
ARCHIVE DESTINATION lib/${CMAKE_PROJECT_NAME}
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}
)
the main.cpp for completeness:
#include <opencv2/viz.hpp>
int main(){}
but it seems that the include_directories and add_library calls inside deps/CMakeLists.txt do not work on the correct scope as i am getting the following error messages:
error C1083: File (Include) can not be opened: "opencv2/viz.hpp"
if i uncomment the include_directories inside the main CMakeLists.txt then i get a linker error (this is not what i want, included directories should be specified inside deps/CMakeLists.txt):
LNK1181: opencv_core.lib can not be opened
If i just copy the contents of deps/CMakeLists.txt in the main CMakeLists.txt in place of the add_subdirectory call everything works fine.
So, how do i get the include directories and the created targets from the subdirectory in my main CMakeLists?
edit:
call to cmake configure:
cmake.exe -B build -S . -G "Visual Studio 17 2022" -A x64 -T v141 -DCMAKE_INSTALL_PREFIX=D:/test
call to cmake build:
cmake.exe --build build --config Release --target install
Unlike to normal targets, which are global, an IMPORTED target by default is local to the directory where it is created.
For extend visibility of the IMPORTED target, use GLOBAL keyword:
add_library(opencv_core SHARED IMPORTED GLOBAL)
This is written in the documentation for add_library(IMPORTED):
The target name has scope in the directory in which it is created and below, but the GLOBAL option extends visibility.
cmake has couple steps:
configuration
generation (depends on configuration)
build (depends on generation)
test (depends on build)
install (depends on build)
Now problem is that your build step depends on result of install step. This happens here:
set(ocv_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_VS_PLATFORM_NAME}/vc15)
and when this variable is used.
This is causing that to be able to complete build step you need success in install step. And cmake will do install step after successful build. So you have dependency cycle.
Instead importing opencv as shared library:
add_library(opencv_viz SHARED IMPORTED)
Link your target with targets created by imported project of opnecv.

Qt5 CMake include all libraries into executable

I'm trying to build a with Qt 5.14 an application on release mode and everything is working fine inside of Qt Creator, but when I'm trying to run the executable by itself I'm getting an error like this:
OS: Windows 10
Qt: 5.14
Cmake: 3.5
What I've tried:
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
${ADDITIONAL_LIBRARIES} -static inside of target_link_libraries
None of the above worked for me and I'm getting the same error whenever I'm trying to run the executable by its self without using Qt Creator.
My CMake file:
cmake_minimum_required(VERSION 3.5)
project(Scrollable LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED Core Widgets Gui Qml Quick Qml)
qt5_add_resources(resource.qrc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories("MoviesInterface")
set(SOURCES
main.cpp
MovieInterface/movieinterfaceomdb.cpp
MovieInterface/moviesinterface.cpp
)
set(HEADERS
MovieInterface/movieinterfaceomdb.h
MovieInterface/moviesinterface.h
)
add_executable(Scrollable ${SOURCES} ${HEADERS} qml.qrc)
qt5_use_modules(Scrollable Core Network)
target_link_libraries(Scrollable
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Qml
${ADDITIONAL_LIBRARIES} -static
)
A You want to statically compile. This won't work for Qt libs and Mingw libs itself, because these would need to be compiled statically, too.
But they are only distributed as dynamic linked libraries.
If you really want to have statically linkable Qt libs, you would need to compile Qt statically, before you can link them. There are some descriptions for compiling Qt statically out there. But it's a lot of work.
B Why Qt5Core.dll is not found:
Inside Qt Creator the path to the Qt libraries for your application is automatically set, because of Compiler/Toolchain auto-detection.
But, when you run your application executable standalone, the path to the Qt libs is not set and they do not reside in the application folder next to the executable.
To solve this i would suggest using windeployqt.
windeployqt analyzes the library or executable you build and copies the needed Qt dependencies into the build folder.
I tend to use a cmake helper function for this.
Create windeployqt.cmake with the following content and place it into /cmake modules folder of your project:
find_package(Qt5Core REQUIRED)
# get absolute path to qmake, then use it to find windeployqt executable
get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION)
get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY)
function(windeployqt target)
# POST_BUILD step
# - after build, we have a bin/lib for analyzing qt dependencies
# - we run windeployqt on target and deploy Qt libs
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${_qt_bin_dir}/windeployqt.exe"
--verbose 1
--release
--no-svg
--no-angle
--no-opengl
--no-opengl-sw
--no-compiler-runtime
--no-system-d3d-compiler
\"$<TARGET_FILE:${target}>\"
COMMENT "Deploying Qt libraries using windeployqt for compilation target '${target}' ..."
)
endfunction()
Note 1: --verbose 1 is set, so that you see what's going on. You might disable it later.
Note 2: Please handle the excludes yourself. I don't know the specific requirements of your app, e.g. if you need OpenGL or SVG support.
Then add to your CMakeLists.txt:
# Set path to our custom CMAKE scripts
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
# Include Qt deployment helper function
include(windeployqt)
Finally, add to the end of CMakeLists.txt:
windeployqt(Scrollable)
Now, windeployqt is run as a POST_BUILD step on your executable, copying the qt libraries to the build folder. The executable will now pick up the Qt dependencies from this folder and should be able to run standalone (without path to Qt libs set).
Keep in mind to also copy other dependencies, e.g. third-party libs or runtime-dependencies.
Follow-up for your mingw dependencies:
set(QT_MINGW "/path/to/your/qt/mingw/compiler")
add_custom_command(TARGET Scrollable POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libgcc_s_dw2-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libstdc++-6.dll $<TARGET_FILE_DIR:${TARGET}>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_MINGW}/bin/libwinpthread-1.dll $<TARGET_FILE_DIR:${TARGET}>
COMMENT "Deploy mingw runtime libraries from ${QT_MINGW}/bin"
)
Follow-up for your mingw dependencies:
...
If Qt is installed with MinGW as well, you can avoid additional copy operattions for runtime libraries within add_custom_command just using windeployqt.exe with --compiler-runtime command line option.

How to "Link All" dynamic and/or static libraries, using a folder path and cmake?

In my test project I have a folder structure of the following
-Root/
-Lib_so/ //folder where it contains all of the .so file
-Lib_a/ //folder where it contains all of the .a file
-Lib_dll/ //folder where it contains all of the dll file
-Includes/ //folder where it contains all of the header files
-main.cpp
I want to write a CMakeLists.txt that generates a single executable that:
automatically link ALL of the .so , .a, and/or dll files just by the folder path shown above.
link installed binaries (such as the GLFW installed by brew on mac)
I have tried the following
cmake_minimum_required(VERSION 3.0)
project(FirstOpenGL)
set(SOURCE main.cpp)
add_executable(myapp ${SOURCE})
#Below Im trying to link ALL of the libs under the "project's local path"
include_directories(${CMAKE_SOURCE_DIR}/Includes)
link_directories(LinkPathSo ${CMAKE_SOURCE_DIR}/Lib_so)
link_directories(LinkPathA ${CMAKE_SOURCE_DIR}/Lib_a)
link_directories(LinkPathDll ${CMAKE_SOURCE_DIR}/Lib_dll)
target_link_libraries(myapp LinkPathSo)
target_link_libraries(myapp LinkPathA)
target_link_libraries(myapp LinkPathDll)
# Below: Im trying to link the installed binaries on mac
find_package(glfw3 3.2 REQUIRED)
find_package(OpenGL REQUIRED)
target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
Thank you all in advance

Cmake managed C++

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

QtCreator CMake Project Auto-Complete Not Always Working?

I have been working on a project that uses cmake as the build system and working in QtCreator just fine. There are sub-projects (some Qt related and others just plain c++) and up until now all of them were able to find header files and hence provide auto-complete functionality.
At some point, I added a Qt project and noticed that my headers for Qt proejcts were not being found by the editor. The really odd thing is they compile and run just fine via QtCreator 'Build->Build All'. It is almost like QtCreator just can't find them for auto-complete.
I looked around and users had problems in earlier versions of QtCreator finding Qt classes, but did not seem to have a problem finding their defined header files.
I put together a simplified "project" and added two fresh Qt Widget Application projects with the main window being a QDialog instead of QMainWindow. I added the following CMakeLists.txt file to each project:
My Standard CMake File For Qt
cmake_minimum_required(VERSION 3.0.2)
project("FooProj")
set(EXECUTABLE_NAME "Foo")
# Find Qt packages.
find_package(Qt5Core)
find_package(Qt5Widgets)
find_package(Qt5Gui)
set(CMAKE_AUTOMOC ON)
set(SOURCES
"src/main.cpp"
"src/Dialog.cpp"
)
set(HEADERS
"includes/Dialog.h"
)
set(UI_FORMS
"forms/Dialog.ui"
)
set(RESOURCES_FILES
"resources/resources.qrc"
)
# Convert Qt UI and resource files to C/C++ files.
qt5_wrap_ui(UI_HEADERS ${UI_FORMS})
qt5_add_resources(RESOURCES ${RESOURCES_FILES})
# Define the executable to be built.
add_executable(${EXECUTABLE_NAME}
${SOURCES}
${HEADERS}
${UI_HEADERS}
${RESOURCES}
)
# Include paths for this project.
target_include_directories(${EXECUTABLE_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
"${CMAKE_CURRENT_BINARY_DIR}"
)
# Link to appropriate libraries.
target_link_libraries(${EXECUTABLE_NAME}
Qt5::Core
Qt5::Widgets
Qt5::Gui
)
# Set distribution location and project structure.
set(DIST_DIR "${CMAKE_BINARY_DIR}/dist/${EXECUTABLE_NAME}")
set_property(TARGET ${EXECUTABLE_NAME} PROPERTY FOLDER "Guis")
# Setup distribution environment and copy final executable.
add_custom_command(TARGET ${EXECUTABLE_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${DIST_DIR}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${EXECUTABLE_NAME}> ${DIST_DIR}
)
# OS specific deployment setup for sytems without Qt installed.
if(WIN32)
add_custom_command(TARGET ${EXECUTABLE_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/QtDeploymentFiles/run.bat" ${DIST_DIR}/${EXECUTABLE_NAME}.bat
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/QtDeploymentFiles/qt.conf" ${DIST_DIR}
)
elseif(UNIX AND NOT APPLE)
add_custom_command(TARGET ${EXECUTABLE_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/QtDeploymentFiles/run.sh" ${DIST_DIR}/${EXECUTABLE_NAME}.sh
)
endif()
Along with this top level CMakeLists.txt:
Top Level CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project("Test")
add_subdirectory("FooProj")
add_subdirectory("BarProj")
Everything makes, compiles, and runs just fine. Auto-complete also works.
I add a Qt library project I need and everything still works fine even when I use the library files. Here is the cmake file for my library:
Qt Library CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project("QtLib")
set(LIB_NAME "QtLib")
# Find Qt packages.
find_package(Qt5Core)
find_package(Qt5Widgets)
set(CMAKE_AUTOMOC ON)
# Set source files to be built.
set(SOURCES
"src/LibFile1.cpp"
"src/LibFile2.cpp"
.
.
.
)
set(HEADERS
"includes/LibFile1Header.h"
"includes/LibFile2Header.h"
"includes/OtherHeaders.h"
.
.
.
)
add_library(${LIB_NAME} ${SOURCES} ${HEADERS})
set_property(TARGET ${LIB_NAME} PROPERTY FOLDER "Libs")
target_include_directories(${LIB_NAME} PRIVATE
"${Qt5Core_INCLUDE_DIRS}"
"${Qt5Widgets_INCLUDE_DIRS}"
"${CMAKE_CURRENT_BINARY_DIR}"
)
target_include_directories(${LIB_NAME} PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
)
target_link_libraries(${LIB_NAME}
Qt5::Core
Qt5::Widgets
)
Lastly I add one of my real projects (one of the ones that does not auto-complete) The structure is as follows:
-forms
-MainForm.ui
-resources
-resources.qrc
-resource files and dirs
-src
-main.cpp
-MainWindow.cpp
-includes
-MainWindow.h
The CMake file is exactly the same as the ones above. Everything makes, compiles, and runs just fine, but auto-complete stops working. I also noticed that ui_MainWindow.h (the one being auto-generated in my project binary directory) is not found.
The really odd thing is, if I just the exact same files with no changes and just open it as a stand alone project, auto-complete works.
Is there something off about my cmake files or is this a Qt related issue? The same thing happens in VS2013 which makes me think it is not QtCreator related, but I am not sure.
After reading around a little more, it seemed like this might be a QtCreator issue (although I don't know why I had problems in VS2013 when I first tested it). I ended up upgrading my QtCreator to 3.6 and my auto-complete problem went away.