Testing with google and cmake [duplicate] - c++

Similar issue here.
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
# Locate GTest
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
# Add test cpp file
add_executable(foo foo.cpp)
# Link test executable against gtest & gtest_main
target_link_libraries(foo ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread)
And my foo.cpp:
#include <gtest/gtest.h>
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Now, all works fine when using the g++ compiler. However, when attempting to use QNX's compiler, ntox86-c++, I run into this problem:
CMake Error at /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:97 (MESSAGE):
Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR
GTEST_MAIN_LIBRARY)
I am on Ubuntu using the ntox86-c++ compiler, googletest, and cmake-gui.
What gives?

Google test was probably not properly installed (libgtest-dev may install only source files that needed to be compiled). I had the same problem and I followed the instructions from http://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/
sudo apt-get install libgtest-dev
sudo apt-get install cmake # install cmake
cd /usr/src/gtest
sudo cmake CMakeLists.txt
sudo make
#copy or symlink libgtest.a and libgtest_main.a to your /usr/lib folder
sudo cp *.a /usr/lib
This worked for me.

As explained by #detrick, the Ubuntu package libgtest-dev only installs sources, so you need to build and install the libraries yourself.
However, there is a much simpler way for building and installing since Ubuntu 18.04 than the manual commands in other answers:
sudo apt install libgtest-dev build-essential cmake
cd /usr/src/googletest
sudo cmake .
sudo cmake --build . --target install

ntox86-c++ looks like a cross-compiler, libgtest-dev package does not provide compiled library for the target platform (QNX).
Since year 2014 compiled libraries was dropped from libgtest-dev and has been added again in Ubuntu-20.04 focal, so find_package(GTest REQUIRED) does not work on Ubuntu-16.04 xenial and Ubuntu-18.04 bionic. The reason is given in /usr/share/doc/googletest/README.Debian (/usr/share/doc/libgtest-dev/README.Debian) and in e.g. in /usr/src/googletest/googletest/docs/V1_7_FAQ.md "Why is it not recommended to install a pre-compiled copy of Google Test (for example, into /usr/local)" section. Difference in compiler flags for the library and for a test could generate incompatible executable code. The problem with 18.04 and 16.04 is the reason why I have decided to add another answer to the old question.
add_subdirectory could be used to compile gtest provided by system package
set(GTest_ROOT /usr/src/googletest/googletest)
add_subdirectory(${GTest_ROOT}
"${CMAKE_CURRENT_BINARY_DIR}/googletest" EXCLUDE_FROM_ALL)
add_executable(test test.cpp)
target_link_libraries(test gtest_main)
# or just gtest if main function is defined
Instead of using system package for googletest sources there are at least 2 variants how to obtain particular version from git (besides obvious submodule), see
https://cmake.org/cmake/help/latest/module/FetchContent.html
https://github.com/google/googletest/blob/master/googletest/README.md

Some time ago I created a dockerfile and it helps me to keep a kind of recipe for installing later on google test on my systems:
apt-get install -y git g++ make cmake
git clone https://github.com/google/googletest.git
cd googletest
mkdir gbuild && cd gbuild && cmake .. && make
cp -r googletest/include/gtest /usr/local/include
cp gbuild/googlemock/gtest/lib*.a /usr/local/lib
cp gbuild/googlemock/lib*.a /usr/local/lib
I hope it helps :)

Related

use mariadb-connector-cpp with cmake project

