0

I am trying to make a shared library in scons but it keeps telling me there is an error because there is an undefined reference to some functions I wrote. I include the .c file from which I am trying to make the shared library. For some reason it is recognizing the cpp file I am inputting but not the .c file.

Your help would be much appreciated`

import os

Import('env')

env = env.Clone()
env.Append(CPPPATH=['include'])
env.Append(LIBS=['serial'])

env.Append(LIBPATH=['/usr/local/lib'])
env.Append(LIBS=['boost_date_time','boost_system', 'boost_thread'])


lib = []
binaries = []

lib.extend(env.SharedLibrary('File1.c', 'File2.cpp']))
print "the error is here"
test_env = env.Clone()
test_env.Append(LIBS=['Program'], LIBPATH=['.'])
binaries.extend([
  test_env.Program('test_Program', Glob('test/test_Adafruit.cpp')),
])

Return('lib', 'binaries')

during the linking phase: I get the errors like:

LINK    build/test_Program
build/test_Program/libProgram.so: 

undefined reference to function(int, sensor_xyz_s*)'

Ariel Baron
  • 331
  • 4
  • 13
  • 1
    You have your question all wrong. Your question is really how to link C code and C++ code together on your platform, whatever platform it is. – David Schwartz Jan 19 '17 at 19:48

1 Answers1

2

C and C++ don't have the same calling conventions, so C++ does not recognize C functions from other objects. If you're trying to call a C function in File1.c from a C++ function in File2.cpp, you either need to (1) make sure to declare the C function with extern "C", (2) explicitly use the C++ compiler to create File1.o, or (3) rename File1 to File1.cpp (assuming that your C code is valid C++). The cleanest solution is probably option (1).

To set the C compiler in your SConscript, use:

env['CC'] = env['CXX']

To tell the C++ code that function is a C function, change the declaration of the C function to the following. Note that this is just the declaration of the function -- if the declaration is in a header used by both C and C++, you need to wrap the extern "C" so that it's hidden from the C compiler (which may not understand it).

#ifdef __cplusplus
extern "C" {
#endif

    void function(int, sensor_xyz_s*);

#ifdef __cplusplus
}
#endif
Community
  • 1
  • 1
Dave Bacher
  • 15,652
  • 3
  • 63
  • 86
  • So if, in File1. c there is void func(){}; it needs to be extern "C" {void func(){}}? – Ariel Baron Jan 19 '17 at 19:16
  • I now get error: conflicting declaration of 'int function(int, sensor_xyz_s*)' with 'C' linkage. Does the header file also have to have the extern "C" around the prototypes? – Ariel Baron Jan 19 '17 at 19:39
  • I updated my answer with an example. You should edit the header file so that there's one declaration of your function that both C and C++ recognize. – Dave Bacher Jan 19 '17 at 19:42
  • Can you have more than one function in the extern "C" brackets? do I have to edit both the .h and the .c file? or leave the .c file alone and just edit the .h file? – Ariel Baron Jan 19 '17 at 19:46
  • also where in the Scons file should I set env['CC'] = env['CXX'] – Ariel Baron Jan 19 '17 at 19:47
  • You really shouldn't need to set env['CC'] = env['CXX']. You can compile the .c with c compiler and .cpp with c++ compiler and have them link correctly without it. (assuming you're using the same version gcc and g++ for example). – bdbaddog Jan 20 '17 at 21:48
  • @bdbaddog, you're right, there's no need to all of what I suggested. I was trying to provide several options -- I clarified the answer. – Dave Bacher Jan 24 '17 at 00:02