gtest installed with conan: undefined reference to `testing::internal::GetBoolAssertionFailureMessage` - c++

I use cmake to build my project and conan to install Google Test as dependency:
conanfile.txt
[requires]
gtest/1.7.0#lasote/stable
[generators]
cmake
[imports]
bin, *.dll -> ./build/bin
lib, *.dylib* -> ./build/bin
CMakeLists.txt
PROJECT(MyTestingExample)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
INCLUDE(conanbuildinfo.cmake)
CONAN_BASIC_SETUP()
ADD_EXECUTABLE(my_test test/my_test.cpp)
TARGET_LINK_LIBRARIES(my_test ${CONAN_LIBS})
test/my_test.cpp
#include <gtest/gtest.h>
#include <string>
TEST(MyTest, foobar) {
std::string foo("foobar");
std::string bar("foobar");
ASSERT_STREQ(foo.c_str(), bar.c_str()); // working
EXPECT_FALSE(false); // error
}
Build
$ conan install --build=missing
$ mkdir build && cd build
$ cmake .. && cmake --build .
I can use ASSERT_STREQ, but if I use EXPECT_FALSE I get an unexpected error:
my_test.cpp:(.text+0x1e1): undefined reference to `testing::internal::GetBoolAssertionFailureMessage[abi:cxx11](testing::AssertionResult const&, char const*, char const*, char const*)'
collect2: error: ld returned 1 exit status
What's wrong with my configuration?

The issue is that you are installing conan dependencies using the default settings (which is build type Release):
$ conan install --build=missing
# equivalent to
$ conan install -s build_type=Release ... --build=missing
The default settings can be seen in your conan.conf file
Then, you are using cmake in a nix system with the default build type which is Debug, which is a single-conf environment (opposed to multi-configuration Debug/Release environments, as Visual Studio), so when you are doing:
$ cmake .. && cmake --build .
# equivalent to
$ cmake .. -DCMAKE_BUILD_TYPE=Debug && cmake --build .
The incompatibility of Debug/Release build leads to that unresolved issue. So the solution would be to use the same build type that matches your installed dependencies:
$ cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build .
If using multi-configuration environments like Visual Studio, the correct way would be:
$ cmake .. && cmake --build . --config Release

On my side, I get this issue because being on Redhat 7 then with an old libstdc++.
Too old for conan default packages binaries/libraries.
I have fixed that by rebuilding gtest with '--build gtest' arg.

Related

Setting up stdlib path while compiling with mingw on linux

I am trying to build my c++ CMake project on linux with mingw. CMakeLists.txt consists of (for understanding):
Setting up project info:
project(<project name> LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Setting up TRY_COMPILE target type:
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
Setting up boost:
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost COMPONENTS system program_options REQUIRED)
Including subdirectories in which there is nothing about mingw:
add_subdirectory(<some_subdirectory>)
...
At the time of build process I see the following compilation command in the log:
/usr/bin/x86_64-w64-mingw32-g++ -I/usr/include -I<user include 1> -I<user include 2> -O3 -DNDEBUG -std=gnu++20 -MD -MT CMakeFiles/common.dir/<source>.cpp.o -MF <source>.cpp.o.d -o <source>.cpp.o -c <project path>/<source>.cpp
After that goes a compiler error message with the following beginning:
[build] In file included from /usr/x86_64-w64-mingw32/include/c++/12.2.0/cstdint:41,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/bits/char_traits.h:731,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ios:40,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ostream:38,
[build] from <project path>/<source>.hpp:5,
[build] from <project path>/<source>.cpp:1:
[build] /usr/include/stdint.h:90:33: error: conflicting declaration «typedef long unsigned int uintptr_t»
[build] 90 | typedef unsigned long int uintptr_t;
[build] | ^~~~~~~~~
...
According to the internet this error message is connected with the different mingw standard library implementation.
I guess in a compile command there should somehow be -I/usr/x86_64-w64-mingw32/include on a place of -I/usr/include in a compilation command. If I am right there, the question is "How to change standard include directory for mingw build spicifically?". If I am not right there, then how to solve the problem with project building?
PS: The project builds using both clang++ and g++.
You probably need a toolchain file for your cross-compiler.
But I'd suggest using quasi-msys2, which takes care of this, and also gives you access to prebuilt libraries for MinGW (Boost in your case).
Install dependencies (this assumes Ubuntu, for other distributions adjust as needed)
# Install Clang and LLD
bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
# Install other dependencies
sudo apt install make wget tar zstd gpg wine
Install and run quasi-msys2:
git clone https://github.com/holyblackcat/quasi-msys2
cd quasi-msys2/
make install _gcc _boost
env/shell.sh
cd ..
Now build your repo:
git clone https://github.com/gogagum/archiever
cd archiever/
git checkout dev
git submodule update --init --recursive
cmake -B build/
cmake --build build/ -j4
I tried running the test app too:
cd build/numerical/
./numerical_encoder.exe --input-file Makefile # This uses Wine automatically

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

libssh's functions couldn't be found on qt

I have cloned libssh library and built it with cmake. Building process was like this :
git clone https://git.libssh.org/projects/libssh.git/
mkdir build in libssh directory.
cd build
cmake -DUNIT_TESTING=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
after this line i got this error about cmocka:
Could NOT find CMocka (missing: CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
then : rm CMakeCache.txt
cmake ..
make
sudo make install
Now I want to use this library on qt but I have some issues there.
I got errors like :
error: undefined reference to `ssh_session_is_known_server'
I can't use any of function or structures on this library. My OS is ubuntu 18.04.

