I'm getting an undefined referenced error, not knowing the reason why.
So I have 2 files which makes a static lib : keyboard_input.c, keyboard_input.h
Here's the content of the .h file:
#ifndef __MOD_KBINPUT__
#define __MOD_KBINPUT__
int kbInit();
int kbWait();
int kbTest();
#endif
And the CMakeLists.txt file looks like this:
FILE(
GLOB_RECURSE
sources
*.c
)
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include/utils/kbreader")
ADD_LIBRARY(keyboardReader ${sources})
Compiling this lib gives some warnings:
src/utils/kbreader/keyboard_input.c: In function ‘kbInit’:
src/utils/kbreader/keyboard_input.c:13:14: warning: assignment from incompatible pointer type [enabled by default]
src/utils/kbreader/keyboard_input.c: In function ‘kbWait’:
src/utils/kbreader/keyboard_input.c:21:55: warning: passing argument 4 of ‘fread’ from incompatible pointer type [enabled by default]
/usr/include/stdio.h:708:15: note: expected ‘struct FILE * __restrict__’ but argument is of type ‘struct FILE *’
Now, for my main executable (main.cpp):
#include <keyboard_input.h>
int main()
{
kbTest();
return 0;
}
Processed by the following CMakeLists.txt file:
include_directories("${PROJECT_SOURCE_DIR}/include/utils/kbreader")
file(
GLOB_RECURSE
srcs
*.cpp
)
add_executable(
PEM
${srcs}
)
target_link_libraries(PEM keyboardReader)
Ends up getting that error:
CMakeFiles/PEM.dir/main.cpp.o: In function `main':
main.cpp:(.text+0xb): undefined reference to `kbTest()'
collect2: ld returned 1 exit status
make[2]: *** [src/PEM/main2/PEM] Error 1
make[1]: *** [src/PEM/main2/CMakeFiles/PEM.dir/all] Error 2
The libkeyboardReader.a is created, and the kbTest() function doesn't do anything except
{return 0; }
If I set the definition of kbTest() in the header file, it works.
But there's something i don't get, when i type: make keyboardReader here is the output:
[ 73%] Building C object src/utils/kbreader/CMakeFiles/KeyboardReader.dir/keyboard_input.c.o
[Warning explained above]
Linking C static library ../../../lib/libKeyboardReader.a
Is there something wrong? Does the note error message makes my lib omit the keyboard_input.c file?
You're mixing C and C++ files. To make that work, you just have to tell the C++ compiler that it's calling a C function, by changing the header file like so:
#ifndef MOD_KBINPUT
#define MOD_KBINPUT
/* note I also fixed the macro so you aren't using a system-reserved name */
#if __cplusplus
/* this is the important part */
extern "C" {
#endif
int kbInit();
int kbWait();
int kbTest();
#if __cplusplus
}
#endif
#endif
Otherwise the C++ compiler assumes the function will be given a C++ internal name (which encodes all the type information in the signature, this is what lets the linker distinguish between overloaded functions) and then the linker doesn't find it.
Related
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.
I am trying to compile a c++ project in Eclipse CDT with third party C project (minimodem https://github.com/kamalmostafa/minimodem), Currently my project simply contains a few cpp files and folder inside the source folder with C files. I have included c headers the main.cpp c files using
extern "C"
{
#include "minimodem/simpleaudio.h"
#include "minimodem/fsk.h"
#include "minimodem/databits.h"
}
the code compiles but breaks at linking with below error
**** Build of configuration Debug for project Sample_Test ****
make all
Building target: Sample_Test
Invoking: GCC C++ Linker
g++ -L/usr/include -o "Sample_Test" ./minimodem/baudot.o ./minimodem/databits_ascii.o ./minimodem/databits_baudot.o ./minimodem/databits_binary.o ./minimodem/databits_callerid.o ./minimodem/databits_uic.o ./minimodem/fsk.o ./minimodem/simple-tone-generator.o ./minimodem/simpleaudio-alsa.o ./minimodem/simpleaudio-benchmark.o ./minimodem/simpleaudio-pulse.o ./minimodem/simpleaudio-sndfile.o ./minimodem/simpleaudio.o ./minimodem/uic_codes.o ./aes256.o ./main.o -lfftw3f -lasound -lpulse-simple -lpulse -lsndfile
./minimodem/simpleaudio.o: In function `simpleaudio_open_stream':
/home/user1/workspace/Sample_Test/Debug/../minimodem/simpleaudio.c:88: undefined reference to `simpleaudio_backend_pulseaudio'
makefile:45: recipe for target 'Sample_Test' failed
/home/user1/workspace/Sample_Test/Debug/../minimodem/simpleaudio.c:99: undefined reference to `simpleaudio_backend_alsa'
/home/user1/workspace/Sample_Test/Debug/../minimodem/simpleaudio.c:105: undefined reference to `simpleaudio_backend_pulseaudio'
collect2: error: ld returned 1 exit status
make: *** [Sample_Test] Error 1
**** Build Finished ****
inside simpleaudio.c the function simpleaudio_open_stream (third party C code)
..
#include "simpleaudio.h"
#include "simpleaudio_internal.h"
..
simpleaudio_open_stream(
...
simpleaudio *sa = calloc(1, sizeof(simpleaudio));
...
#if USE_PULSEAUDIO
sa->backend = &simpleaudio_backend_pulseaudio;
#elif USE_ALSA
..
#if USE_ALSA
case SA_BACKEND_ALSA:
sa->backend = &simpleaudio_backend_alsa;
break;
#endif
#if USE_PULSEAUDIO
case SA_BACKEND_PULSEAUDIO:
sa->backend = &simpleaudio_backend_pulseaudio;
break;
#endif
...
)
the structs linker is unable to find reside in simpleaudio_internal.h
extern const struct simpleaudio_backend simpleaudio_backend_benchmark;
extern const struct simpleaudio_backend simpleaudio_backend_sndfile;
extern const struct simpleaudio_backend simpleaudio_backend_alsa;
extern const struct simpleaudio_backend simpleaudio_backend_pulseaudio;
I'm getting an undefined referenced error, not knowing the reason why.
So I have 2 files which makes a static lib : keyboard_input.c, keyboard_input.h
Here's the content of the .h file:
#ifndef __MOD_KBINPUT__
#define __MOD_KBINPUT__
int kbInit();
int kbWait();
int kbTest();
#endif
And the CMakeLists.txt file looks like this:
FILE(
GLOB_RECURSE
sources
*.c
)
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include/utils/kbreader")
ADD_LIBRARY(keyboardReader ${sources})
Compiling this lib gives some warnings:
src/utils/kbreader/keyboard_input.c: In function ‘kbInit’:
src/utils/kbreader/keyboard_input.c:13:14: warning: assignment from incompatible pointer type [enabled by default]
src/utils/kbreader/keyboard_input.c: In function ‘kbWait’:
src/utils/kbreader/keyboard_input.c:21:55: warning: passing argument 4 of ‘fread’ from incompatible pointer type [enabled by default]
/usr/include/stdio.h:708:15: note: expected ‘struct FILE * __restrict__’ but argument is of type ‘struct FILE *’
Now, for my main executable (main.cpp):
#include <keyboard_input.h>
int main()
{
kbTest();
return 0;
}
Processed by the following CMakeLists.txt file:
include_directories("${PROJECT_SOURCE_DIR}/include/utils/kbreader")
file(
GLOB_RECURSE
srcs
*.cpp
)
add_executable(
PEM
${srcs}
)
target_link_libraries(PEM keyboardReader)
Ends up getting that error:
CMakeFiles/PEM.dir/main.cpp.o: In function `main':
main.cpp:(.text+0xb): undefined reference to `kbTest()'
collect2: ld returned 1 exit status
make[2]: *** [src/PEM/main2/PEM] Error 1
make[1]: *** [src/PEM/main2/CMakeFiles/PEM.dir/all] Error 2
The libkeyboardReader.a is created, and the kbTest() function doesn't do anything except
{return 0; }
If I set the definition of kbTest() in the header file, it works.
But there's something i don't get, when i type: make keyboardReader here is the output:
[ 73%] Building C object src/utils/kbreader/CMakeFiles/KeyboardReader.dir/keyboard_input.c.o
[Warning explained above]
Linking C static library ../../../lib/libKeyboardReader.a
Is there something wrong? Does the note error message makes my lib omit the keyboard_input.c file?
You're mixing C and C++ files. To make that work, you just have to tell the C++ compiler that it's calling a C function, by changing the header file like so:
#ifndef MOD_KBINPUT
#define MOD_KBINPUT
/* note I also fixed the macro so you aren't using a system-reserved name */
#if __cplusplus
/* this is the important part */
extern "C" {
#endif
int kbInit();
int kbWait();
int kbTest();
#if __cplusplus
}
#endif
#endif
Otherwise the C++ compiler assumes the function will be given a C++ internal name (which encodes all the type information in the signature, this is what lets the linker distinguish between overloaded functions) and then the linker doesn't find it.
EDIT: the solution to the problem is the following: http://www.jusuchyne.com/codingchyne/2011/03/codeblocks-failed-to-find-the-header-file/
It won't compile, I have the following errors:
foo.h no such file in directory;
foo has not been declared;
num was not declared in this scope
foo is not a class or a namespace
It is odd, to say the least, because I just used the code blocks "Create a new Class" and then added it to this project. This is the source code:
Header:
#ifndef FOO_H
#define FOO_H
class foo
{
private:
int num;
public:
foo();
void set_num(int set);
int get_num();
};
#endif // FOO_H
the cpp
#include "foo.h"
foo::foo()
{
num = 10;
}
void foo :: set_num(int set)
{
num = set;
}
int foo :: get_num()
{
return num;
}
Disregard the calss itself and what it does, the problem is that it doesn't compile even though I used the default code blocks class creation setting.
The errors:
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|1|error: foo.h: No such file or directory|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|3|error: 'foo' has not been declared|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|3|error: ISO C++ forbids declaration of 'foo' with no type|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp||In function 'int foo()':|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|5|error: 'num' was not declared in this scope|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|6|warning: no return statement in function returning non-void|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|8|error: 'foo' is not a class or namespace|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp||In function 'void set_num(int)':|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|10|error: 'num' was not declared in this scope|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|13|error: 'foo' is not a class or namespace|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp||In function 'int get_num()':|
C:\Users\SameTime\Desktop\CodeBLocks\ASDD\src\foo.cpp|15|error: 'num' was not declared in this scope|
||=== Build finished: 8 errors, 1 warnings ===|
If the header is not in the same directory you must either specify the path in the include command, or you must add -I Path directive to your makefile or include settings.
Maybe this link also helps as codeblock seems to have problems.
http://www.jusuchyne.com/codingchyne/2011/03/codeblocks-failed-to-find-the-header-file/
This should be a comment, but I don't have 50 rep yet...
Can you navigate to the source directory in the command line and try to compile manually to ensure that the error isn't with the IDE?
If your IDE is using g++ (it probably is) then the command would be g++ foo.cpp
Open Windows Explorer
Navigate to the folder containing the files
Make sure the header is called "foo.h" (You know Explorer sometimes hides file extensions, right?)
If that doesn't do it, your compiler is broken.
I use extern variable for my application class so i can forward class function to glutDisplayFunction(funcPtr).
main.cpp:
#include "main.hpp"
int main(int argc, char** argv)
{
gApp = new GameApp();
return 0;
}
main.hpp:
#ifndef MAIN_HPP
#define MAIN_HPP
#include "GameApp.hpp"
#endif
GameApp.hpp:
#include <GL/gl.h>
#include <GL/freeglut.h>
class GameApp
{
public:
int running;
GameApp();
virtual ~GameApp();
void resize(int width, int height);
void init(int argc, char** argv, int width, int height);
void draw();
void update();
void key_input(unsigned char key, int x, int y);
};
extern GameApp *gApp;
void display_clb()
{
if (!gApp)
{
return;
}
gApp->draw();
}
This is the output:
g++ -o dist/Debug/GNU-Linux-x86/gravity build/Debug/GNU-Linux-x86/main.o build/Debug/GNU-Linux-x86/GBody.o build/Debug/GNU-Linux-x86/GameApp.o build/Debug/GNU-Linux-x86/GBodyList.o -lm -lGL -lglfw -lGLU -lglut
build/Debug/GNU-Linux-x86/main.o: In function `main':
/home/viktor/Documents/cpp/Gravity/main.cpp:6: undefined reference to `gApp'
/home/viktor/Documents/cpp/Gravity/main.cpp:7: undefined reference to `gApp'
/home/viktor/Documents/cpp/Gravity/GameApp.cpp:13: undefined reference to `gApp'
/home/viktor/Documents/cpp/Gravity/GameApp.cpp:18: undefined reference to `gApp'
build/Debug/GNU-Linux-x86/GameApp.o: In function `display_clb()':
/home/viktor/Documents/cpp/Gravity/GameApp.cpp:23: undefined reference to `gApp'
build/Debug/GNU-Linux-x86/GameApp.o:/home/viktor/Documents/cpp/Gravity/GameApp.cpp:28: more undefined references to `gApp' follow
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/gravity] Error 1
make[2]: Leaving directory `/home/viktor/Documents/cpp/Gravity'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/home/viktor/Documents/cpp/Gravity'
make: *** [.build-impl] Error 2
I expected gApp to be visible in my main.cpp and in GameApp class.
That's not a compile error, it is a link error. You variable declaration is visible just fine in main.cpp, but you haven't defined it anywhere - i.e. you don't allocate space for that variable anywhere.
You'll need one (and exactly one) C++ file that defines that variable. Possibly your main.cpp:
GameApp *gApp;
(You could initialize it too right there, but that is not necessary in this case.)
This tells the compiler there is a variable named gApp but it is defined somewhere else:
extern GameApp *gApp;
because that definition does not exist, the linker fails.
Add the following to another (and only one) source file:
GameApp *gApp;
With extern, you tell the compiler that the variable exists, but it is located somewhere else. The compiler believes you the variable exists, and
All you have to do is create the actual variable somewhere in the source. You can do this by simply adding something like GameApp *gApp; somewhere. For example in your cpp file.
Same as the previous answers from other guys, you announced the existence of gApp, but you did not actually provide it.
Add one more word: I suggest you put the definition of gApp in a "GameApp.cpp" file(not GameApp.hpp), and put the declaration of it in a "GameApp.h" file.