How to link a .a file in C++ - c++

I'm trying to get the yaml-cpp parser working on my computer. I followed the instructions on the README, which generated the file libyaml-cpp.a with no errors or warnings. Then I copied that file into a directory, let's call it /path/to/files, where I also put b.yaml, and main.cpp, which contains the following text:
// main.cpp
int main(int argc, const char *argv[])
{
YAML::Node config = YAML::LoadFile("b.yaml");
return 0;
}
This comes from the first line of the yaml-cpp tutorial. I tried compiling this while linking to the yaml-cpp library in a few different ways, all of which lead to the same compile-time error: use of undeclared identifier 'YAML'. Here are some of the things I tried:
g++ main.cpp -lyaml-cpp -L/path/to/files
g++ main.cpp libyaml-cpp.a
g++ main.cpp libyaml-cpp.a -lyaml-cpp -L/path/to/files
and so on. How do I compile this correctly or more properly debug this process?
==EDIT==
Now my main.cpp file looks like this:
// main.cpp
#include <iostream>
#include "yaml.h"
int main(int argc, const char *argv[])
{
YAML::Node config = YAML::LoadFile("b.yaml");
return 0;
}
Here's my compile command and error message:
$ g++ main.cpp -lyaml-cpp -I/Users/benlindsay/scratch/yaml-cpp/include -L/Users/benlindsay/scratch/yaml-cpp/build
main.cpp:10:3: error: use of undeclared identifier 'YAML'
YAML::Node config = YAML::LoadFile("b.yaml");
^
main.cpp:10:23: error: use of undeclared identifier 'YAML'
YAML::Node config = YAML::LoadFile("b.yaml");
^
2 errors generated.
make: *** [a.out] Error 1
/Users/benlindsay/scratch/yaml-cpp/include contains a yaml-cpp directory, which in turn contains all the .h files including yaml.h. /Users/benlindsay/scratch/yaml-cpp/build contains the lyaml-cpp.a file.

Ok, I downloaded yaml-cpp and tried out, Here is a working version
#include <iostream>
#include "yaml-cpp/yaml.h" //You need to prepend the yaml-cpp
int main(int argc, const char *argv[])
{
YAML::Node config = YAML::LoadFile("b.yaml");
//return 0; In cpp, return 0 is not required on main, hence commented
}
The compile using g++ -std=c++11 main.cpp -lyaml-cpp -I/Users/benlindsay/scratch/yaml-cpp/include -L/Users/benlindsay/scratch/yaml-cpp/build

Related

extern main declaration from bsplib returns error

