/usr/bin/ld: cannot find -lgmock on ubuntu while running gmock program - c++

I am trying to compile simple gmock example on my ubuntu vmware(16.04 LTS)
and getting below error while doing "make"
I have below files -
"test.h"
class CBasicMath
{
public:
CBasicMath(){}
virtual ~CBasicMath() {}
virtual int Addition(int x, int y);
virtual int Multiply(int x, int y);
virtual int Divide(int x, int y);
};
"test.cpp"
#include "test.h"
int CBasicMath::Addition(int x, int y)
{
return (x + y);
}
int CBasicMath::Multiply(int x, int y)
{
return (x * y);
}
int CBasicMath::Divide(int x, int y)
{
return (x / y);
}
"mocktest.h"
#include "gmock/gmock.h"
#include "test.cpp"
class MockBasicTest : public CBasicMath {
public:
MOCK_METHOD2(Addition, int(int x, int y));
MOCK_METHOD2(Multiply, int(int x, int y));
MOCK_METHOD2(Divide, int(int x, int y));
};
"main.cpp"
#include "mocktest.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
TEST(BasicMathTest, testAddition) {
MockBasicTest basictest;
EXPECT_CALL(basictest, Addition(2,3)).Times(0);
// EXPECT_EQ(0, basictest.Addition(2,3));
/*
.Times(5);
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
*/
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
"CMakeLists.txt"
cmake_minimum_required(VERSION 2.6)
# Locate GTest
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
# Link runTests with what we want to test and the GTest and pthread library
add_executable(runTests main.cpp)
target_link_libraries(runTests -lgtest -lgmock -lpthread)
These are the steps I followed for compilation -
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$ cmake CMakeLists.txt
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ajay/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$
and after that When I did make I am facing the issue
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$ make
Scanning dependencies of target runTests
make[2]: Warning: File 'main.cpp' has modification time 84978 s in the future
[ 50%] Building CXX object CMakeFiles/runTests.dir/main.cpp.o
[100%] Linking CXX executable runTests
/usr/bin/ld: cannot find -lgmock
collect2: error: ld returned 1 exit status
CMakeFiles/runTests.dir/build.make:94: recipe for target 'runTests' failed
make[2]: *** [runTests] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/runTests.dir/all' failed
make[1]: *** [CMakeFiles/runTests.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$
I don't know why this "/usr/bin/ld: cannot find -lgmock" issue is coming even though I have installed gmock successfully.
I am able to run gtest programs but when I am adding gmock I am getting this issue.
Please help me to resolve.
Let me know for more info.

Lookup the documentation for taget_link_libraries. Check the comments in FindGtest.cmake
You should not specify libraries them with -l instead use the variables from find_package e.g. ${GTEST_LIBRARIES}
You haven't done find_package for GMOCK so there are no variables defined for GMOCK. As this is not a standard CMake module, write your own or take one from the Internet
BUT, the Google test documentation recommends not use the installed libraries from the system, but to build them yourself inside your Project.There are several examples on the internet how to add gtest/gmock as ExternalProject to your cmake project.

Related

C++ uniform declaration is not working in class

I am trying to have a member array in a class with its length specified by the const static int variable for future needs.
My compiler throws an error with it, and I am not sure this is an error about a uniform initialization or array initialization, or both.
Here is the header file:
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length{2};
double array[array_length];
};
#endif
This is the source file.
#include "source.h"
Test::Test()
:array_length{0} //Typo of array{0}
{
}
These are the problem messages.
[enter image description here][1]
[1]: https://i.stack.imgur.com/IQ2Mk.png
This is the CMake file.
cmake_minimum_required(VERSION 3.0.0)
project(temp VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(temp main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Finally, these are what the compiler is complaining about when I try to build the project.
[main] Building folder: temp
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /Users/USERNAME/Desktop/temp/build --config Debug --target all -j 14 --
[build] [1/2 50% :: 0.066] Building CXX object CMakeFiles/temp.dir/main.cpp.o
[build] FAILED: CMakeFiles/temp.dir/main.cpp.o
[build] /usr/bin/clang++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -MD -MT CMakeFiles/temp.dir/main.cpp.o -MF CMakeFiles/temp.dir/main.cpp.o.d -o CMakeFiles/temp.dir/main.cpp.o -c ../main.cpp
[build] In file included from ../main.cpp:1:
[build] ../source.h:8:22: error: function definition does not declare parameters
[build] static const int array_length{2};
[build] ^
[build] ../source.h:9:18: error: use of undeclared identifier 'array_length'
[build] double array[array_length];
[build] ^
[build] 2 errors generated.
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
I am using macOS 12.0 beta, with VS Code 1.60.2, clang 13.0.0, CMake 3.20.2.
Please let me know if you see any wrong or have any suggestions.
This cannot work:
Test::Test()
:array_length{0}
You cannot set a const static data member in your constructor. A static value has the same value accross all object instances. But as it is also const no instance is allowed to change the value.
Since array_length is static const you have to initialize it like this:
source.h
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length = 2;
//static const int array_length{2}; this will also work just note that we cannot use constructor initializer list to initialize static data members
double array[array_length];
};
#endif
source.cpp
#include "source.h"
Test::Test()//we cannot use constructor initializer list to initialize array_length
{
}
Note that static const int array_length{2}; will also work but the thing is that in the constructor we cannot use constructor initializer list to initialize static data member.
EDIT:
If you decide to use static const int array_length{2}; then make sure that you have C++11(or later) enabled in your CMakeLists.txt. For this you can add
set (CMAKE_CXX_STANDARD 11)
to your CMakeLists.txt.
Alternatively, you could instead add
target_compile_features(targetname PUBLIC cxx_std_11)
in your CMakeLists.txt. In your case replace targetname with temp since that is the targetname that you have. Check this out for more how to active C++11 in CMake .

catch2 throws and error when adding a struct

This is the root of my project. I think I am missing a basic concept because the error occur when I wrap the the find() function in a struct.
CMakeLists.txt
bst.cpp
bst.hpp
bst-test.cpp
catch.hpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.16.4 FATAL_ERROR)
project(bst LANGUAGES CXX)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(bst bst.cpp)
add_executable(bst-test bst-test.cpp)
target_link_libraries(bst-test bst)
enable_testing()
add_test(
NAME catch_test
COMMAND $<TARGET_FILE:bst-test> --success
)
bst.cpp
struct Bst {
int find(int num, int array[]) { return -1; }
};
bst.hpp
struct Bst {
int find(int num, int array[]);
};
bst-test.cpp
#include "bst.hpp"
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
TEST_CASE("The number to search is not found in the list", "[notFound]") {
int array[]{};
Bst tree;
REQUIRE(tree.find(1, array) == -1);
}
This is the error when trying to compile.
CMakeFiles/bst-test.dir/bst-test.cpp.o: In function `____C_A_T_C_H____T_E_S_T____0()':
bst-test.cpp:(.text+0x2b0b5): undefined reference to `Bst::find(int, int*)'
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/bst-test.dir/build.make:84: recipe for target 'bst-test' failed
make[2]: *** [bst-test] Error 1
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/bst-test.dir/all' failed
make[1]: *** [CMakeFiles/bst-test.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2
you are declaring the Bst structure again in your .cpp file. The source file should only contain the definition of the methods, not the declaration of the structure.
Changing bst.cpp to the following fixes the error:
#include "bst.hpp"
int Bst::find(int num, int array[]) { return -1; }

How could I generate runnable shared library with cmake

I have seens some answers, but most of them does not work for me. So I would like to make everything clear by adding a new question, my CMakeLists.txt is like this:
cmake_minimum_required(VERSION 3.17)
project(example)
include_directories(./)
link_directories(./)
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Os -g ${CMAKE_CXX_FLAGS}")
message("CMAKE_COMPILER_IS_GNUCXX is True")
message("option is: ${CMAKE_CXX_FLAGS}")
endif (CMAKE_COMPILER_IS_GNUCXX)
add_executable(main try.cpp)
target_link_libraries(main fun)
set_property(TARGET main PROPERTY POSITION_INDEPENDENT_CODE 1 LINK_FLAGS -pie)
add_library(fun SHARED func.cpp)
# target_compile_options(fun PUBLIC "-pie")
target_link_libraries(fun PUBLIC "-pie")
set_property(TARGET fun PROPERTY POSITION_INDEPENDENT_CODE 1)
And the source code for try.cpp is:
#include<iostream>
#include "func.hpp"
int main() {
using namespace std;
cout << "hello from exe main" << endl;
func();
return 0;
}
The code for fun.cpp and fun.hpp is like this:
// func.hpp
void func();
// func.cpp
#include <iostream>
using std::cout;
using std::endl;
void func() {
cout << "hell from so func\n";
}
int main() {
cout << "hello from so main\n";
return 0;
}
My problem is that: I got the following link error when I compile it with cmake:
Scanning dependencies of target fun
[ 25%] Building CXX object CMakeFiles/fun.dir/func.cpp.o
[ 50%] Linking CXX shared library libfun.so
[ 50%] Built target fun
Scanning dependencies of target main
[ 75%] Building CXX object CMakeFiles/main.dir/try.cpp.o
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/try.cpp.o: in function `main':
/home/coin/learn-coding/projects/C/cmake/try.cpp:8: undefined reference to `func()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:105: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:125: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:104: all] Error 2
What is the problem with the configuration and how could I make it work ?
By the way, I tried to compile with command line:
g++ -fPIC -pie func.cpp -o libfun.so -shared
g++ try.cpp -o main -L. -lfun
Which does work when I run the generated main, but the generated so file cannot be runnable:
$ ./main
hello from exe main
hell from so func
$ ./libfun.so
Segmentation fault (core dumped)
What did I miss here ?
The following files based on this answer:
cat >CMakeLists.txt <<EOF
cmake_minimum_required(VERSION 3.17)
project(example)
if(CMAKE_COMPILER_IS_GNUCXX)
add_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-std=c++11>
-Wall
-Os
-g
)
endif()
add_executable(main try.cpp)
target_link_libraries(main PRIVATE fun)
add_library(fun SHARED func.cpp)
target_link_options(fun PRIVATE -Wl,-e,entry_point)
EOF
cat >func.cpp <<EOF
// func.hpp
void func();
// func.cpp
#include <iostream>
using std::cout;
using std::endl;
void func() {
cout << "hell from so func\n";
}
static inline
int lib_main() {
printf("hello from so main\n");
return 0;
}
extern "C" const char interp_section[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";
extern "C" void entry_point()
{
lib_main();
exit(0);
}
EOF
cat >try.cpp <<EOF
#include<iostream>
void func();
int main() {
using namespace std;
cout << "hello from exe main" << endl;
func();
return 0;
}
EOF
when compiled with the following on my 64-bit system with glibc, it generates two files that are executable:
$ cmake -S . -B _build && cmake --build _build -- VERBOSE=1
balbla compilation output
$ _build/main
hello from exe main
hell from so func
$ _build/libfun.so
hello from so main
I replaced std::cout with printf because I received a segmentation fault - I suspect global constructors are not beeing run and something in iostream destructors makes it go segfault.
I think adding LINK_FLAGS -pie) and target_link_libraries(fun PUBLIC "-pie") makes no point, it's handled with POSITION_INDEPENDENT_CODE property and I guess for shared library it's TRUE anyway (but I am not sure about that).