github repo. i am using c++20 with cmake on visual studio to program on wsl and getting error loading shared library. can't find file libmariadb.so.3.
I used the build instructions to build it for Debian & Ubuntu on wls and it was installed in these paths.
so in my cmake I included
find_package(mariadbcpp)
include_directories("/usr/local/include/mariadb")
link_directories("/usr/local/lib/mariadb")
target_link_libraries(${PROJECT_NAME} mariadbcpp)
when I run I get the following error
error while loading shared libraries: libmariadb.so.3: cannot open shared object file: No such file or directory
I tried running
sudo /sbin/ldconfig -v
and I also tried including this in my top level cmake
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
SET(CMAKE_INSTALL_RPATH "/usr/local/lib/mariadb")
to get it working you just need to add this to your cmake
include_directories("/usr/include/mariadb") #path to include folder
add_library(mariadbcpp STATIC IMPORTED)
set_property(TARGET mariadbcpp PROPERTY IMPORTED_LOCATION "/usr/lib/libmariadbcpp.so") #path to libmariadbcpp.so
then just include
#include <conncpp.hpp>
in source
to install I followed this Debian/Ubuntu and in step 10 the command to install libmariadbcpp.so.3 and lib/mariadb... should have been lib64/mariadb...
like so
sudo install lib64/mariadb/libmariadbcpp.so /usr/lib
sudo install lib64/mariadb/libmariadbcpp.so.3 /usr/lib
sudo install lib64/mariadb/plugin/* /usr/lib/mariadb/plugin

How set CMake to find a local package FFmpeg?

I am trying write CMakeLists with FFmpeg package, with compile on Windows and Linux.
First downloaded from FFmpeg-Builds shared releases
I imagine the structure of the project like this:
<project root>
deps/
ffmpeg/
win-x64/
incluve/
lib/
bin/
linux-x64/
incluve/
lib/
bin/
src/
CMakeLists.txt
How to help CMake find libraries: avcodec, avformat, avutil, etc?
Maybe in the folder lib/pkgconfig using PkgConfig it is possible to specify the path.
But I dont know how
The following worked well for me on Linux with cmake.
You will have to find the equivalents for Windows.
I used ffmpeg on Windows, but without cmake (i.e. directly in a Visual Studio project).
Install pkg-config, nasm:
sudo apt-get install -y pkg-config
sudo apt-get install nasm
Download ffmpeg source code:
https://ffmpeg.org/download.html
Build ffmpeg and install it:
tar -xvf <downloaded_filename>
cd /root/folder/with/ffmpeg/src
./configure
make
sudo make install
Add the following to your CMakeLists.txt:
In the beginning:
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
libavdevice
libavfilter
libavformat
libavcodec
libswresample
libswscale
libavutil
)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
In the linker area:
target_link_libraries(${PROJECT_NAME} PUBLIC PkgConfig::LIBAV)

What is a correct way to setup protobuf and grpc for cpp project?

I have a cpp project, and I want to build everything from source, to get latest things likned in. So under my project root I've created a 3rd_party folder and assemble following script:
sudo apt-get install autoconf automake libtool curl make g++ unzip -y
git clone https://github.com/google/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure
make
make check
sudo make install
sudo ldconfig
cd ..
echo installing grpc
git clone --recurse-submodules -b v1.43.0 https://github.com/grpc/grpc
export MY_INSTALL_DIR=$HOME/.local
be sure that its exists
cd grpc
mkdir -p cmake/build
pushd cmake/build
cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR ../..
make -j
make install
popd
i've encountered following flaws:
grpc v1.43.0 clones 3rd party submodule protoc v3.18, which after build has problems - protoc binary says "cpp plugin not found", when trying to generate
To overcome that I've copied sources obtained in the first part of script, to 3rd party subfolder of second part, to gurantee it to be 3.19 - then after compilation protoc working great, plugins are in place, and grpc is linked against latest version.
Very weird issue, needs understanding why it clones outdated version, and why 3.18 has no plugins under same build parameters as 3.19
in cmakelists find_package(Protobuf REQUIRED) fails at all
find_package( gRPC REQUIRED ) is not operating properly:
Found package configuration file:
[cmake]
[cmake] /home/a/.local/lib/cmake/grpc/gRPCConfig.cmake
[cmake]
[cmake] but it set gRPC_FOUND to FALSE so package "gRPC" is considered to be NOT
[cmake] FOUND. Reason given by package:
[cmake]
[cmake] The following imported targets are referenced, but are missing:
[cmake] protobuf::libprotobuf protobuf::libprotoc
Question
How can I write script, that in an empty folder will get me everything, related to grpc 3rd party libs and tools, that I need for project?
Here are the steps I took:
$ mkdir .local
$ export INSTALL_PREFIX="$PWD/.local"
$ export CMAKE_GENERATOR=Ninja # optional, but recommended
$ git clone --recurse-submodules -b v3.19.3 --depth 1 https://github.com/google/protobuf.git
$ pushd protobuf
$ ./autogen.sh
$ ./configure --prefix=$INSTALL_PREFIX
$ make -j$(nproc)
$ make install
$ popd
$ git clone --recurse-submodules -b v1.43.0 --depth 1 https://github.com/grpc/grpc.git
$ cmake -S grpc -B .build/grpc \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
-DCMAKE_PREFIX_PATH=$INSTALL_PREFIX \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DgRPC_PROTOBUF_PROVIDER=package \
-DABSL_PROPAGATE_CXX_STD=ON
$ cmake --build .build/grpc --target install
...
$ mkdir example
$ echo "int main () { return 0; }" > example/main.cpp
$ vim example/CMakeLists.txt
$ cat example/CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(example)
find_package(gRPC REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE gRPC::grpc++)
$ cmake -S example -B .build/example \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=$INSTALL_PREFIX
$ cmake --build .build/example
...
I build protobuf separately because gRPC doesn't set up its dependencies in CMake correctly when using its internal protobuf build (I tried both ways). This involves passing --prefix to protobuf's ./configure script and passing -DgRPC_PROTOBUF_PROVIDER=package to gRPC's CMake build. The latter is a gRPC-specific variable that tells it not to build protobuf, but to search for it instead. I tell gRPC where to find protobuf by setting CMAKE_PREFIX_PATH, which is a standard variable.

Need help completing command line installation of {fmt} on Windows 10

I'm a Linux user who's trying to set up a dev environment on Windows. I've cloned the fmt repo and built it the way I'm used to on Linux:
C:\Users\me\Development> git clone https://github.com/fmtlib/fmt.git
C:\Users\me\Development> cd fmt
C:\Users\me\Development> mkdir build
C:\Users\me\Development> cd build
C:\Users\me\Development> cmake ..
C:\Users\me\Development> cmake --build . --config Release
Now I want to install it so that I can include it in projects. Normally I would $ sudo make install but I'm not sure what to do on Windows and the fmt doc page has nothing for Windows installation.
When I did this same set of steps with FLTK there was a variable that I had to set to help me find things:
# CMakeLists.txt
set(FLTK_DIR "Path/to/installation")
find_package(FLTK REQUIRED NO_MODULE)
But it seems to be looking for the installation point, not the build dir. How can I get this to work?
You can run:
cmake --install . [--prefix <install-dir>]
The prefix is optional. On Windows, the default CMAKE_INSTALL_PREFIX is set to:
C:/Program Files (x86)/<project name>
Which in the case fmtlib would be:
C:/Program Files (x86)/FMT
Another option is to use vcpkg on Windows, which will install fmtlib locally in its own vcpkg install prefix. Then you can use it via:
find_package(fmt REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE fmt::fmt)
You just have to pass the vcpkg cmake toolchain file to your cmake invocation:
cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

How do you add libraries to CMakeLists?

After searching everywhere I could not find anything or anyone to help me figure out how to add GL GLEW and SDL2 Libraries to my CMakeLists.txt. I am using Ubuntu 14.04 LTS and I installed the following libraries with
sudo apt-get install libsdl2-dev #for SDL-2
sudo apt-get install libgl-dev #for GL
sudo apt-get install libglew-dev #for GLEW
This all worked great, and i was able to compile in g++ with this commmand
g++ ./main.cpp ./display.h ./display.cpp ./shader.cpp ./shader.h -l SDL2 -l GL -l GLEW
Now I need to switch to CMake Compiler and I have no clue how to add the libraries GL, GLEW, and SDL2 to the CMakeLists.txt.
The way to include the libraries depends on a few things. Some packages such as sdl2 have pkgconfig files that define the libraries and includes to use.
Cmake comes with a FindPkgConfig module that can get it for you.
For example:
include(FindPkgConfig)
pkg_check_modules(SDL2 REQUIRED sdl2)
target_link_libraries(executablename ${SDL2_LIBRARIES})
You can also manually add them with the target_link_libraries function.
Other packages have "Find" modules like GLEW: /usr/share/cmake-*/Modules/FindGLEW.cmake
CMake has lots of great docs in the man pages, and on their wiki as #Mikael Persson mentioned.