0

I'm working on a quite large Makefile from the tensorflow repo and I need to add a file link.

After quite some debugging of a link error, I found out that if my file ends with .cc, then the link error disappears, whereas when linking a .c file, the error appears (file content remains the same).

I am linking the file in a Makefile.inc file:

.
.
.
FL_SRCS := \
tensorflow/lite/vis_mi/main.cc \
myFunctions.c \ -->>>>IF I CHANGE THE FILENAME TO myFunctions.cc and link to this .cc file here, it works!!
.
.
.
# Builds a standalone binary.
$(eval $(call vis_test,vis_mi,\
$(FL_SRCS),$(FL_HDRS)))

The link error when using the .c ending ends with:

tensorflow/lite/vis_mi/main.o: In function `main':
tensorflow/lite/vis_mi/main.cc:183: undefined reference to `printMsg()'
../downloads/gcc_embedded/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: link errors found, deleting executable `tensorflow/lite/vis_mi'
collect2: error: ld returned 1 exit status
gmake: *** [tensorflow/lite/vis_mi/Makefile.inc:578: tensorflow/lite/vis_mi/bin/micro_speech] Error 1

The .c file code:

#include <stdio.h>
#include "myFunctions.h"


void printMsg(){
    //do something here
}

And the header file:

#ifndef MYFUNCTIONS_H
#define MYFUNCTIONS_H

void printMsg();
#endif /* MYFUNCTIONS_H */

How can I include a file ending with .c? Makefiles are fairly new to me, and didn't want to include all the details, and if you need any further details from the Makefile to answer this question I'm happy to edit my post.

user2212461
  • 3,105
  • 8
  • 49
  • 87
  • The file extension tells make whether to treat the file as C code or C++ code. That changes the compiler, the flags, the make variables used, etc. https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html – kaylum Dec 09 '19 at 22:05
  • 1
    So, is your code actually C or C++? If it is C++ then it doesn't make sense to use a `.c` extension as that will just confuse everyone. – kaylum Dec 09 '19 at 22:05
  • @kaylum Its C code – user2212461 Dec 09 '19 at 22:06
  • And the whole application including libraries are C? If that is the case then we would need more details including the actual errors, the makefile rules and variables, etc. I've given you what changing the extension does to make but can't offer any more beyond that with the given info. – kaylum Dec 09 '19 at 22:09
  • I think more information is needed. One guess is maybe you have a rule similar to `%.o: %.cc $(CXX) -xc++ -c $< -o $@` in your makefile. But none for c files. – hko Dec 09 '19 at 22:10
  • If makefiles are new to you, I urge you to avoid use such complex and advanced capabilities like `eval` and `call`. Why not just write a straightforward rule and get that working? There's absolutely no way we can help since all the important parts of the makefile are hidden behind these advanced functions. – MadScientist Dec 09 '19 at 22:15
  • 1
    One file is being compiled as `C++` (main.cc) and the other as `C` (myFunctions.c). That won't work without code changes. If all the code really is C then change `main.cc` to be `main.c`. – kaylum Dec 09 '19 at 22:22
  • If you want the `.c` extension, you're probably going to have to learn about `extern "C"` in C++ and how to use it when you're calling C code. – Jonathan Leffler Dec 09 '19 at 22:22

1 Answers1

4

The name resolution for C and C++ functions is different. This is sometimes causing problem to "C" code that is also valid "C++". For example:

int foo(int x) { return x+1 } ;

The code Will create a function called 'foo' when compiled as "C", and will create a function called '_Z3fooi' when compiled as C++. Decoding the C++ name will (using c++filt) will show foo(int). The reason for the difference is that C++ support polymorphic functions (and methods), so that function names also identify the type of their parameters.

The proper solution is to decide on the language of the code. C++ and C are different language, and while it's possible to write code that will be valid for both, it will limit the ability to leverage each function abilities.

Important constraint: If a project contain both C and C++ code, it is important to remember that only functions that follow the "C" conventions can be called between the languages. This is usually implemented with extern "C" directive, and with #ifdef __cplusplus:

See more: https://www.thegeekstuff.com/2013/01/mix-c-and-cpp/ How to call C++ function from C? Call a C function from C++ code

dash-o
  • 13,723
  • 1
  • 10
  • 37