CMake add external libraries located within the project folder - c++

Preface: I am on Windows and wish to easily send this project to someone else on a different OS.
My folder structure is:
EigenTest/
libs/
├─ Eigen3/
├─ OpenBLAS C Asm/
src/
├─ main.cpp
My cmake file:
cmake_minimum_required(VERSION 3.22)
project(EigenTest)
set(CMAKE_CXX_STANDARD 20)
add_executable(EigenTest src/main.cpp)
add_library(EigenLib STATIC)
target_include_directories(EigenLib INTERFACE "libs/Eigen3")
target_link_libraries(EigenTest PRIVATE EigenLib)
add_library(OpenBlasLib STATIC)
target_include_directories(OpenBlasLib PRIVATE "libs/OpenBLAS C ASM")
target_link_libraries(EigenTest PRIVATE OpenBlasLib)
For some reason, I get an error that there are no sources when both Eigen3 and OpenBLAS have their own CmakeList.txt and source files in those folders.
Error:
CMake Error at CMakeLists.txt:8 (add_library):
No SOURCES given to target: EigenLib
CMake Error at CMakeLists.txt:14 (add_library):
No SOURCES given to target: OpenBlasLib

Related

Add static lib .lib and .a file in android studio

I'm trying to add .lib file and .a (x64) file to Android project with a native component but I got an error in CMakelists.txt
error:
CMake Error: Cannot determine link language for target "LIB".
CMake Error: CMake can not determine linker language for target: LIB
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
my following CMakelists like:
cmake_minimum_required(VERSION 3.20)
project(testGu)
set(CMAKE_CXX_STANDARD 14)
include_directories(GuruX)
link_directories(GuruX/include)
add_library(guruxLib STATIC IMPORTED )
add_executable(testGu main.cpp)
set_target_properties(libGuruX PROPERTIES IMPORTED_LOCATION D:\\testGu\\GuruX\\lib\\libGuruX.a)
add_library(LIB GuruX/lib/GuruxDLMS)
target_link_libraries(LIB SHARED GuruX/lib/GuruxDLMS)
where
|-GuruX
|-lib
|-libGuruX.a
|-GuruxDLMS.lib
|-includes (*.h files)

Generate grpc files for a library target in CMAKE

In the following project structure(from my previous question):
root/
├─ CMakeLists.txt
├─ protocol/
│ ├─ msg.proto
│ ├─ myrpc.proto
│ ├─ CMakeLists.txt
├─ app/
│ ├─ main.cpp
│ ├─ CMakeLists.txt
I could generate the protobuf files and add them as dependency into the app target. Now I am trying to generate grpc files inside the same library.
Something is not right with the grpc generation function, which is based on this answer and blog post;as the following error message is printed:
-- Configuring done
-- Generating done
-- Build files have been written to: /media/davids91/Work/rafko/src/main/cxx/build
[ 1%] Running grpc protocol buffer compiler on /usr/local/bin/grpc_cpp_plugin
/usr/local/bin/grpc_cpp_plugin: File does not reside within any path specified using --proto_path (or -I). You must specify a --proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names -- protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think).
make[2]: * [protocol/CMakeFiles/protocol.dir/build.make:138: /media/usr/local/bin/grpc_cpp_plugin.grpc.pb.h] Error 1
make[1]: * [CMakeFiles/Makefile2:276: protocol/CMakeFiles/protocol.dir/all] Error 2
make: * [Makefile:103: all] Error 2
I can see that the install folder looks correct, as that is where the grpc library was installed from source.
root CMakeLists.txt:
cmake_minimum_required(VERSION 3.18.4)
project(
root
VERSION 0.1
LANGUAGES CXX
)
add_subdirectory(protocol)
add_subdirectory(app)
protocol CMakeLists.txt:
add_library(protocol)
target_include_directories(protocol
PUBLIC
.
${CMAKE_CURRENT_BINARY_DIR}
${Protobuf_INCLUDE_DIRS}
)
find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG REQUIRED)
target_link_libraries(protocol ${Protobuf_LIBRARIES})
get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
protobuf_generate( TARGET protocol LANGUAGE CPP PROTOS msg.proto )
protobuf_generate(
TARGET
protocol
LANGUAGE
grpc
PROTOS
myrpc.proto
PLUGIN
"protoc-gen-grpc=${grpc_cpp_plugin_location}"
)
app CMakeLists.txt:
add_library(app)
target_link_libraries(app PUBLIC protocol)
target_include_directories(app PUBLIC .)
target_sources(app
PRIVATE
main.cpp
)
What might be missing from this solution to generate out the grpc files based on the plugins?
After some experimenting and closely looking at the example here I figured it out!
I updated protocol CMakeLists.txt:
changed
find_package(Protobuf REQUIRED)
to
find_package(Protobuf CONFIG REQUIRED)
I figure it tells CMake that the proto files are being procesed at configuration time, but any deeper explanation is welcome!

