cmake does not link conan's installed library - c++

I'm setting up a c++ project, which uses cmake and has two build type:
debug, having a cmake-build-debug folder
release, having a cmake-build-release folder
I want to add plog through cmake, so I installed it successfully by defining a conanfile.txt:
[requires]
plog/1.1.5
[generators]
cmake
then, I conan install . on my root and I edited my CMakeLists.txt like this:
set(CMAKE_VERBOSE_MAKEFILE ON)
cmake_minimum_required(VERSION 3.17)
project(test)
set(CMAKE_CXX_STANDARD 20)
set(CXX_EXTENSIONS OFF)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(LLVM_ENABLE_WARNINGS ON)
endif()
# ADDED ROW
include(conanbuildinfo.cmake)
add_executable(primo main.cpp io.cpp io.h)
# ADDED ROW
target_link_libraries(plog ${CONAN_LIBS})
the problem is that cmake complaints about the last row:
CMake Error at CMakeLists.txt:15 (target_link_libraries):
Cannot specify link libraries for target "plog" which is not built by this
project.
I'm new to cmake so maybe I've configured it badly. What seems to be the problem?

Related

After `libigl` update to ver 2.4.0 I can't build anymore

My CMakeLists.txt file for my old libigl testing project contains the piece below:
project(libigl)
set(LIBIGL_HOME $ENV{HOME}/apps/libigl)
set(CMAKE_PREFIX_PATH ${LIBIGL_HOME})
set(CMAKE_MODULE_PATH ${LIBIGL_HOME}/cmake)
find_package(${PROJECT_NAME} CONFIGS libigl.cmake REQUIRED)
if(${PROJECT_NAME}_FOUND)
message("-- Found ${PROJECT_NAME}")
else()
message(FATAL_ERROR "${PROJECT_NAME} is not found")
endif()
I tried to build this project with the new version 2.4.0 of the libigl library and got this message:
CMake Error at /home/hekto/apps/libigl/cmake/libigl.cmake:5 (message):
You included libigl.cmake directly from your own project. This behavior is
not supported anymore. Please add libigl to your project via
add_subdirectory(<path_to_libigl>). See the libigl example project for
more information: https://github.com/libigl/libigl-example-project/
Call Stack (most recent call first):
CMakeLists.txt:43 (find_package)
So, they recommend to use the add_subdirectory command for client projects. I looked at the CMakeLists.txt file from the recommended GitHub example project and couldn't find the add_subdirectory command:
cmake_minimum_required(VERSION 3.16)
project(example)
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Libigl
include(libigl)
# Enable the target igl::glfw
igl_include(glfw)
# Add your project files
file(GLOB SRC_FILES *.cpp)
add_executable(${PROJECT_NAME} ${SRC_FILES})
target_link_libraries(${PROJECT_NAME} PUBLIC igl::glfw)
How should I build with the new version 2.4.0 of the libigl?
OS: Ubuntu 20.04.5 LTS
Compiler: g++ (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0

CMake Errors including IXWebSocket in Ubuntu 22 (works on MacOS 12.6)

Context:
I have a cpp program built on MacOS 12.6 with the following CMakeLists.txt file.
cmake_minimum_required(VERSION 3.19.0)
project(cpp-test VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(cpp-test main.cpp)
add_library(test-helpers main.cpp ${PROJECT_SOURCE_DIR}/helpers.hpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
# this is super important in order for cmake to include the vcpkg search/lib paths!
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
# find library and its headers
find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket/IXWebSocket.h)
find_library(IXWEBSOCKET_LIBRARY ixwebsocket)
find_package(OpenSSL REQUIRED)
find_package(CURL REQUIRED)
# include headers
include_directories(${IXWEBSOCKET_INCLUDE_DIR} ${CURL_INCLUDE_DIR})
# Cmake will automatically fail the generation if the lib was not found, i.e is set to NOTFOUND
target_link_libraries(
${PROJECT_NAME} PRIVATE
${IXWEBSOCKET_LIBRARY}
OpenSSL::SSL
OpenSSL::Crypto
${CURL_LIBRARIES}
"-framework Foundation"
"-framework Security"
"-lz"
)
This compiles just fine. However, when I try to pull it into my Ubuntu VM and try to build it /build> cmake .., I get the following errors
CMake Error in CMakeLists.txt:
Found relative path while evaluating include directories of "cpp-test":
"IXWEBSOCKET_INCLUDE_DIR-NOTFOUND"
CMake Error in CMakeLists.txt:
Found relative path while evaluating include directories of
"test-helpers":
"IXWEBSOCKET_INCLUDE_DIR-NOTFOUND"
-- Generating done
What I have tried...
I have installed vcpkg and created my symlink ln -s /path/to/vcpkg /usr/local/bin/vcpkg.
I have installed ixwebsocket via vcpkg install ixwebsocket, but it seems that the CMAKE_TOOLCHAIN_FILE is not being parsed correctly.
I'm a bit lost, any help would be appreciated
This is not a great answer to the issue, but I ended up resolving it by building ixwebsocket via CMake instead.
It seems that vcpkg was not compatible with the linux distro in my VM.

C++ file cannot find library linked with CMake

I wanted to use DearImGui therefore I needed to either copy ImGui into the project or use a package manager, so I chose the latter. I'm currently using Conan as a my package manager, the file looks like this:
conanfile.txt
[requires]
boost/1.79.0
imgui/1.88
glad/0.1.36
glfw/3.3.7
[generators]
cmake_find_package
cmake_paths
CMakeDeps
CMakeToolchain
It has all the dependancies as a normal ImGui project would need as well as boost which had been downloaded as a binary previously and works fine, using just a normal header like #include <boost/asio.hpp>. I figure this happens because it was aleady installed.
I have a basic file structure that looks like this, prebuild:
conanfile.txt
CMakeLists.txt
src -
main.cpp
With this main CMakeLists I set up a linker with conan and simple setup instructions like the project name, executable, and the libraries
cmake_minimum_required(VERSION 3.23)
project(RenderCam CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/build/conan_paths.cmake)
add_executable(${PROJECT_NAME} src/main.cpp)
find_package(Boost 1.79.0 REQUIRED COMPONENTS thread system filesystem)
if(TARGET boost::boost)
target_link_libraries(${PROJECT_NAME} boost::boost)
endif()
find_package(glfw3 3.3 REQUIRED)
if(TARGET glfw)
message("Found GLFW")
target_link_libraries(${PROJECT_NAME} glfw)
endif()
find_package(imgui 1.88 REQUIRED)
if(TARGET imgui::imgui)
message("found imgui")
target_link_libraries(${PROJECT_NAME} imgui::imgui)
endif()
After running two commands (conan install .. and cmake .. -DCMAKE_BUILD_TYPE=Release) in the new build directory the CMake build responds with all the found messages for the project as well as the location of the files, which should be expected. Though when add the #include <imgui.h> to the main.cpp it states the file is not found which shouldn't be if I have linked it. On the other hand #include <boost/asio.hpp> has no errors and I can go upon my day with all of the commands. I would just like to include the directories and have tried multiple steps and guides before I took it here. For further reference, this is my conanprofile :
Configuration for profile default:
[settings]
os=Macos
os_build=Macos
arch=x86_64
arch_build=x86_64
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
build_type=Release
[options]
[conf]
[build_requires]
[env]
Don't mix up mutually exclusive generators like cmake_find_package vs CMakeDeps, or cmake_paths vs CMakeToolchain.
Here is a basic example of non-intrusive integration of conan:
conanfile.txt
[requires]
boost/1.79.0
imgui/1.88
glfw/3.3.7
[generators]
CMakeToolchain
CMakeDeps
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(RenderCam CXX)
find_package(Boost 1.79.0 REQUIRED thread system filesystem)
find_package(glfw3 3.3 REQUIRED)
find_package(imgui 1.88 REQUIRED)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE Boost::headers Boost::thread Boost::system Boost::filesystem glfw imgui::imgui)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14)
Install dependencies, configure & build:
mkdir build && cd build
conan install .. -s build_type=Release -b missing
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build . --config Release

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.