cmake and Visual Studio 15 2017 generator - defining a build type

I work on Windows 10. I use cmake with Visual Studio 15 2017 generator. CMakeLists.txt requires CMAKE_BUILD_TYPE to be defined because it is used by Conan command called from cmake (execute_process). Here is the cmake command:
cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 15 2017" ..
When I run build command this way:
cmake --build .
I get the following error:
error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MTd_StaticDebug' in Tests.obj
Conan installs a release library (MT_StaticRelease) but CMAKE_BUILD_TYPE is ignored during build. Building works when I use the following command:
cmake --build . --config Release
How does it work ? When I have to define --config buildType ? What with other generators, for example Ninja ?
Visual Studio is a multi-configuration system. It means that the build type is selected at build time, lets say when you are using the IDE, you can select at that time the Release or Debug configuration and build. So when you are generating the Visual Studio solution (project generation or configure step), with cmake -G "Visual Studio ...", CMake doesnt have a value for CMAKE_BUILD_TYPE.
So the CMake invocations need to be different depending on the system:
In multi-configuration environments like Visual Studio, you use just 1 build folder:
$ mkdir build && cd build # assume we are in the folder containing CMakeLists.txt
$ cmake .. -G "Visual Studio 15 2017 Win64" # Unless building for 32 bits, add the Win64
$ cmake --build . --config Release # Or open IDE, change config to Release and build
$ cmake --build . --config Debug
In single-configuration environments like gcc with Makefiles, you need to use 1 folder for every configuration
$ mkdir build_release && cd build_release # assume we are in the folder containing CMakeLists.txt
$ cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
$ cmake --build .
$ cd .. && mkdir build_debug && cd build_debug
$ cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
$ cmake --build .
A different issue is the definition of the MT (static) Visual Studio runtime. It is possible that you have defined in your Conan profile compiler.runtime=MT, or it is being set by your CMakeLists.txt directly. Conan doesn't install such static MT_StaticRelease library, it is part of Visual Studio. If you are trying to statically link the visual studio environment, your used profiles should look like:
# for debug
$ conan install .. -s build_type=Debug -s compiler.runtime=MTd
# for release
$ conan install .. -s build_type=Release -s compiler.runtime=MT

Testing with google and cmake [duplicate]

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 :)