Adding a dll to CMake - cmake

I am trying to add an external library, called OpenAlpr, with alpr.h and openalpr.lib/openalpr.dll files to my CLion project. I put the header file in my project directory and included it in the source code, but I have no idea how to add the .dll or .lib files. I looked at other answers like this and this, but they are too confusing for me and I could not get mine to work; the following errors are output when I try to run:
undefined reference to `alpr::Alpr::Alpr(std::string, std::string, std::string)'
.text+0x9f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `alpr::Alpr::Alpr(std::string, std::string, st
undefined reference to `alpr::Alpr::getVersion()'
(.text+0xf3): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `alpr::Alpr::getVersion()'
undefined reference to `alpr::Alpr::~Alpr()'
.text+0x123): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `alpr::Alpr::~Alpr()'
undefined reference to `alpr::Alpr::~Alpr()'
.text+0x1af): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `alpr::Alpr::~Alpr()'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/AlprCpp.dir/build.make:84: AlprCpp.exe] Error 1
make[2]: *** [CMakeFiles/Makefile2:73: CMakeFiles/AlprCpp.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/AlprCpp.dir/rule] Error 2
make: *** [Makefile:118: AlprCpp] Error 2
These are the contents of my CMake file:
cmake_minimum_required(VERSION 3.12)
project(AlprCpp)
set(CMAKE_CXX_STANDARD 14)
add_executable(AlprCpp main.cpp alpr.h)
link_directories(C:\\Projects\\AlprCpp)
find_library(AlprCpp openalpr.lib)
Thanks in advance.

Do not copy the header files of your libraries to your project.
At some point you will need to go through tutorials the hard way and learn how to use find_package. If you just want to get thing to work quickly, here is one simplistic way (assuming file names Alpr.lib Alpr.h) .
cmake_minimum_required(VERSION 3.12)
project(AlprCpp)
set(ALPR_LIBRARY "" CACHE FILEPATH "Full path to Alpr.lib")
set(ALPR_INCLUDE_PATH "" CACHE PATH "Directory containing Alpr.h")
include_directories(${ALPR_INCLUDE_PATH})
add_executable(AlprCpp main.cpp)
target_link_libraries(AlprCpp ${ALPR_LIBRARY })
As for the dll files (assuming Windows), either set the PATH environment variable or copy the DLL to the directory where the .exe is located.

Related

Pre-compiling googletest to run on baremetal

I've been trying to use google test on bare metal and followed the slightly harder variant of the website below to precompile google test, obtain the library file and then link it in a project's CMake
https://clarkli86.wordpress.com/2016/01/28/build-googletest-for-baremetal-targets-stm32/
The CMake runs smoothly throughout the project, in which I'm trying to integrate google test, up to the part it starts building google test
The CMakeLists file of the folder containing the tests and google test looks like this:
set(BINARY ${CMAKE_PROJECT_NAME}_tst)
set(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/googletest/)
add_executable(${BINARY} ${SOURCE})
add_test(NAME ${BINARY} COMMAND ${BINARY})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/googletest/googletest/include/gtest)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/googletest/googletest/include/gtest)
target_link_libraries(${BINARY} PUBLIC Library gtest)
which gives the following error:
SDK_test/testing/main.cpp:3:25: fatal error: gtest/gtest.h: No such file or directory
compilation terminated.
make[2]: *** [testing/CMakeFiles/SdkTest_tst.dir/build.make:63: testing/CMakeFiles/SdkTest_tst.dir/main.cpp.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:9691: testing/CMakeFiles/SdkTest_tst.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
On the main.cpp file, gtest is called using:
#include <gtest/gtest.h>
I've tried to build the project using this flag:
-l/testing/googletest/googletest/include/gtest
include the path directly in the CMakeLists, and all result in the error above
If I uncomment the add_subdirectory line, the make build fails due to the pthreads and sleep libraries
examples:
testing/googletest/googletest/include/gtest/internal/gtest-port.h:1453:24: error: 'nanosleep' was not declared in this scope
nanosleep(&time, NULL);
testing/googletest/googletest/include/gtest/internal/gtest-port.h:1499:3: error: 'pthread_mutex_t' does not name a type
pthread_mutex_t mutex_;
Any suggestions on how to properly link the library?

ld: library not found for -lnetcdf

I am new to CMake. I can not resolve the flowing error. Could someone help me?
------------ERROR--------------
ld: library not found for -lnetcdf
collect2: error: ld returned 1 exit status
make[3]: *** [NUP] Error 1
make[2]: *** [CMakeFiles/NUP.dir/all] Error 2
make[1]: *** [CMakeFiles/NUP.dir/rule] Error 2
make: *** [NUP] Error 2
------------------- CMake File------------------
cmake_minimum_required(VERSION 3.10.0)
project(NUP Fortran)
enable_language(Fortran)
set(INCLUDE_FILE /usr/local/Cellar/netcdf/4.7.4/include)
set(lib_FILE /usr/local/Cellar/netcdf/4.7.4/lib)
find_package(netcdf REQUIRED)
if(netcdf_FOUND)
include_directories(${INCLUDE_FILE})
set(
SOURCE_FILES
${PROJECT_BINARY_DIR} unpack.f90
)
add_executable(NUP ${SOURCE_FILES} )
target_link_libraries(NUP netcdf)
endif()
--------------unpack.f90-------------------
PROGRAM unpack_array
IMPLICIT NONE
INCLUDE 'netcdf.inc'
INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307)
......
I am using MACOS Catalina. Apple clang version 11.0.3 (clang-1103.0.32.59)
Target: x86_64-apple-darwin19.4.0
If you're using find_package() to find NetCDF on your machine, you shouldn't need to manually specify the paths as you have. Let find_package do that for you.
Note: CMake doesn't ship with a Find Module for NetCDF, so you'll have to download one (like this one) from the internet. Then, you need to tell CMake where to locate this FindNetCDF.cmake file on your system using CMAKE_MODULE_PATH. Finally, you can use the NetCDF::NetCDF imported target to link NetCDF to your project's targets.
cmake_minimum_required(VERSION 3.10.0)
project(NUP Fortran)
# Don't need this, you already enabled Fortran above in the 'project' call.
enable_language(Fortran)
set(INCLUDE_FILE /usr/local/Cellar/netcdf/4.7.4/include)
set(lib_FILE /usr/local/Cellar/netcdf/4.7.4/lib)
# Add the location of the 'FindNetCDF.cmake' file to your module path.
list(APPEND CMAKE_MODULE_PATH "/path/to/downloaded/find/module")
# Then, call find package for NetCDF.
find_package(NetCDF REQUIRED)
if(${NetCDF_FOUND})
# Don't need this if you use the imported target below.
include_directories(${INCLUDE_FILE})
# Don't provide directories with source file list.
set(SOURCE_FILES
${PROJECT_BINARY_DIR}
unpack.f90
)
add_executable(NUP ${SOURCE_FILES})
# Use the imported target to link netcdf instead.
target_link_libraries(NUP PRIVATE NetCDF::NetCDF)
endif()
As commented, there are other approaches to adding NetCDF to your CMake project. If you use a different find module, the syntax of the provided NetCDF CMake variables and imported targets may be slightly different. You'll have to examine the find module file itself.
In addition, you may instead use a CMake package configuration file (e.g. netCDFConfig.cmake) downloaded from the internet to add NetCDF to your project. In this case, you would still use find_package(), but you would specify the configuration file's location using CMAKE_PREFIX_PATH, rather than CMAKE_MODULE_PATH.
You can find detailed descriptions for each of these approaches in the CMake find_package() documentation. I highly encourage you spend some time to read it.

