Author Topic: how to link source files in a project  (Read 664 times)

Offline alle_meije

  • Multiple posting newcomer
  • *
  • Posts: 29
how to link source files in a project
« 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: [Select]
-------------- 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: [Select]
#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: [Select]
#ifndef MAIN_HPP_INCLUDED
#define MAIN_HPP_INCLUDED

#include "test.h"

#endif // MAIN_HPP_INCLUDED

test.h
Code: [Select]
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED

void print_message (char *message);

#endif // TEST_H_INCLUDED

test.c
Code: [Select]
#ifndef TEST_C_INCLUDED
#define TEST_C_INCLUDED
#include <stdio.h>

void print_message (char *message) {

    printf("%s\n", message);

}

#endif // TEST_C_INCLUDED
« Last Edit: January 31, 2019, 03:25:04 pm by alle_meije »

Offline gd_on

  • Regular
  • ***
  • Posts: 494
Re: how to link source files in a project
« Reply #1 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!");
Windows 10, svn C::B (last version or almost!), WxWidgets 3.1.3, Compilers 8.1.0, 64 bits (seh, posix : gcc, g++ and gfortran in C:\MinGW64) or 32 bits (sjlj, posix in C:\MinGW32).

Offline Miguel Gimenez

  • Regular
  • ***
  • Posts: 383
Re: how to link source files in a project
« Reply #2 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: [Select]
#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

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 12126
    • Travis build status
Re: how to link source files in a project
« Reply #3 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).
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Miguel Gimenez

  • Regular
  • ***
  • Posts: 383
Re: how to link source files in a project
« Reply #4 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

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