I have a C library made by cluster.h and cluster.c. I compiled that with gcc -c cluster.c.
I have to use a method of this library in the main class of a C++ project. This is the makefile i use:
abundancebin: main.o profileManager.o myHash.o myMalloc.o myStack.o myStringHash.o
g++ -o abundancebin main.o profileManager.o myHash.o myMalloc.o myStack.o myStringHash.o
main.o: main.cpp
g++ -c main.cpp
profileManager.o: profileManager.cpp
g++ -c profileManager.cpp
myHash.o: myHash.cpp
g++ -c myHash.cpp
myMalloc.o: myMalloc.cpp
g++ -c myMalloc.cpp
myStack.o: myStack.cpp
g++ -c myStack.cpp
myStringHash.o: myStringHash.cpp
g++ -c myStringHash.cpp
clean:
-rm *.o abundancebin
I tried to import the C library in main.cpp using after other imports:
#ifdef __cplusplus
extern "C" {
#endif
#include <cluster.h>
#ifdef __cplusplus
}
#endif
but when i compile with make i have this response:
main.cpp:29:21: fatal error: cluster.h: No such file or directory
#include <cluster.h>
^
compilation terminated.
make: *** [main.o] Error 1
if i use "cluster.h" instead of i have this error:
main.o:main.cpp:(.text+0xf68): riferimento non definito a "kmedoids"
main.o:main.cpp:(.text+0xf68): rilocazione adattata per troncamento: R_X86_64_PC32 contro il simbolo non definito "kmedoids"
/usr/bin/ld: main.o: bad reloc address 0x18 in section.xdata'
collect2: error: ld returned 1 exit status
make: * [abundancebin] Error 1`
I also tried to copy the code part i need from C library to C++ project but the compiler reports many errors like this:
error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]
vector = malloc(nnodes*sizeof(int));
The library files are in the same folder of the project files. Can someone help?
Thank you
If you want to add some code which is wrote in c language, you have to #include it like:
extern "C" {
#include "x264.h"
}
which tell compiler to deal with it differently, and its not necessary to change your code to c++
1: you add your code as: #include <cluster.h>
its better to change it to: #include "cluster.h"
the different is, the second one tell the compiler to first search for your header in the current directory and then in the main c++ libraries directory
your error:
main.cpp:29:21: fatal error: cluster.h: No such file or directory
is because it can't find the header, so, if cluster.h is in the same directory as main.cpp, use #include "cluster.h"
or you can use -I. (which tell its in the current directory) or -I/address to tell compiler where to look for your header
when you correct it, you get the second error, which I believe its because of your code, and I think its because of your code in main.cpp, and do not have anything with your cluster code, I suggest, try to post your code to find out what's the problem
In answer to your question, I would approach it something like this in the makefile:
all: cfile.o
g++ main.cpp -o app
cfile.o: cluster.c cluster.h
gcc -c cluster.c
Note: This assumes that everything is in the same directory, so take care to specify paths if not.
Let me know of any further errors.
Related
I'd like to learn how to use lapack together with C/C++ code in Windows. I am a C/C++ programming newbie, so I know how to code in C, how to organize the code in h/c files, and how to compile them with gcc under cygwin / MinWG / VS. What I'm totally new to is the use of external libraries, such as lapack.
To learn how to use it with Cygwin (64bit), I followed the procedure indicated here
(http://matrixprogramming.rudnyi.ru/2011/04/using-lapack-from-c/)
which seemed to be successful and created the built version of lapack in the folder $HOME\lapack-3.3.0
Now I want to re-run this example: main.cc
What I did was to try to compile it by calling
$ g++ -O3 main.cc -L$HOME/lapack-3.3.0 -llapack -lblas -lgfortran -I ./include -o main
and what I get is
main.cc: In function ‘int main(int, char**)’:
main.cc:39:23: error: ‘dgetf2’ was not declared in this scope
info = dgetf2(A, ipvt);
^
main.cc:45:23: error: ‘dgetrf’ was not declared in this scope
info = dgetrf(A, ipvt);
^
main.cc:55:26: error: ‘dgetrs’ was not declared in this scope
info = dgetrs(A, B, ipvt);
^
where the "include" folder only contains the
Matrix.h
matrix class required in main.cc
To me it seems that some header files are missing. What I do not understand is how this is possible if the building process of the libraries was successful. Do I have to give further "-I options"? I looked for "dgetf2", "dgetrf" and "dgetrs" in the lapack-3.3.0 folder, so I found the object files in $HOME\lapack-3.3.0\SRC but if I include them as well as
$ g++ -O3 main.cc -L$HOME/lapack-3.3.0 -llapack -lblas -lgfortran -I ./include -I $HOME/lapack-3.3.0/SRC -o main
I get exactly the same error which makes somehow sense as they are object files and not header files. What am I doing wrong? How does one manage declarations of functions implemented in external libraries?
Thanks!
I have a strange problem when compiling a C++ code using a makefile. The code first compiles perfectly. Then I change one function argument to "const". If I then compile, I will receive the error message when the code tries to use the function in which I changed the argument to const. This can be resolved by removing all .o files and then compiling again, but I am curious as to what causes this issue in the first place. My files are:
MyClass.h
class MyClass {
public:
void fun(double*const c);
};
MyClass.cpp
#include "MyClass.h"
void MyClass::fun(double *const c){
};
Main.cpp
#include "MyClass.h"
int main(int argc,char* argv[]) {
MyClass foo;
double *bar=new double[2];
foo.fun(bar);
};
Makefile
all: main
main: Main.o MyClass.o
g++ -o a.out Main.o MyClass.o
Main.o: Main.cpp
g++ -c Main.cpp
MyClass.o: MyClass.cpp
g++ -c MyClass.cpp
If I now first run make, everything works. But then I change the signature of fun to fun(const double *const c), I receive the error message
Main.cpp:(.text+0x3b): undefined reference to `MyClass::fun(double*)'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'main' failed
make: *** [main] Error 1
However, if I remove all the .o files and then run make again, it compiles.
The rule
main.o: Main.cpp
says thay the main.o object file only depend on the Main.cpp source file. But it actually depends on another file: The MyClass.h header file.
There's also an error in the capitalization of the name of the target.
The above two problems means that when you change the header file MyClass.h to update the function signature, the Main.o object file will not be recreated and still reference the old function.
So the rule should be
Main.o: Main.cpp MyClass.h
That addition will cause the Main.o object file to be recompiled when you change the header file.
This change should also be done for the MyClass.o target.
Also note that the main target uses MyClass.o as a dependency, but then you use the MyClass.cpp source file when linking, instead of the object file.
The name of the target should also be the name of the generated file (i.e. a.out in your case).
The problem is, that your Makefile is broken: It ignores the fact that a .o file does not only depend on the corresponding .cpp file, but also on the .h files it includes. A correct Makefile rule must include all dependencies, including the directly, or even indirectly included .h files.
Since you Makefile is incomplete, make did not recompile the calling site of your function when its definition changed, so the stale object still references the non-const function. Due to C++ name-mangling, the linker caught it in the act, the error would have gone unnoticed in C!
To fix this situation for good, I recommend spending an hour or two reading this article on automatic dependency generation, and implementing some of the solutions it offers into your Makefile. Once you have done this, you will likely just copy-cat your existing solution into the Makefiles of future projects, and otherwise forget about the problem.
I trying to compile a .cpp program from Debian 6. I have a working makefile, which only works with .c archives, but I need to compile my program on .cpp. So here its the makefile:
#
# Build the examples.
#
# The great thing about GNU Make is that it knows so much about your lifestyle, you don't need to
# tell it the obvious things. This file is a minimal makefile.
# You run this makefile by typing `make' in the directory with the makefile
# You can find out more about make by typing `info make'.
# This tells Make that we need to link everything with the robot code:
LDLIBS=/usr/lib/robot.a
CC=gcc
# This variable has a handy copy of all the things we aim to produce
EXEC= read_sensor turn_on_and_off control_joint cerrar_mano
# Thses are all the things we need to compile:
all: ${EXEC}
CFLAGS=-I/usr/realtime/include/ -D_ISOC99_SOURCE -D_GNU_SOURCE - rtai_types -rtai_lxrt
# Make now looks around the directory, finds the read_sensor.c and
# turn_on_and_off.c files, works out it can compile them into the
# read_sensor and turn_on_and_off executables, and does so!
# However, for the kernel modules, we need to do a bit more.
rt_control: rt_control.o
ld -E -O2 -r -o $# $^
# This is an example of making a binary from several object files, as an example only!
fred: bert.o jim.o
ld -E -O2 -o $# $^
# We need to tell the compiler quite a lot about where to find the right header files
rt_control.o: control.c
$(CC) -c -O2 -DREALTIME -DRTAI_3 -I./include/ -I. -I../ -isystem /usr/realtime/include/ -isystem /usr/src/linux/include -o $# $^
# We put some housekeeping in here:
# This target is used to remove intermediate files Make produces.
clean:; rm -f *.o
# This target is used to remove output files Make produces as well.
realclean: clean
rm -f ${EXEC}
So when I write on terminal make myprogramname.cpp This is what i get:
In file included from /usr/include/robot/robot.h:38,
from Programa_Hand2.cpp:4:
/usr/include/robot/sensor.h:24:44: error: rtai_types.h: No such file or directory
/usr/include/robot/sensor.h:38:23: error: rtai_lxrt.h: No such file or directory
In file included from /usr/include/robot/robot.h:38,
from Programa_Hand2.cpp:4:
/usr/include/robot/sensor.h:168: error: 'RTIME' does not name a type
In file included from /usr/include/robot/robot.h:38,
from Programa_Hand2.cpp:4:
/usr/include/robot/sensor.h:178: error: 'RTIME' does not name a type
In file included from Programa_Hand2.cpp:4:
/usr/include/robot/robot.h:194: error: 'RTIME' does not name a type
/usr/include/robot/robot.h:244: error: 'RTIME' does not name a type
Programa_Hand2.cpp: In function 'int main()':
Programa_Hand2.cpp:18: error: expected initializer before 'printf'
Programa_Hand2.cpp:19: error: 'f' was not declared in this scope
hand#hand-cartagena:~/Desktop/Joaquin/examples$ make Programa_Hand2
g++ Programa_Hand2.cpp /usr/lib/robot.a -o Programa_Hand2
In file included from /usr/include/robot/robot.h:38,
from Programa_Hand2.cpp:4:
/usr/include/robot/sensor.h:24:44: error: rtai_types.h: No such file or directory
/usr/include/robot/sensor.h:38:23: error: rtai_lxrt.h: No such file or directory
In file included from /usr/include/robot/robot.h:38,
from Programa_Hand2.cpp:4:
/usr/include/robot/sensor.h:168: error: 'RTIME' does not name a type
In file included from /usr/include/robot/robot.h:38,
from Programa_Hand2.cpp:4:
/usr/include/robot/sensor.h:178: error: 'RTIME' does not name a type
In file included from Programa_Hand2.cpp:4:
/usr/include/robot/robot.h:194: error: 'RTIME' does not name a type
/usr/include/robot/robot.h:244: error: 'RTIME' does not name a type
Programa_Hand2.cpp: In function 'int main()':
Programa_Hand2.cpp:18: error: expected initializer before 'printf'
Programa_Hand2.cpp:19: error: 'f' was not declared in this scope
make: *** [Programa_Hand2] Error 1
Also tried with gcc -o Programa_Hand2 Programa_Hand2.cpp and getting the same error, I think its something I have to change with the makefile but dont know what its wrong there
Any ideas? Im new to programming and linux, so Im getting a bit mad with this, because I need the program to be compiled on c++, and I compiled it and works properly on c. Thanks for your help!
Edit: doing some research from the internet, seems to be that RTAI doesnt support C++; so there is any way to compile it in C++? Also, my #includes are:
#include <stdio.h>
#include <robot/robot.h>
#include <unistd.h>
#include <error.h>
#include <iostream>
#include "RobotConfig.h"
Thanks again!
In short you need to use the command g++ not gcc for C++ files.
You need to compile C++ files with a C++ compiler not a C compiler and there are differences.
The command for GNU C++ Compiler is g++ assuming you have it installed. That is likely since you seem to have a C compiler.
Add a variable to your Makefile named CXX and set it equal to g++. Then compile your C++ code using the CXX variable as the command instead of the CC variable.
$(CXX) -o <.output file name> <.cpp files go here>
I'm currently trying to simply link a file called main.cpp with boost in order to do asio(asynchronous input and output). I'm using a makefile in order to compile the C++ code into executable form. However, despite using the -I modifier on my terminal command in Mac OS X, it still cannot find the appropriate directory to search in. Here is my code in Main
#include <asio.hpp>
int main(){
return 1;
}
and here is the makefile command that I am using
all:
g++ -Iboost_1_60_0/boost/ -o main main.cpp
In my file structure, boost_1_60_0, main.cpp, and makefile are all on the top level, where asio is in the folder boost which is in the folder boost_1_60_0. I'm very confused about this and any help would be appreciated! Thanks!
EDIT: Full error is
1 error generated.
make: *** [all] Error 1
iMats-2:SerialC++ wfehrnstrom$ make
g++ -Iboost_1_60_0 -o main main.cpp
main.cpp:2:10: fatal error: 'asio.hpp' file not found
You should use -Iboost_1_60_0 (or, better still, install Boost properly so that it's found automatically under /usr/include/), and write #include <boost/asio.hpp>.
The include directives inside Boost itself will assume this form, so…
BTW, this has nothing to do with exceptions. Presumably it's a compiler error you've seen.
The Background
I have the following source code
#include <libubuntuone-1.0/u1-music-store.h>
#include <libsyncdaemon-1.0/libsyncdaemon/libsyncdaemon.h>
static void
get_credentials (U1MusicStore *music_store,
gchar **oauth_consumer_token,
gchar **oauth_consumer_secret,
gchar **oauth_token,
gchar **oauth_token_secret)
{
SyncdaemonCredentials *credentials;
*oauth_consumer_token = *oauth_consumer_secret = *oauth_token = *oauth_token_secret = NULL;
*oauth_consumer_token = g_strdup (syncdaemon_credentials_get_consumer_key (credentials));
*oauth_consumer_secret = g_strdup (syncdaemon_credentials_get_consumer_secret (credentials));
*oauth_token = g_strdup (syncdaemon_credentials_get_token (credentials));
*oauth_consumer_secret = g_strdup (syncdaemon_credentials_get_token_secret (credentials));
}
int main()
{
return 0;
}
and I am compiling it with the following makefile
main: main.o
g++ main.o -o main
main.o: main.cpp
g++ -c main.cpp `pkg-config --cflags --libs gtk+-2.0`
I need to include the pkg-config option since the u1-music-store.h header tried to included gtk/gtk.h, but the compiler isn't able to find it on it's own.
libsyncdaemon.h is a meta-header whose only purpose is to include a larger list of headers, which can be seen below
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-authentication.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-config-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-credentials.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-daemon.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-events-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-file-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-filesystem-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-folder-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-folders-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-publicfiles-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-share-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-status-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-status-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-transfer-info.h>
My problem
Whenever I try to compile my code, I get the following error:
main.o: In function `get_credentials(_U1MusicStore*, char**, char**, char**, char**)':
main.cpp:(.text+0x34): undefined reference to `syncdaemon_credentials_get_consumer_key'
main.cpp:(.text+0x3c): undefined reference to `g_strdup'
main.cpp:(.text+0x4e): undefined reference to `syncdaemon_credentials_get_consumer_secret'
main.cpp:(.text+0x56): undefined reference to `g_strdup'
main.cpp:(.text+0x68): undefined reference to `syncdaemon_credentials_get_token'
main.cpp:(.text+0x70): undefined reference to `g_strdup'
main.cpp:(.text+0x82): undefined reference to `syncdaemon_credentials_get_token_secret'
main.cpp:(.text+0x8a): undefined reference to `g_strdup'
collect2: ld returned 1 exit status
make: *** [main] Error
Using grep, I've tracked down the four syncdaemon_credentials_get_* functions to syncdaemon-credentials.h, which I would expect the compiler to be able to find since it's listed in libsyncdaemon.h, but for some reason that's not happening. I'm assuming it's for the reason that u1-music-store.h was unable to find gtk/gtk.h that compelled me to use the pkg-config option in my makefile, but I'm having trouble understanding why this is even the case to begin with. If the file's #included, I would expect it to be included by the compiler.
Using grep again I was able to track down g_strdup to a number of headers, but I also discovered that when I replaced by makefile with the single command
g++ main.cpp -o main `pkg-config --cflags --libs gtk+-2.0`
I can eliminate the g_strdup warning, and I'm just left with the function errors.
My question
There are two things I'm looking to know here:
What should my makefile look like in order to solve my specific problem
What is the general solution to my problem? I'm guessing it's something to do with daisy-chaining #include directives together, and having to use pkg-config to fix that, but I'm not sure.
You need to link against libsyncdaemon.so. Get the appropriate arguments from pkg-config ... libsyncdaemon-1.0.
You need to link against libraries that export the required symbols. If there is a .pc file then you can use it to get the appropriate arguments.
"Unresolved external symbol" (MSVC) and "undefined reference to" (GCC) mean that the compiler found the declarations but the linker couldn't find the definitions.
This either means that you forgot to compile and/or link against a .cpp or that you forgot to link against an external library (.lib (Windows) / .a (Unix/Linux)) or object file (.o) which contains said definitions.