Linking with a custom external library in CMAKE

There is a project, when building the project has problem with a linking library to the project.
I would be very grateful if someone told me how to solve this problem.
As I understand the problem is in the correct location of the library. So that when build the project correctly linked with it.
This is projects file CmakeList
cmake_minimum_required(VERSION 3.5.1)
project(maintenance)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC OFF)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Charts REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5Network REQUIRED)
include_directories(../../088)
#include(FindPackageHandleStandardArgs)
#find_library(Network_LIBRARY NAMES NetworkCommunication PATHS ../../088/build-libs-ubuntu-Release)
#find_package_handle_standard_args(Network DEFAULT_MSG Network_LIBRARY)
add_library(NetworkCommunication SHARED IMPORTED)
set_property(TARGET NetworkCommunication PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/../../088/build-libs-ubuntu-Release/libNetworkCommunication.so)
set(Network_LIBRARY NetworkCommunication)
#link_directories(${CMAKE_CURRENT_LIST_DIR}/../../088/build-libs-ubuntu-Release)
qt5_add_resources(RCC_RESOURCES resources.qrc)
file(GLOB SOURCE_FILES_2
${CMAKE_CURRENT_SOURCE_DIR}/cop/*.h
${CMAKE_CURRENT_SOURCE_DIR}/cop/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/curves/*.h
${CMAKE_CURRENT_SOURCE_DIR}/curves/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/curves/shapes/*.h
${CMAKE_CURRENT_SOURCE_DIR}/curves/shapes/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/general/*.h
${CMAKE_CURRENT_SOURCE_DIR}/general/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/load_cells/*.h
${CMAKE_CURRENT_SOURCE_DIR}/load_cells/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/motors/*.h
${CMAKE_CURRENT_SOURCE_DIR}/motors/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/passive_mode/*.h
${CMAKE_CURRENT_SOURCE_DIR}/passive_mode/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/settings/*.h
${CMAKE_CURRENT_SOURCE_DIR}/settings/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/system/*.h
${CMAKE_CURRENT_SOURCE_DIR}/system/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../Gener095/Messages/*.h
${CMAKE_CURRENT_SOURCE_DIR}/../Gener095/Messages/*.cpp
)
set(SOURCE_FILES
Error.cpp
Error.hpp
main.cpp
MainWindow.cpp
MainWindow.h
NetworkCommunicator.cpp
NetworkCommunicator.h
Utils.cpp
Utils.h
ITab.h
)
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${SOURCE_FILES_2} ${RCC_RESOURCES})
#target_link_libraries(${PROJECT_NAME} ${Network_LIBRARY})
target_link_libraries(${PROJECT_NAME} NetworkCommunication)
target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::Core Qt5::Gui Qt5::Charts Qt5::Xml Qt5::Network)
include(../../088/BuildUtilities/scripts/lib_setup.cmake)
and logs with errors
...
[ 95%] Building CXX object CMakeFiles/maintenance.dir/qrc_resources.cpp.o
[ 97%] Building CXX object CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o
[100%] Linking CXX executable maintenance
CMakeFiles/maintenance.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow(QMainWindow*)':
/media/blinct/free1/QtProjects/Applications/095/maintenance/MainWindow.cpp:74: undefined reference to `TenzGraphTab::TenzGraphTab(QWidget*)'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o: In function `AngleSensors::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)':
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:92: undefined reference to `AngleSensors::OnSetNullPosition()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:93: undefined reference to `AngleSensors::OnResetAccel()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:94: undefined reference to `AngleSensors::OnDataReceived(QString, QMap<QString, QVariant>)'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:95: undefined reference to `AngleSensors::OnHandleUp()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:96: undefined reference to `AngleSensors::OnHandleDown()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:97: undefined reference to `AngleSensors::OnHandleReleased()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:98: undefined reference to `AngleSensors::OnHandleTimer()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x28): undefined reference to `AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x30): undefined reference to `AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x1c0): undefined reference to `non-virtual thunk to AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x1c8): undefined reference to `non-virtual thunk to AngleSensorColumn::~AngleSensorColumn()'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlSerialPortImpl::setRequestToSend(bool)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `g_sVersion_NetworkCommunication'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlUdpSocketImpl::writeDatagram(QByteArray const&, QHostAddress const&, unsigned short)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::isListening() const'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlFileImpl::close()'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::hasPendingConnections() const'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpSocketImpl::connectToHost(QHostAddress const&, unsigned short)'
...
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlUdpSocketImpl::readDatagram(char*, long long, QHostAddress*, unsigned short*)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::close()'
collect2: error: ld returned 1 exit status
CMakeFiles/maintenance.dir/build.make:936: recipe for target 'maintenance' failed
make[3]: *** [maintenance] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/maintenance.dir/all' failed
make[2]: *** [CMakeFiles/maintenance.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/maintenance.dir/rule' failed
make[1]: *** [CMakeFiles/maintenance.dir/rule] Error 2
Makefile:118: recipe for target 'maintenance' failed
make: *** [maintenance] Error 2
Thanks in advance.
For a very long time I can not understand how to solve this problem.
If NetworkCommunication is something you've written and already have installed, then consider including a FindNetworkCommunication.cmake file with the package. That file should contain a method for finding NetworkCommunication like so:
# Sets NetworkCommunication_FOUND if found.
#
# If NetworkCommunication_FOUND is TRUE, then the following variables are also
# set:
#
# NetworkCommunication_LIBRARY - Full path to library to link
# NetworkCommunication_INCLUDE_DIR - Path to include directory
#
# $NetworkCommunicationDIR is an environment variable that would correspond to the
# ./configure --prefix=$NetworkCommunicationDIR used in building NetworkCommunication.
#
find_path(NetworkCommunication_INCLUDE_DIR NetworkCommunication.h
HINTS
ENV NetworkCommunicationDIR
PATH_SUFFIXES include/NetworkCommunication include/NetworkCommunication include
PATHS
/opt/local
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Alexey\\NetworkCommunication\\1.00.0000;InstallDir]
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_NetworkCommunication_ARCH_DIR libs/Win64)
else()
set(_NetworkCommunication_ARCH_DIR libs/Win32)
endif()
find_library(NetworkCommunication_LIBRARY
NAMES NetworkCommunication
HINTS
ENV NetworkCommunicationDIR
PATH_SUFFIXES lib64 lib libs64 libs ${_NetworkCommunication_ARCH_DIR}
PATHS
/opt/local
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Alexey\\NetworkCommunication\\1.00.0000;InstallDir]
)
unset(_NetworkCommunication_ARCH_DIR)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NetworkCommunication DEFAULT_MSG NetworkCommunication_LIBRARY NetworkCommunication_INCLUDE_DIR)
mark_as_advanced(NetworkCommunication_LIBRARY NetworkCommunication_INCLUDE_DIR)
Copy FindNetworkCommunication.cmake into the cmake installation's Modules folders (/usr/share/cmake-3.8/Modules) or copy it to a local folder and include the path to that folder in ${CMAKE_MODULES_PATH}.
Next, in your CMakeLists.txt file of your maintenance project add the following after add_executable
Find_Package(NetworkCommunication REQUIRED)
if (NetworkCommunication_FOUND)
target_include_directories(${PROJECT_NAME} ${NetworkCommunication_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${NetworkCommunication_LIBRARY})
endif (NetworkCommunication_FOUND)
This is a good solution if NetworkCommunication is an independant library which is used by maintenance but you intend to have it used by several other libraries too. If NetworkCommunication is part of the same project solution as maintenance and is really only meant to be linked to one project ever, then there are probably simpler solutions.
In maintenance.pro for Qt Creator i have this link for this library
U_LIB_DIR_PREFIX += ../../088/build-libs
U_LIBS += NetworkCommunication
There are many similar libraries for another project and I linked like
U_LIBS += NetworkCommunication \
Logging \
UnitController \
TherapyRunnersController \
GenersControllerCommon
All these libraries are build as dynamic libraries. And after this I link this libraries to projects.
Maybe there is another way how to link library to the project?
Because if you compare this option
U_LIB_DIR_PREFIX += ../../088/build-libs-ubuntu-Release
U_LIBS += NetworkCommunication
from QtCreator project file maintenance.pro and and writing a module for each library, it turns out very strange and difficult in comparison with 2 lines from *.pro

GNU Fortran cannot find library file although its physically there

I am trying to link a precompiled BLAS dll to a Fortran example, the linker refuses.
I read:
gfortran can't find library that IS there unfortunately what helped there didn't work for me.
Specifically:
gfortran -o "Test2" ./main.o -l"C:/Users/abc/workspace/Test2/blasdyndbgx64.dll"
c:/Program Files (x86)/mingw32/bin/../lib/gcc/i686-w64-mingw32/4.8.2/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lC:/Users/abc/workspace/Test2/blasdyndbgx64.dll
collect2.exe: error: ld returned 1 exit status
make: *** [Test2] Error 1
The previous link I provided recommended to use the -l"entire/path/filename.ext", yet it still throws at me that error whatever I try. Obviously the file is there,
dir to the path+filename finds the dll.
I guess that since compilers are not my strong side I am still missing something trivial.

Building project involving cmake, how do I make it aware of libraries

When I try to build this project with cmake and gcc on a 64-bit linux (debian) machine, I get an error from the linker:
Linking C executable ../../../../cpsadamsx
/home/dala/lib64/libSimTKcommon.so: undefined reference to `dlopen'
/home/dala/lib64/libSimTKcommon.so: undefined reference to `dlclose'
/home/dala/lib64/libSimTKcommon.so: undefined reference to `dlerror'
/home/dala/lib64/libSimTKcommon.so: undefined reference to `dlsym'
collect2: ld returned 1 exit status
make[2]: *** [cpsadamsx] Error 1
make[1]: *** [sundials/examples/cpodes/serial/CMakeFiles/cpsadamsx.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
Apparently dlopen, dlclose, dlerror and dlsym are references to libdl.so. I have that library in /lib64/libdl.so.2, but why is it not found?
Would it have been a normal './configure; make; make install'-path I could have set the LIBS variable and issued the configure command like this (I think):
export LIBS=-ldl && ./configure
But how do I do it now?
UPDATE:
So it seems that the (or at least a) library is found, but does not contain the symbols in question. Perhaps it tries with the 32-bit library in /lib?
Is there a way to disassemble /lib64/libdl.so.2 to make sure it does have the references dlopen etc?
The problem now seems to guide the build tools to the correct version of the library.
As this question is showing up on google and both answers won't point to the correct solution here it is:
In your CMakeLists.txt add ${CMAKE_DL_LIBS} to link against idl.
It should look similar to this:
target_link_libraries(ExpandableTest
${CMAKE_DL_LIBS}
Expandable
ExpandableTestLibrary
)
Probably you need to add target_link_libraries() - see link text
Add this in CMakeLists.txt and it should work:
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ldl")