Im setting up the bsplib (https://github.com/Zefiros-Software/BSPLib) on a windows system (in VS Code) using WSL. When compiling I get the error message:
test.cpp:4:5: error: conflicting declaration of C function ‘int main()’
4 | int main()
| ^~~~
In file included from /mnt/d/study/software/bsp/include/bsp/bspExt.h:30,
from /mnt/d/study/software/bsp/include/bsp/bsp.h:34,
from test.cpp:2:
/mnt/d/study/software/bsp/include/bsp/bspClass.h:59:12: note: previous declaration ‘int main(int, char**)’
59 | extern int main(int argc, char **argv);
The program is used is just a bare example for BSP:
#include <iostream>
#include "bsp/bsp.h"
int main()
{
bsp_begin(bsp_nprocs());
int s = bsp_pid();
int p = bsp_nprocs();
printf("Hello World from processor %d / %d", s, p);
bsp_end();
return 0;
}
Compiled with:
g++ -I/mnt/d/study/software/bsp/include -g -lpthread -o main test.cpp
To my (quite limited) knowledge, the 'extern' in the header file should prevent the compiler from labelling the main as 'duplicate' of some sort. Im mostly interested in some of BSPs functionalities as part of a class of mine, that sadly does not include any support on the installation. What I've done so far:
Copied the include files from the repo
Added the include path to the compilation (-I Flag) and the -lpthread as instructed by the class script
Added the include path to the configuration (c_cpp_properties.json) [tested both with and without this, no difference]
Due to the many possible sources of that error (program, compiler, wsl, library, configuration, vs code, my stupidity) I cant determine where I am mistaken, nor am I able to find online resources to that combination.

How To Run Google test from terminal on C code?

I am testing C code using googleTest.
My test.cpp file look like that
#include <gtest/gtest.h>
extern "C" {
#include "list.h"
#include "list.c"
}
TEST(ListTest, singleInsertion) {
// some tests
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
However trying to run the test from the terminal using
g++ test.cpp -lgtest gives Errors and warning as if the code being tested is C++ not C.
Error and warning Examples :
error: invalid conversion for mallocs and
warning: ISO C++ forbids converting a string constant to ‘char*'
how can I declare that my tested files are C not C++ ?
However trying to run the test from the terminal using g++ test.cpp -lgtest gives Errors and warning as if the code being tested is C++ not C.
That's because you are compiling it as C++ by using the g++ compiler. Use gcc to compile as C.
Unfortunately, this code won't compile as C - it'll choke on the google::InitGoogleTest() call because C doesn't recognize the :: scoping operator. I'm not familiar with this testing framework, but at first glance it looks like it's meant to be used with C++, not C.
The way to fix this is to remove the #include "list.c" directive
extern "C" {
#include "list.h"
}
and compile it separately as C:
gcc -c list.c
then compile your tester:
g++ -c test.cpp
and then link the object files with the library:
g++ -o test test.o list.o -lgtest

libtorque - how do i include the PBSD_status function?

I am writing an application to test whether pbs_connect() is working or not. Here is my code:
#include <stdio.h>
#include "/usr/include/torque/pbs_ifl.h"
#include "/usr/include/torque/pbs_error.h"
#include <pbs_config.h>
#include "libpbs.h"
int main() {
printf("Hello world\n");
int server = pbs_connect("inferno.local");
//batch_status * stat1 = pbs_statserver(server, NULL, NULL);
pbs_errno = 0;
batch_status * stat1 = PBSD_status(server, 21, (char *)"", NULL, NULL);
printf("fd: %d\n", server);
//printf("text: %s\n", stat1->text);
//printf("name: %s\n", stat1->name);
printf("name: %d\n", pbs_errno);
return 0;
}
//compiled using - //g++ -o test test.c -L/usr/lib64 -ltorque
I get:
# g++ -o test test.c -L/usr/lib64 -ltorque
test.c:7:24: error: pbs_config.h: No such file or directory
test.c:8:20: error: libpbs.h: No such file or directory
test.c: In function 'int main()':
test.c:19: warning: deprecated conversion from string constant to 'char*'
test.c:24: error: 'PBSD_status' was not declared in this scope
The source file that contains PBSD_status can be found here:
https://github.com/adaptivecomputing/torque/blob/4.2.7/src/lib/Libifl/PBSD_status.c
Is there something i need to include in my g++ command to get this to work? I have checked in /usr/lib64/, and there is no libpbs.h or pbs_config.h. Where would they be, if they aren't there?
As far as your headers, you're running into the difference between installed and not installed headers. Essentially, a software project doesn't install every header inside that project, only relevant ones for the API. These other two aren't in the API and therefore aren't installed. You need to reference their path.
As far as including PBSD_status() in the library, you could edit the Makefile for Libpbs to include the source file for PBSD_status() and then rebuild, or you could link to the libifl library, which is in src/lib/Libifl from the base directory for the project.

C++ class method not found when compiled

I created a simple class 'Hello' in C++ using header(.h) and definition(.cpp) files. This is the header file content:
#ifndef HELLO_H
#define HELLO_H
#include <string>
namespace test
{
class Hello
{
private:
std::string name;
public:
Hello();
void say_hello();
};
}
#endif
And the definition file content is just as you expected:
#include "Hello.h"
#include <iostream.h>
using namespace test;
Hello::Hello()
{
this->name = "Yoppy Yunhasnawa";
}
void Hello::say_hello()
{
string message = "Hello, " + this->name + ".. Have nice day!";
cout << message << "\n";
}
I included this class to a main.cpp file and use it like this:
#include "Hello.h"
using namespace test;
int main(int argc, char *argv[])
{
Hello* hello = new Hello;
hello->say_hello();
}
When I compiled the main.cpp file with g++ like this,
g++ main.cpp
I got following annoying error:
Undefined symbols for architecture x86_64:
"test::Hello::say_hello()", referenced from:
_main in ccsaoOZa.o
"test::Hello::Hello()", referenced from:
_main in ccsaoOZa.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
However, that error does not appear when I don't call both constructor and say_hello method:
int main(int argc, char *argv[])
{
Hello* hello;// = new Hello;
//hello->say_hello();
}
I use macport GCC 4.7 and I am very sure that my method is there but why this symbol(s) not found error keep appearing? Please show me my mistake. Thank you.
When you invoke g++ main.cpp, compiler performs both compiling AND linking. But the code cannot be linked without Hello.cpp file. So, you have two options: either compile and link separately:
g++ -c main.cpp
g++ -c hello.cpp
gcc main.o hello.o
or compile and link everything at the same time:
g++ main.cpp hello.cpp

can i use CLucene and the Cue Sheet Parser together?

i'm trying to use clucene-0.9.21b and libcue-1.3.0 in Qt Creator on Kubuntu Lucid. this code is compilable:
project.pro
SOURCES += main.cpp
LIBS += -lcue
INCLUDEPATH += /usr/include/libcue-1.3/libcue
main.cpp
extern "C" {
#include <libcue.h>
}
int main(int argc, char *argv[]) {
return 0;
}
so is this:
project.pro
SOURCES += main.cpp
LIBS += -clucene
main.cpp
#include <CLucene.h>
int main(int argc, char *argv[]) {
return 0;
}
but not this one:
project.pro
SOURCES += main.cpp
LIBS += -lcue \
-clucene
INCLUDEPATH += /usr/include/libcue-1.3/libcue
main.cpp
extern "C" {
#include <libcue.h>
}
#include <CLucene.h>
int main(int argc, char *argv[]) {
return 0;
}
the latter generates the following errors:
Running build steps for project project...
Configuration unchanged, skipping QMake step.
Starting: /usr/bin/make -w
make: Entering directory `/home/user/project/project'
/usr/bin/qmake-qt4 -spec /usr/share/qt4/mkspecs/linux-g++ -unix CONFIG+=debug -o Makefile project.pro
make: Leaving directory `/home/user/project/project'
make: Entering directory `/home/user/project/project'
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I/usr/include/libcue-1.3/libcue -I. -o main.o main.cpp
In file included from /usr/include/sys/stat.h:107,
from /usr/include/CLucene/StdHeader.h:76,
from /usr/include/CLucene.h:11,
from main.cpp:5:
/usr/include/bits/stat.h:88: error: field ‘st_atim’ has incomplete type
/usr/include/bits/stat.h:89: error: field ‘st_mtim’ has incomplete type
/usr/include/bits/stat.h:90: error: field ‘st_ctim’ has incomplete type
/usr/include/bits/stat.h:149: error: field ‘st_atim’ has incomplete type
/usr/include/bits/stat.h:150: error: field ‘st_mtim’ has incomplete type
/usr/include/bits/stat.h:151: error: field ‘st_ctim’ has incomplete type
main.cpp:6: warning: unused parameter ‘argc’
main.cpp:6: warning: unused parameter ‘argv’
make: *** [main.o] Error 1
make: Leaving directory `/home/user/project/project'
Exited with code 2.
Error while building project project
When executing build step 'Make'
why is that and how to make it work?
Ok, this time I got a chance to actually try it. Problem seems to be that libcue has a file called time.h in its include folder. So if you compile with -I/usr/include/libcue-1.4/libcue then you end up with libcue's time.h instead of libc's.
This works for me:
extern "C" {
#include <libcue/libcue.h>
}
#include <CLucene.h>
int main(int argc, char *argv[]) {
return 0;
}
and obviously compiling with -I/usr/include/libcue-1.4/ instead of -I/usr/include/libcue-1.4/libcue
What happens if you swap the cue and clucene includes around? It could be a problem with include order and I suspect mixing c and c++ may make include order even more important