User forums > Using Code::Blocks
how to link source files in a project
(1/1)
alle_meije:
Haven't used C::B for a while, and now I need to compile a C++ project that also include some old .c/.h files. I have added all the files to the project and included the headers for the functions, but I get an 'undefined reference' error. Am I making some basic mistake?
I have made a small project based on "hello world" that reproduces it. The project files are
test
├── bin
│ └── Debug
├── main.cpp
├── main.hpp
├── obj
│ └── Debug
├── test.c
├── test.cbp
├── test.depend
└── test.h
So to not get the 'undefined reference to print_message(char*)' error I need to make sure that test.c is compiled before main.cpp and linked when main.cpp is compiled?
Thanks for your help.
The build log is
--- Code: ----------------- Build: Debug in test (compiler: GNU GCC Compiler)---------------
g++ -o bin/Debug/test obj/Debug/main.o obj/Debug/test.o
/usr/bin/ld: obj/Debug/main.o: in function `main':
/tmp/test/main.cpp:9: undefined reference to `print_message(char*)'
collect2: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
2 error(s), 0 warning(s) (0 minute(s), 0 second(s))
--- End code ---
The contents of main.cpp are
--- Code: ---#include <iostream>
#include "main.hpp"
using namespace std;
int main() {
cout << "Hello world!" << endl;
print_message ("Hello world!");
return 0; }
--- End code ---
And the files main.hpp, test.h and test.c are:
main.hpp
--- Code: ---#ifndef MAIN_HPP_INCLUDED
#define MAIN_HPP_INCLUDED
#include "test.h"
#endif // MAIN_HPP_INCLUDED
--- End code ---
test.h
--- Code: ---#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
void print_message (char *message);
#endif // TEST_H_INCLUDED
--- End code ---
test.c
--- Code: ---#ifndef TEST_C_INCLUDED
#define TEST_C_INCLUDED
#include <stdio.h>
void print_message (char *message) {
printf("%s\n", message);
}
#endif // TEST_C_INCLUDED
--- End code ---
gd_on:
In your project workspace, right click on test\Sources\test.c, choose properties in the popup, in the second tab (Build) you can lower the priority for force test.c to be compiled before main.cpp, but the problem is not there. Click on the third tab (Advanced) and put CPP as the compiler variable, not CC given by default for a .c file.
And to avoid a warning, you can cast the string in print_message by (char *), to obtain print_message ((char *)"Hello world!");
Miguel Gimenez:
When mixing C and C++ sources you must specify C linkage in the C include files. Try this version of test.h:
--- Code: ---#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
void print_message (char *message);
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif // TEST_H_INCLUDED
--- End code ---
oBFusCATed:
--- Quote from: Miguel Gimenez on January 31, 2019, 06:00:06 pm ---When mixing C and C++ sources you must specify C linkage in the C include files. Try this version of test.h:
--- End quote ---
It is the other way round!
C++ names are mangled, so to stop the compiler/linker for mangling them you need to specify extern "C" in C++ files (both headers and sources).
Miguel Gimenez:
Name mangling must be removed in both cases (calling C from C++ and C++ from C) using extern "C" where appropiate. In this case the OP wants to call C code from C++, so the C headers must be modified.
Excerpt from sqlite3.h, part of a pure C library:
--- Quote ---/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
--- End quote ---
How do I call a C function from C++?
https://isocpp.org/wiki/faq/mixing-c-and-cpp#call-c
How do I Include a non-system C header file in C++ code?
https://isocpp.org/wiki/faq/mixing-c-and-cpp#include-c-hdrs-nonsystem
How do I call a C++ function from C?
https://isocpp.org/wiki/faq/mixing-c-and-cpp#call-cpp
Navigation
[0] Message Index
Go to full version