"clang: error: linker command failed with exit code 1" on "ld: symbol(s) not found for architecture x86_64"

Right, please bare with on this, it might be quite a long one, and one related issue was solved here (I think): CMake make[2]: *** No rule to make target `/path/to/uthash/utarray.h', needed by `HelloTest'. Stop.
I have been struggling for some days now to build a simple 'Hello World' programme which mixes C and C++, and pulls in various external libraries using CMake. For full disclosure it should be known that I am fairly new to C, C++ and CMake hence please be nice.
I am working in OS X Yosemite 10.10.4 (my googling seems to suggest this might be part of the problem). I am working out of the CLion IDE.
Alas, here we go, here is the programme I am trying to build:
#include <iostream>
#include "Simbody.h" \\Written in C++
extern "C"
{
#include "project_in_C.h"
}
using namespace std;
using namespace SimTK;
int main(int argc, char** argv) {
cout << "Hello, World!" << endl;
return 0;
}
We have a physics library written in C++ a bespoke project written in C, for which the main header file is, lets call it; project_in_C.h.
Again; all I am trying to do is build a simple mixed C/C++ project.
Now, the above is executed using CMake, and the following CMakeLists.txt file:
cmake_minimum_required(VERSION 3.2)
project(HelloTest)
# Simbody
find_package(Simbody REQUIRED)
include_directories(${Simbody_INCLUDE_DIR})
link_directories(${Simbody_LIB_DIR})
# Project C Headers
set(PROJC_ROOT_DIR "/Users/usr/project-c")
set(PROJC_INCLUDE_DIR ${PROJC_ROOT_DIR}/src
${PROJC_ROOT_DIR}/dir1
${PROJC_ROOT_DIR}/dir2)
include_directories(${PROJC_INCLUDE_DIR})
# Check that it has found the most important header
find_path(projFound project_in_C.h PATHS "/Users/usr/project-c/src")
if(NOT projFound)
message(FATAL_ERROR "Cannot find folder containing project_in_C.h")
endif()
# Project C Source [we want to avoid globbing]
set(PROJC_SOURCE ${PROJC_ROOT_DIR}/src/file1.c
${PROJC_ROOT_DIR}/src/file2.c
${PROJC_ROOT_DIR}/src/file3.c
${PROJC_ROOT_DIR}/src/file4.c
${PROJC_ROOT_DIR}/dir1/file5.c)
# Make library from source files
add_library(PROJC_LIBRARIES ${PROJC_SOURCE})
# Tie together
set(SOURCE_FILES main.cpp)
add_executable(HelloTest ${SOURCE_FILES})
target_link_libraries(HelloTest ${Simbody_LIBRARIES} ${PROJC_LIBRARIES})
So far so good, but here is where the truly mysterious problem arises. Upon build this is what I get in return:
/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/usr/Library/Caches/clion10/cmake/generated/c1d0f54d/c1d0f54d/Debug --target all -- -j 2
Scanning dependencies of target HelloTest
[ 91%] Built target PROJC_LIBRARIES
[100%] Building CXX object CMakeFiles/HelloTest.dir/main.cpp.o
Linking CXX executable HelloTest
Undefined symbols for architecture x86_64:
"_program_execution_wrapper", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [HelloTest] Error 1
make[1]: *** [CMakeFiles/HelloTest.dir/all] Error 2
make: *** [all] Error 2
But what the flippin' dynamite does that actually mean?
It is kicking up a fuss with project_in_C.h where the section the error seems to be referring to is written as so:
int program_execution_wrapper(int argc, char **argv);
int __program(int argc, char **argv);
#define main main(int argc, char **argv) { return program_execution_wrapper(argc, argv); } int __program
As ever, any help greatly appreciated.
Em...Undefined symbols is _program_execution_wrapper ... I don't see this symbol anywhere in you program. Is this maybe typo in your post? what if you change code in project_in_C.h from prog_exec_wrapper to program_execution_wrapper? And also, this function is not implemented in your code. For a start try something like this:
int program_execution_wrapper(int argc, char **argv) { printf("%s", "something"); }
Edit based on your comments:
See the following example:
We have two files (main.cpp)
#include <iostream>
int sum(int a, int b);
int main()
{
int a = sum(3, 5);
std::cout << a << std::endl;
return 0;
}
and file sum.cpp
#include <iostream>
int sum(int a, int b)
{
return a+b;
}
So I've I would like to compile this program...it would be like this
g++ main.cpp
I get the following error:
Undefined symbols for architecture x86_64:
"sum(int, int)", referenced from:
_main in main-22f955.o
ld: symbol(s) not found for architecture x86_64
But if I include sum.cpp in my main program, then program will work as charm.

