Code::Blocks Forums

User forums => Using Code::Blocks => Topic started by: alle_meije on January 31, 2019, 03:08:52 pm

Title: how to link source files in a project
Post by: alle_meije on January 31, 2019, 03:08:52 pm
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))

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; }

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

test.h
Code
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED

void print_message (char *message);

#endif // TEST_H_INCLUDED

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
Title: Re: how to link source files in a project
Post by: gd_on on January 31, 2019, 04:47:28 pm
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!");
Title: Re: how to link source files in a project
Post by: 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:

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
Title: Re: how to link source files in a project
Post by: oBFusCATed on January 31, 2019, 06:23:00 pm
When mixing C and C++ sources you must specify C linkage in the C include files. Try this version of test.h:
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).
Title: Re: how to link source files in a project
Post by: Miguel Gimenez on January 31, 2019, 06:49:26 pm
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

How do I call a C function from C++?

https://isocpp.org/wiki/faq/mixing-c-and-cpp#call-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 (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 (https://isocpp.org/wiki/faq/mixing-c-and-cpp#call-cpp)