Problem building C++ code with Eigen3 and CMake eigen3/Eigen/Core' file not found

I have simple C++ project that is organized like this:
project
|-- Input
| |-- data.cpp <-- this file used eigen3
| |--- CmakeLists.txt
|--- main.cpp
|--- CmakeLists.txt
Basically I am trying to create .so library from input and have main.cpp calls functions in it.
CMake under project looks like this
cmake_minimum_required(VERSION 3.20)
project(myProj)
find_package (Eigen3 REQUIRED)
# Dependencies paths
set(EIGEN_INC_DIR ${EIGEN3_INCLUDE_DIR})
if (TARGET Eigen3::Eigen)
message("Eigen was found"). <--- I do see this message so Eigen3 package is found
endif (TARGET Eigen3::Eigen)
add_subdirectory(Input)
<more cmake commands to link with main.cpp>
CMake under Input looks like this
cmake_minimum_required(VERSION 3.20)
set(TARGET_LIB_INPUT input_data)
set(SRC_FILES
Data.cpp
)
set(INC_DIRS
${EIGEN_INC_DIR}
)
include_directories(${INC_DIRS})
add_library (${TARGET_LIB_INPUT} SHARED ${SRC_FILES})
target_link_libraries (${TARGET_LIB_INPUT} Eigen3::Eigen)
in file data.cpp, I do the following include to eigen3
#include <eigen3/Eigen/Core>
But I keep getting the error
fatal error: 'eigen3/Eigen/Core' file not found
I see the build command clearly include eigen directory:
-I /usr/local/include/eigen3
Anybody knows what am I missing here?
Thanks for help
The include directory defined in Eigen3::Eigen already includes eigen3 (e.g., /usr/include/eigen3 on Ubuntu). So you should use #include <Eigen/Core>.
You can check this by:
find_package(Eigen3 REQUIRED CONFIG)
# checking property of the target
get_target_property(inc_dir Eigen3::Eigen INTERFACE_INCLUDE_DIRECTORIES)
message("[DEBUG] inc_dir: ${inc_dir}")
# or checking the Eigen variable
message("[DEBUG] EIGEN3_INCLUDE_DIRS: ${EIGEN3_INCLUDE_DIRS}")
EIGEN3_INCLUDE_DIRS is defined in here.

CMake CUDA separate compilation static lib link error on Windows but not on Ubuntu