Cannot find "Findaws-lambda-runtime.cmake" on ubuntu18.04

Trying to build the hello world example, but the cmake always complain
By not providing "Findaws-lambda-runtime.cmake" in CMAKE_MODULE_PATH this
project has asked CMake to find a package configuration file provided by
"aws-lambda-runtime", but CMake did not find one.
Environment
OS : ubuntu18.04.3 LTS,64bits
install curl by : sudo apt-get install libcurl4-openssl-dev
install cmake by ubuntu software(cmake version 3.16.1)
Steps to build and install aws lambda cpp
git clone https://github.com/awslabs/aws-lambda-cpp.git
cd aws-lambda-cpp
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF \
-DCMAKE_INSTALL_PREFIX=${PWD}/install
make -j2
sudo make install
CmakeLists.txt(omit another part, want to make sure find_package works first)
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(aws_cpp_test LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/build/")
list(APPEND CMAKE_MODULE_PATH "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake/")
find_package(aws-lambda-runtime REQUIRED)
add_executable(${PROJECT_NAME} "main.cpp")
I do not use the ec2 to build the project, how could I tell the cmake where should it find the aws-lambda-runtime?
Edit :
Based on the suggestion of Yevhenii Mamontov, I change the CMakeLists.txt to
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(aws_cpp_test LANGUAGES CXX)
set(AWS_LAMBDA_CMAKE "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake/")
set(CMAKE_PREFIX_PATH "${AWS_LAMBDA_CMAKE};${CMAKE_PREFIX_PATH}")
#check the prefix paths are correct or wrong
foreach(path ${CMAKE_PREFIX_PATH})
message("Path: " ${path})
endforeach(path)
find_package(aws-lambda-runtime REQUIRED)
But it come with different error message
CMake Error at
/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake/aws-lambda-runtime-config.cmake:6
(include): include could not find load file:
/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake/#CMAKE_PROJECT_NAME#-targets.cmake
I tried with different paths
set(AWS_LAMBDA_CMAKE "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/build/install")
set(AWS_LAMBDA_CMAKE "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/build/install/lib/aws-lambda-runtime/cmake")
and tried to do not add any new path, but all of them give the same error messages
Edit 2 :
Find a way to make it work
Remove the contents of /home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake/aws-lambda-runtime-config.cmake
set path as set(AWS_LAMBDA_CMAKE "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/build/install/lib/aws-lambda-runtime/cmake")
However, this solution is awkward, should ask the cmake do not search from the path "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake" first
Edit 3:
The solution I written in Edit 2 do not work. It fail when I add
add_executable(${PROJECT_NAME} "main.cpp")
target_link_libraries(${PROJECT_NAME} PUBLIC AWS::aws-lambda-runtime)
Error messages are
Target "aws_cpp_test" links to target "AWS::aws-lambda-runtime" but the
target was not found. Perhaps a find_package() call is missing for an
IMPORTED target, or an ALIAS target is missing?
Could you try to set CMAKE_PREFIX_PATH just before the find_package?
Something like this:
set(AWS_LAMBDA_CMAKE "/home/yyyy/Qt/3rdLibs/aws-lambda-cpp/cmake/")
set(CMAKE_PREFIX_PATH "${AWS_LAMBDA_CMAKE};${CMAKE_PREFIX_PATH}")
The first set() creates a variable with the path to your lib cmake folder.
The second set() appends to CMAKE_PREFIX_PATH one more path to search for any package that you've indicated in find_package().
Find out the solution, all you need to do are set the path of the aws library installed.
Example:
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(encoder LANGUAGES CXX)
set(AWS_LAMBDA_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdLibs/aws-lambda-cpp/build/install/)
set(AWS_LAMBDA_CPP_SDK ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdLibs/aws-sdk-cpp/build/install/)
set(CMAKE_PREFIX_PATH "${AWS_LAMBDA_CMAKE};${CMAKE_PREFIX_PATH};${AWS_LAMBDA_CPP_SDK}")
find_package(CURL REQUIRED)
find_package(aws-lambda-runtime REQUIRED)
find_package(AWSSDK COMPONENTS s3)
add_executable(${PROJECT_NAME} "main.cpp")
target_link_libraries(${PROJECT_NAME}
${CURL_LIBRARIES}
AWS::aws-lambda-runtime
${AWSSDK_LINK_LIBRARIES})
aws_lambda_package_target(${PROJECT_NAME})
You may need to install following libs on your ubuntu if you haven't
sudo apt-get install zlib1g-dev libssl-dev libcurl4-openssl-dev
I got the same error, the answer marked as solution worked pretty well, but I also found tha this works:
set(aws-lambda-runtime_DIR /lib/aws-lambda/lib64/aws-lambda-runtime/cmake/)
I am using CMake 3.13 and had the lambda runtime installed on "/lib/aws-lambda" when running tha cmake as instructed by the installation instructions:
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/lib/aws-lambda