I have a C++ project based on CMake that uses Ninja. It's been build and ran using eclipse for C/C++. My current machine is a Mac OS.
The file:
#include <iostream>
#include <exception>
#include <string>
#include <stdexcept>
#include <vector>
#include <cmath>
using namespace std;
class Server {
private:
static int load;
public:
static int compute(long long A, long long B) {
load += 1;
if(A < 0) {
throw std::invalid_argument("A is negative");
}
vector<int> v(A, 0);
int real = -1, cmplx = sqrt(-1);
if(B == 0) throw 0;
real = (A/B)*real;
int ans = v.at(B);
return real + A - B*ans;
}
static int getLoad() {
return load;
}
};
int Server::load = 0;
int main() {
int T;
cin >> T;
while(T--) {
long long A, B;
cin >> A >> B;
/* Enter your code here. */
try{
cout << Server::compute(A, B) << endl;
} catch(invalid_argument e){
cout << "Exception: A is negative" << endl;
} catch(bad_alloc &e){
cout << "Not enough memory" << endl;
} catch(exception &e){
cout << "Exception: ";
cout << e.what() << endl;
} catch(...){
cout << "Other Exception" << endl;
}
}
cout << Server::getLoad() << endl;
return 0;
}
Build info:
cmake --build . -- -v
[1/2] /Library/Developer/CommandLineTools/usr/bin/c++ -O3 -DNDEBUG -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -MD -MT CMakeFiles/deleteme.dir/deleteme.cpp.o -MF CMakeFiles/deleteme.dir/deleteme.cpp.o.d -o CMakeFiles/deleteme.dir/deleteme.cpp.o -c ../../deleteme.cpp
[2/2] : && /Library/Developer/CommandLineTools/usr/bin/c++ -O3 -DNDEBUG -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/deleteme.dir/deleteme.cpp.o -o deleteme && :
Build complete (0 errors, 0 warnings):
When I run:
Building in:
cmake --build . -- -v
ninja: no work to do.
Build complete (0 errors, 0 warnings):
It does not give me the chance to input the values. It just skips everything and finishes execution. If I put a cout right at the beginning, then the program works as expected.
Why is this happening?
Ps: The project complete path was removed from here for safety reasons. And yes, my project was created with the name 'deleteme'.
Pss: I took this snippet from HackerRank for studing purposes, so It should be fine. I've only added the try/catch and method call.
You are confusing building your program with running your program.
When you run the command cmake --build . -- -v, cmake will build your project. That means it will launch the appropriate tools to compile and link your program, which will produce an executable called deleteme somewhere in your build directory.
The subsequent invocation of the same command correctly reports that no work needs to be done (since you presumably haven't modified any of the source code between invocations).
To be clear, normally this will not run your program, which is why you don't get a prompt to input any values.
To run your program, which, if I understand correctly is what you are trying to do, simply run the executable deleteme that was produced by the build process. You will most likely find this executable in the build directory, that is, the directory where you ran the cmake --build . command. (Depending on your CMake project structure, you may also find it in a subdirectory of your build directory.)
I've figured It out how to solve this. I don't know what have caused It. It looks like ninja is not need if you have properly configured your environment variables, related to your compiler, inside Eclipse.
After doing that, everything works fine.
Related
The question may seem weird.
I tried to use GCOV/LCOV for my small project and practiced with simple code before applying it. While practicing it, I encountered an error that I had no idea how to solve.
The report created by LCOV showed that the functions declared before the unused function inside the source code file are reported as unused functions. In contrast, the functions displayed correct outputs when the binary file was executed.
The followings are actual codes used for the practice.
# makefile
CC = g++
CFLAG = -g -fPIC -fprofile-arcs -ftest-coverage
RM = rm -rf
main.o : main.cpp
$(CC) $(CFLAG) -c -Wall -Werror main.cpp
dummy_class.o : dummy_class.cpp
$(CC) $(CFLAG) -c -Wall -Werror dummy_class.cpp
build : main.o dummy_class.o
$(CC) $(CFLAG) -o main main.o dummy_class.o
gcov: main.cpp dummy_class.cpp
gcov main.cpp dummy_class.cpp
coverage.info: gcov
lcov --capture --directory . --output-file coverage.info
lcov -remove coverage.info "/usr/include/*" "/usr/local/include/*" --output-file coverage.info
report : coverage.info
genhtml coverage.info --output-directory ./out
clean :
rm -f main
rm -f *.o *.so *.gcno *.gcda *.gcov coverage.info
rm -r out
do :
make build
./main
make report
// dummy_class.hpp
#pragma once
void func_even_case(void);
void func_odd_case(void);
void func_not_reachable(void);
void dummy(void);
void dummy2(void);
void dummy3(void);
// dummy_class.cpp
#include <iostream>
#include <vector>
#include "dummy_class.hpp"
void func_even_case(void)
{
std::cout << "This is even case" << std::endl;
}
void func_odd_case(void)
{
std::cout << "This is odd case" << std::endl;
}
void func_not_reachable(void)
{
std::cout << "This is not reachable" << std::endl;
}
void dummy(void)
{
std::cout << "This is dummy1." << std::endl;
}
void dummy2(void)
{
std::cout << "This is dummy2." << std::endl;
}
void dummy3(void)
{
std::cout << "This is dummy3." << std::endl;
}
// main.cpp
#include <iostream>
#include "dummy_class.hpp"
int main(void)
{
for (int i = 0; i < 10; ++i)
{
if (i % 2 == 0)
{
func_even_case();
}
else if (i % 2 != 0)
{
func_odd_case();
}
else
{
func_not_reachable();
}
}
func_not_reachable();
dummy();
dummy2();
dummy3();
return 0;
}
When func_not_reachable() is placed outside the for-loop, the report returns
Overall coverage rate:
lines......: 96.7% (29 of 30 lines)
functions..: 100.0% (7 of 7 functions)
and the result is expected.
When func_not_reachable() is removed, the expected result was
Overall coverage rate:
lines......: 86.5% (25 of 29 lines)
functions..: 100.0% (6 of 7 functions)
since func_not_reachable() is the one that will not be executed.
However, the actual result was
Overall coverage rate:
lines......: 65.5% (19 of 29 lines)
functions..: 57.1% (4 of 7 functions)
If the dummy_class.cpp is modified as following
#include <iostream>
#include <vector>
#include "dummy_class.hpp"
void func_even_case(void)
{
std::cout << "This is even case" << std::endl;
}
void func_odd_case(void)
{
std::cout << "This is odd case" << std::endl;
}
void dummy(void)
{
std::cout << "This is dummy1." << std::endl;
}
void dummy2(void)
{
std::cout << "This is dummy2." << std::endl;
}
void dummy3(void)
{
std::cout << "This is dummy3." << std::endl;
}
// unused function declared at the end of the source code.
void func_not_reachable(void)
{
std::cout << "This is not reachable" << std::endl;
}
The report result becomes follows.
Overall coverage rate:
lines......: 34.5% (10 of 29 lines)
functions..: 14.3% (1 of 7 functions)
I am sure I made errors while using GCOV and LCOV, but I cannot figure out where I made a mistake.
Can someone tell me where I made a mistake?
The above code was executed on the following.
Ubuntu 20.04.4 LTS
g++ (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
gcov (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
lcov: LCOV version 1.14
Find out the source of the problem.
The problem was related to the compiler (g++ 11.1.0) or gcov (9.3.0) I used.
The code coverage reported the correct result when the compiler changed from g++ to clang.
To ensure the problem is related to the specific version of the compiler (g++ 11.1.0), I upgraded the system from Ubuntu 20.04.4 LTS to Ubuntu 22.04.4 LTS.
The test condition became as follow
Ubuntu 22.04.4 LTS
g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0
gcov (Ubuntu 11.2.0-19ubuntu1) 11.2.0
After the update had been made, the code coverage reported the correct result with g++.
Hi I get a linking error when compiling my program with the gcc compiler on cygwin. The first picture is a simple sample program from the boost filesystem libraries tutorial page where I have included filesystem.hpp in the boost folder. Beneath that is the picture of my linker error when I try to compile with the following command:
g++ -I C:/Users/Ejer/Desktop/c++Dep/boost_1_77_0 -I C:/Users/Ejer/Desktop/c++Dep/eigen-3.4.0 -L C:/Users/Ejer/Desktop/c++Dep/boost_1_77_0/stage/lib test.cpp -o ser
Here I try to compile my program test.cpp with the eigen and boost libraries and set the includer path that they tell me to set as the path after I have built the library with b2.exe. I have also linked to the lib files for boost. I have also tried linking to the different filesystem lib files specifically. Thanks in advance
#include <iostream>
#include <boost/filesystem.hpp>
using std::cout;
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "Usage: tut3 path\n";
return 1;
}
path p (argv[1]);
try
{
if (exists(p))
{
if (is_regular_file(p))
cout << p << " size is " << file_size(p) << '\n';
else if (is_directory(p))
{
cout << p << " is a directory containing:\n";
for (directory_entry& x : directory_iterator(p))
cout << " " << x.path() << '\n';
}
else
cout << p << " exists, but is not a regular file or directory\n";
}
else
cout << p << " does not exist\n";
}
catch (const filesystem_error& ex)
{
cout << ex.what() << '\n';
}
return 0;
}
I get a linking error when compiling my program
No, you don't. You are getting a linking error when linking your program, not when compiling it.
The reason: you didn't supply the library (-L C:/Users/.... tells the linker where to search for libraries; not which libraries to link). Your command line should look something like:
g++ -I ... -L ... test1.cpp -o ser -lboost_filesystem
This code fails to compile with an error that it can't resolve stio. Have I made some newbie mistake here?
Eclipse Version: 3.8.1 Mint KDE should all be up to date.
GCC Version: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int main() {
string numberGuessed;
int intNumberGuessed = 0;
int answer = 0;
answer = (rand() % 100) + 1;
do {
cout << "Guess a number "; // prints !!!Hello World!!!
getline(cin, numberGuessed);
intNumberGuessed = stoi(numberGuessed);
cout << "You guessed "<< numberGuessed << endl;
cout << "You are not correct. Try again" << endl;
} while (answer != intNumberGuessed);
cout << "you got it";
return 0;
}
The error message.
16:39:14 **** Incremental Build of configuration Debug for project Hello2 ****
make all
Building file: ../src/Hello2.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Hello2.d" -
MT"src/Hello2.d" -o "src/Hello2.o" "../src/Hello2.cpp"
../src/Hello2.cpp: In function ‘int main()’:
../src/Hello2.cpp:27:40: error: ‘stoi’ was not declared in this scope
intNumberGuessed = stoi(numberGuessed);
^
make: *** [src/Hello2.o] Error 1
src/subdir.mk:18: recipe for target 'src/Hello2.o' failed
16:39:14 Build Finished (took 613ms)
The std::stoi function is available since the c++11 standard.
Apparently your compiler version of GCC is too old, to take c++11 as the current default standard.
You may try to specify the -std=c++11 or -std=c++0x compiler flags, or update your gcc compiler to one of the most recent versions.
Here's a link explaining in detail how to set the compiler flags.
This might help you with updating your compiler version to the latest.
I am trying same,
http://www.linuxforums.org/forum/suse-linux/135465-gcov-g.html
Code from the link,
#include <iostream>
using namespace std;
void one(void);
void two(void);
void __gcov_flush(void);
int main(void)
{
int i;
while(true)
{
__gcov_flush();
cout << "Enter a number(1-2), 0 to exit " << endl;
cin >> i;
if ( i == 1 )
one();
else if ( i == 2 )
two();
else if ( i == 0 )
break;
else
continue;
}
return 0;
}
void one(void)
{ cout << "One is called" << endl; }
void two(void)
{ cout << "Two is called" << endl; }
but for me also it gives,
test.cpp:(.text+0x1d9): undefined reference to `__gcov_flush()'
collect2: ld returned 1 exit status
Tried the followings,
g++ -fprofile-arcs test.cpp
g++ -fprofile-arcs -g test.cpp
g++ -fprofile-arcs -ftest-coverage -g test.cpp
g++ -fprofile-arcs -ftest-coverage -g test.cpp -lgcov
I have also tried the "-lgcov" & "extern void __gcov_flush(void)" as mentioned in link above. I am currently on Ubuntu12.04 and g++ 4.6
So, I want to know if there is solution for this or gcov_flush doesnt work anymore.
void __gcov_flush();
Since the code is compiled as C++, this declares the existence of a C++ function of that name. C++ functions are subject to name mangling, so the (C++) symbol is not found in the (C) link library, and the linker (rightfully) complains about it.
If you declare the function, declare it as a function with C linkage:
extern "C" void __gcov_flush();
This should do the trick.
Note the commend by Paweł Bylica -- __gcov_flush() has been removed in GCC 11, you should use __gcov_dump().
I fixed this issue changing the settings.
Test Project --> Build Settings
Instrument Program Flow = Yes
I am trying to figure out how to use the upcoming C++ release 0x. It should be available in GCC 4.3+ with using the gcc std=gnu++0x option.
My simple thread program using 0x compiles in Eclipse CDT with std=gnu++0x added in Project > properties > C/C++ Build > Settings > Miscellaneous > Other flags.
#include <iostream>
#include <thread>
using namespace std;
void hello()
{
cout << "Hello Concurrent World!" << endl;
}
int main()
{
cout << "starting" << endl;
thread t(hello);
t.join();
cout << "ending" << endl;
return 0;
}
The program only prints "starting" and returns 0. Does anyone know why it does not run the hello function threaded?
To use threads you also need to link against the threading library.
In case you haven't done that add -lpthread to your command line or in your case to other flags field.
The command line execute (visible in your console window in eclipse) should look like this:
gcc -std=gnu++0x -lpthread <source_file_name>.cc