I am using CMake to compile a CUDA project, which contains a static lib and a main file. MWE here. The directory is:
├── CMakeLists.txt
├── src
├── mylib.h
├── mylib.cu
├── test
├── CMakeLists.txt
├── main.cpp
On Ubuntu everything works fine. But on Windows I got a link error:
mylib.lib(mylib.cu.obj) : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_40_tmpxft_00006024_00000000_7_mylib_cpp1_ii_935b38c5 referenced in function "void __cdecl __sti____cudaRegisterAll(void)" (?__sti____cudaRegisterAll##YAXXZ)\build\test\Release\main.exe : fatal error LNK1120: 1 unresolved externals
This issue only relates to the first CMakeLists.txt:
cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)
# check requirements
find_package(CUDA 8.0 REQUIRED)
# set include and link directories
if (UNIX)
set(CUDA_SAMPLE_INC ${CUDA_TOOLKIT_ROOT_DIR}/samples/common/inc)
set(CUDA_TARGET_INC ${CUDA_TOOLKIT_ROOT_DIR}/targets/x86_64-linux/include)
set(CUDA_SAMPLE_LKN ${CUDA_TOOLKIT_ROOT_DIR}/targets/x86_64-linux/lib)
endif (UNIX)
if (WIN32)
set(CUDA_SAMPLE_INC C:/ProgramData/NVIDIA\ Corporation/CUDA\ Samples/v9.0/common/inc)
set(CUDA_TARGET_INC C:/Program\ Files/NVIDIA GPU\ Computing\ Toolkit/CUDA/v9.0/include)
set(CUDA_SAMPLE_LKN C:/Program\ Files/NVIDIA\ GPU\ Computing\ Toolkit/CUDA/v9.0/lib/x64)
endif (WIN32)
include_directories(src ${CUDA_SAMPLE_INC} ${CUDA_TARGET_INC})
link_directories(${CUDA_SAMPLE_LKN})
# define and compile our static library
set(STATIC_MY_LIB mylib)
add_library(${STATIC_MY_LIB} STATIC src/mylib.cu)
# install
install(TARGETS ${STATIC_MY_LIB}
ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/lib
LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/lib)
# comment it out to suppress the error
set_target_properties( ${STATIC_MY_LIB} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
# add our test project
add_subdirectory(test)
If I comment out set_target_properties( ${STATIC_MY_LIB} PROPERTIES CUDA_SEPARABLE_COMPILATION ON), the link error is gone.
Environments:
Ubuntu 16.04, gcc 5.4, Tesla Titan X, CUDA 9.1, CMake 3.10.1
Windows 10, VS 2015, K20c, CUDA 9.0, CMake 3.10.1
I have tried suggestions in 1, 2. But none of them works.
Why this happens? And how to overcome?
After struggling with this issue for several days, I think I have found a solution. When creating the static library using CMake, set CUDA_RESOLVE_DEVICE_SYMBOLS, i.e. with
set_target_properties(your_project PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
According to this article from Nvidia, this setting forces CMake to compile and link all CUDA symbols (function calls and the like) when the library is built.
If you need separable compilation device linking to occur before
consumption by a shared library or executable,you can explicitly
request CMake to invoke device linking by setting the target property
CUDA_RESOLVE_DEVICE_SYMBOLS

CMake and OpenCV 3.0

I'm trying to set up a really basic project with Cmake and OpenCV 3.0.
My folder structure looks like this:
OpenCVTest
|
|--- build
|--- data
|--- include
|--- src
|--- CMakeLists.txt
The CMakeLists.txt file has the following content:
cmake_minimum_required(VERSION 3.4)
project(OpenCVTest)
find_package(OpenCV REQUIRED)
include_directories(
${CMAKE_SOURCE_DIR}/include
${OpenCV_INCLUDE_DIRS})
set(SOURCES
src/main.cpp
src/MyData.cpp
include/MyData.h)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
I extracted OpenCV, set the environment variable OPENCV_DIR = <PATH_TO_OPEN_CV>\opencv\build\x86\vc12, and added %OPENCV_DIR%\bin to the PATH variable in Windows, as suggested by the OpenCV + CMake tutorial.
When running CMake, the following error message occurs:
CMake Error at CMakeLists.txt:4 (find_package):
By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has asked
CMake to find a package configuration file provided by "OpenCV", but CMake did
not find one.
Could not find a package configuration file provided by "OpenCV" with any
of the following names:
OpenCVConfig.cmake
opencv-config.cmake
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
provides a separate development package or SDK, be sure it has been
installed
I therefore changed the value of the environment variable OpenCV_DIR = <PATH_TO_OPEN_CV>\opencv\build, where the OpenCVConfig.cmake file is located.
After doing so (and restarting to Windows to update the environment variables!!!), CMake is able to configure and generate the project successfully.
However, CMake uses static library linking...
OpenCV STATIC: ON
Found OpenCV 3.0.0 in <PATH_TO_CMAKE>/opencv/build/x86/vc12/staticlib
... and you have to switch the Runtime Library in Visual Studio (C/C++ --> Code Generation --> Runtime Library) to /MTd.
Adding...
set(BUILD_SHARED_LIBS ON)
before
find_package(OpenCV REQUIRED)
will force CMake to use dynamic linking, however, then the PATH variable does not contain the correct path to the OpenCV DLL's, and <PATH_TO_OPEN_CV>\opencv\build\x86\vc12\bin needs to be added (for 32bit and VS2013).
All ob the above solutions seem quite inelegant and not really portable to me. I also tried several FindOpenCV.cmake files, however, none of them were able to correctly find the OpenCV directory.
My question is: Can anybody provide a solution for setting up a very basic CMake + OpenCV 3.0 example project, that does not have the above described shortcomings?