I want to generate Dbgsym packages (containing debug symbols for debugging packages). I'm using CPACK to generate Debian packages like below.
add_library( libraryA )
...
install (TARGETS libraryA EXPORT LibA COMPONENT lib)
install (EXPORT LibA COMPONENT lib DESTINATION lib/cmake/LibA)
...
set( CPACK_GENERATOR DEB )
set( CPACK_DEB_COMPONENT_INSTALL ON )
set( CPACK_COMPONENTA_ALL lib )
set( CPACK_DEBIAN_PACKAGE_DEPENDS "" )
...
set( CPACK_DEBIAN_LIB_DEBUGINFO_PACKAGE ON )
After building when running cpack --config CPackConfig.cmake I've got bellow error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
but without CPACK_DEBIAN_LIB_DEBUGINFO_PACKAGE variable it works fine.
Related
I have the following problem. I have a project (classic c++ library) called arsenalgear-cpp and want to compile it and let it be distributable for other projects.
My CMakeLists.txt is the following:
# CMake project settings
cmake_minimum_required( VERSION 3.15 )
project( arsenalgear-cpp
VERSION 1.0
DESCRIPTION "Build system for arsenalgear-cpp."
LANGUAGES CXX
)
# Error if building out of a build directory
file( TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH )
if( EXISTS "${LOC_PATH}" )
message( FATAL_ERROR "You cannot build in a source directory (or any directory with "
"CMakeLists.txt file). Please make a build subdirectory. Feel free to "
"remove CMakeCache.txt and CMakeFiles." )
endif()
# Other settings for paths
include_directories( . )
# Compile tests
add_subdirectory( test )
# Create static library
file( GLOB source src/*cpp )
add_library( arsenalgear STATIC ${source} )
# Installing headers
if( UNIX )
set( INSTALLATION_DIR_INCLUDE /usr/include )
elseif( APPLE )
set( INSTALLATION_DIR_INCLUDE /usr/local/include )
elseif( WIN32 )
set( WIN_INSTALLATION_DIR_INCLUDE "" CACHE STRING "Installation directory for Windows OSs." )
set( INSTALLATION_DIR_INCLUDE ${WIN_INSTALLATION_DIR_INCLUDE} )
endif()
INSTALL(
FILES include/containers.hpp include/math.hpp include/operators.hpp include/system.hpp include/stream.hpp include/type.hpp include/constants.hpp include/utils.hpp
DESTINATION ${INSTALLATION_DIR_INCLUDE}/arsenalgear
)
# Creating static libraries path
if( UNIX )
set( INSTALLATION_DIR_LIB /usr/lib )
elseif( APPLE )
set( INSTALLATION_DIR_LIB /usr/local/lib )
elseif( WIN32 )
set( WIN_INSTALLATION_DIR_LIB "" CACHE STRING "Installation directory for Windows OSs." )
set( INSTALLATION_DIR_LIB ${WIN_INSTALLATION_DIR_LIB} )
endif()
# Installing cmake package configuration files and libraries
INSTALL(
FILES build/libarsenalgear.a
DESTINATION ${INSTALLATION_DIR_LIB}
)
install(
FILES scripts/cmake/arsenalgearConfig.cmake
DESTINATION ${INSTALLATION_DIR_LIB}/cmake/arsenalgear
)
I will not post the content of the CMakeLists.txt of the directory test, since it is trivial.
I will post instead the content of scripts/cmake/arsenalgearConfig.cmake which is important:
# Headers path
set( arsenalgear_INCLUDE_DIRS ${PREFIX}/include/arsenalgear)
# Libraries path
set( arsenalgear_LIBRARIES ${PREFIX}/lib/libarsenalgear.a)
The library is correctly compiled and if I want to use it with an external project (once I have installed it) I should do:
find_package( arsenalgear )
target_link_libraries( ${TARGET_NAME} PRIVATE arsenalgear )
And that's fine. However I would be able to link the library using the CMake namespace, in this way:
find_package( arsenalgear )
target_link_libraries( ${TARGET_NAME} PRIVATE arsenalgear::arsenalgear )
I searched all around the web and the StackOverflow community for similar questions and found many of them, but none solved my problem.
How should I modify my CMake files in order to satisfy my requirements? Thanks.
PS: if you want to suggest also general improvements to my CMake files you are more than welcome!
I would like to use a virtual environment to call Python from C++ in Clion.
I can use Py_Initialize(); on C++ when I run it on terminal, but I cannot use it when I run it on Clion.
The following is the error message when running in Clion.
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00007fbd24916680 (most recent call first):
On the terminal, I use GNU Make to build and run the code by entering the Anaconda virtual environment. Then the code works as expected.
On the other hand, on Clion, I thought that if I set up the Anaconda virtual environment in Python Interpreter from File/Build, Execution, Deployment/Python Interpreter/, it would be referenced at runtime. However, it seems that the reference is not working properly and the above error occurred. The above error also occurred when I ran the code in the terminal without entering the virtual environment.
Does anyone know how to set this up?
Thank you.
== Aditional part ==
This is CMakeList.txt
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Python2CPP )
# Require C++14 (or Later)
set( CMAKE_CXX_STANDARD 14)
set( CMAKE_CXX_STANDARD_REQUIRED ON )
find_package(OpenCV REQUIRED)
add_definitions("-DNOMINMAX")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
add_executable(
Python2CPP
src/main.cpp
src/Python2CPP.cpp
src/Python2CPP.h )
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Python2CPP" )
# virtual python env from anaconda
set(PYTHON_INCLUDE_DIRS /home/masahiro/anaconda3/envs/virt/include/python3.6m)
set(NUMPY_INCLUDE_DIRS /home/masahiro/anaconda3/envs/virt/lib/python3.6/site-packages/numpy/core/include)
set(PYTHON_LIBRARIES /home/masahiro/anaconda3/envs/virt/lib/libpython3.6m.so)
include_directories(
${PYTHON_INCLUDE_DIRS}
${NUMPY_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS})
target_link_libraries(
Python2CPP
${PYTHON_LIBRARIES}
${OpenCV_LIBS}
)
I have reworked your CMakeLists.txt to use the standard way of finding the Python interpreter and Python libraries. Can you give it go? If you have CMake 3.14 or higher then the ability to find NumPy is already built in.
cmake_minimum_required( VERSION 3.14 )
# Create Project
project( Python2CPP )
# Require C++14 (or Later)
set( CMAKE_CXX_STANDARD 14)
set( CMAKE_CXX_STANDARD_REQUIRED ON )
find_package(Python3 COMPONENTS Interpreter Development NumPy REQUIRED)
find_package(OpenCV REQUIRED)
add_definitions("-DNOMINMAX")
add_executable(
Python2CPP
src/main.cpp
src/Python2CPP.cpp
src/Python2CPP.h)
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Python2CPP" )
target_include_directories(Python2CPP PRIVATE ${Python3_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS})
target_link_libraries(Python2CPP PRIVATE ${Python3_LIBRARIES} ${OpenCV_LIBS})
Otherwise, if you have older version of CMake, then you can add a test to check whether NumPy is available:
cmake_minimum_required( VERSION 3.6 )
# Create Project
project( Python2CPP )
# Require C++14 (or Later)
set( CMAKE_CXX_STANDARD 14)
set( CMAKE_CXX_STANDARD_REQUIRED ON )
find_package(PythonInterp REQUIRED)
find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED)
find_package(OpenCV REQUIRED)
# Find NumPy location
execute_process(
COMMAND
${PYTHON_EXECUTABLE} "-c" "import re, numpy; print(re.compile('/__init__.py.*').sub('',numpy.__file__))"
RESULT_VARIABLE _numpy_status
OUTPUT_VARIABLE _numpy_location
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT _numpy_status)
set(NumPy ${_numpy_location} CACHE STRING "Location of NumPy")
endif()
# Find NumPy version
execute_process(
COMMAND
${PYTHON_EXECUTABLE} "-c" "import numpy; print(numpy.__version__)"
OUTPUT_VARIABLE _numpy_version
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NumPy
FOUND_VAR NumPy_FOUND
REQUIRED_VARS NumPy
VERSION_VAR _numpy_version)
add_definitions("-DNOMINMAX")
add_executable(
Python2CPP
src/main.cpp
src/Python2CPP.cpp
src/Python2CPP.h )
set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "Python2CPP" )
target_include_directories(Python2CPP PRIVATE ${PYTHON_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})
target_link_libraries(Python2CPP PRIVATE ${PYTHON_LIBRARIES} ${OpenCV_LIBS})
Python virtual environment
Before building your C++ program, activate your Python virtual environment. If you're using CLion, it has Terminal tab. Select that and activate your virtual environment like this: source <virtual environment path>/bin/activate. Then cmake should find the correct Python interpreter.
I am trying to build a dbgsym package with cmake and cannot find any help anywhere. I've seen CPACK_DEBIAN_DEBUGINFO_PACKAGE but cannot use it in CMakeLists.txt since the version of CMake I am using does not have that.
I do have set(CMAKE_BUILD_TYPE Debug).
I want to be able to include debug symbols with the package.
The following CMakeLists.txt creates a debug symbol package. I didn't check if it's usable in gdb, though.
cmake_minimum_required(VERSION 3.13)
message( STATUS "Build type is " ${CMAKE_BUILD_TYPE} )
project( demonstrator
DESCRIPTION "Demonstrator"
VERSION 1.0.0
LANGUAGES CXX )
add_library( my_library SHARED )
target_sources( my_library
PRIVATE my_code.cpp )
target_include_directories( my_library
PUBLIC include )
set_target_properties ( my_library
PROPERTIES
PUBLIC_HEADER "include/my_code.hpp" )
install(
TARGETS my_library
ARCHIVE
DESTINATION lib
COMPONENT runtime
LIBRARY
DESTINATION lib
COMPONENT runtime
PUBLIC_HEADER
DESTINATION include
COMPONENT development
)
set( CPACK_PACKAGE_NAME ${PROJECT_NAME} )
set( CPACK_PACKAGE_CONTACT "Contact name" )
set( CPACK_PACKAGE_VERSION ${PROJECT_VERSION} )
set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Description" )
set( CPACK_GENERATOR DEB )
set( CPACK_DEB_COMPONENT_INSTALL ON )
set( CPACK_DEBIAN_PACKAGE_DEPENDS "" )
set( CPACK_DEBIAN_RUNTIME_DEBUGINFO_PACKAGE ON )
include( CPack )
You might be interested in this ticket regarding a bug in CMake regarding debug symbol creation.
i have a little problem with run test on travis ci. I wrote Cmakelists.txt and .travis.yml files, which contain this code:
language: cpp
compiler:
- gcc
install:
- sudo apt-get install libgtest-dev
before_script:
- mkdir build
- cd build
- cmake --version
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON ..
script: make && make test
and cmakelists.txt file:
cmake_minimum_required( VERSION 2.6 )
project ( CodeProject )
project ( TestProject )
set( CMAKE_CXX_STANDARD 14 )
set( CMAKE_CXX_STANDARD_REQUIRED on )
include_directories ( ${CodeProject_SOURCE_DIR}/code_src/ )
include_directories ( ${TestProject_SOURCE_DIR}/test_src/ )
set ( CodeProject_SOURCES ${CodeProject_SOURCE_DIR}/code_src/main.cpp )
set ( TestProject_SOURCES ${TestProject_SOURCE_DIR}/test_src/mainTest.cpp )
set( CMAKE_EXECUTABLE_OUTPUT_PATH "build/${CodeProject}" )
add_executable( CodeProject ${CodeProject_SOURCES} )
add_executable( TestProject ${TestProject_SOURCES} )
When i try build my solution on travis ci, i recieve this kind of message:
make: *** No rule to make target `test'. Stop.
The command "make && make test" exited with 2.
What problem?
You have to enable testing by enable_testing() first. Each test is added by add_test() (requires a exe target).
# ...
# Enables 'test' target
enable_testing()
# Create your test executable
add_executable(TestProject ${TestProject_SOURCES})
# Register the test
add_test(NAME TestProject COMMAND TestProject)
# Add further tests ...
I have a simple project structure derived from the amazing tutorial
https://rix0r.nl/blog/2015/08/13/cmake-guide/
It looks as follows:
- src
- CMakeLists.txt
- mylib
- include/mylib/mylibclass.h
- src/mylibclass.cpp
- CMakeLists.txt
- myapp
- src/myapp.cpp
- CMakeLists.txt
The top level CMakeLists.txt contains:
cmake_minimum_required( VERSION 3.6 )
project( sample_project VERSION 0.1 LANGUAGES CXX )
set( BUILD_SHARED_LIBS ON CACHE BOOL "" )
add_subdirectory( mylib )
add_subdirectory( myapp )
The CMakeLists.txt in the mylib folder contains:
add_library( mylib src/mylibclass.cpp include/mylib/mylibclass.h )
set_target_properties( mylib PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
target_include_directories( mylib
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> PRIVATE src )
And the one in the myapp folder contains:
add_executable( myapp src/myapp.cpp )
target_link_libraries( myapp mylib )
I want to use this structure to develop both mylib (as a shared or static library as determined by BUILD_SHARED_LIBS) and myapp. For this, I want to set myapp as my startup project in Visual Studio and compile and run in the MSVC debugger. This is not possible for the shared library case without extra CMake code, as the myapp.exe doesn't know where to find the mylib.dll.
What is best CMake practice to tell the program where to find the dll?
Edit:
Based on the suggestions by #Andre, I've added the following lines to the top level CMakeLists.txt:
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out CACHE STRING "" )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out CACHE STRING "" )
The problem occurs, because your mylib.dll is not in the same folder as your myapp.exe nor is it in the %PATH% environment variable when Visual Studio tries to start your myapp.exe
The obvious solution is to make sure both dll and exe are in the same folder. There are several ways to do this:
Put both exe and dll into a single "output" directory by setting the RUNTIME_OUTPUT_DIRECTORY and the LIBRARY_OUTPUT_DIRECTORY properties on your targets:
set_target_properties( myapp PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${sample_project_BINARY_DIR}/build_results/bin )
set_target_properties( mylib PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${sample_project_BINARY_DIR}/build_results/bin )
This will produce the myapp.exe and mylib.dll into a single build_results/bin folder in your top-level build folder.
Or by setting the the global CMAKE_RUNTIME_OUTPUT_DIRECTORY and CMAKE_LIBRARY_OUTPUT_DIRECTORY variables which will do this for all targets in your sample_project.
Copy the dll to the exe location after building, e.g. with
add_custom_command(TARGET mylib
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy mylib.dll ${myapp_BINARY_DIR}/.
)