xerces c++ and cmake

i tryng to build a small example of Xerces with xerces c++ 3.1 and cmake, but i and only getting linkings problems.
This is my cmkelists.txt:
//============================================================================
project(ConfiguradorXerces)
cmake_minimum_required(VERSION 2.8)
include_directories (/home/ricardo/Desktop/librerias/xerces/xerces-c-3.1.1/src)
link_directories (/home/ricardo/Desktop/librerias/xerces/xerces-c-3.1.1/src/.libs)
link_directories (/home/ricardo/Desktop/librerias/xerces/xerces-c-3.1.1/src/)
set ( XercesLib xerces-c )
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${XercesLib})
//==============================================
//===============================================
#include <iostream>
#include <xercesc/util/PlatformUtils.hpp>
using namespace xercesc;
using namespace std;
int main()
{
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
// Do your failure processing here
return 1;
}
// Do your actual work with Xerces-C++ here.
XMLPlatformUtils::Terminate();
// Other terminations and cleanup.
return 0;
}
//==============================================
and this is my console output:
CMakeFiles/ConfiguradorXerces.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x25): undefined reference to `xercesc_3_1::XMLUni::fgXercescDefaultLocale'
main.cpp:(.text+0x2a): undefined reference to `xercesc_3_1::XMLPlatformUtils::Initialize(char const*, char const*, xercesc_3_1::PanicHandler*, xercesc_3_1::MemoryManager*)'
main.cpp:(.text+0x2f): undefined reference to `xercesc_3_1::XMLPlatformUtils::Terminate()'
CMakeFiles/ConfiguradorXerces.dir/main.cpp.o:(.gcc_except_table+0x10): undefined reference to `typeinfo for xercesc_3_1::XMLException'
collect2: error: ld returned 1 exit status
make[2]: *** [ConfiguradorXerces] Error 1
make[1]: *** [CMakeFiles/ConfiguradorXerces.dir/all] Error 2
make: *** [all] Error 2
16:28:55: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project ConfiguradorXerces (target: Desktop)
When executing step 'Make'
//
i was thinking trhat my cmakeLsits.txt was not complete, there is an especial setup that it has to be done??
thx in advance
I am pretty sure that target_link_libraries() macro accepts a target as its first parameter:
target_link_libraries(<target> [item1 [item2 [...]]]
[[debug|optimized|general] <item>] ...)
And you have forgot to specify it. So instead of target_link_libraries(${XercesLib}), try target_link_libraries(${PROJECT_NAME} ${XercesLib}).
Hopefully, that solves it.