1

Cross compiling for Beagle Bone Black on my centos machine.

Im creating an application 'BasicComponentsTest.cpp' which uses the 'SimFrameProducer' class that I've created and built into a static library i.e. 'libspu.a'. see below makefile and code for reference.

I get link error when compiling the main application using the 'libspu.a' statically link a library, however it works fine when I link the objects directly (see direct object makefile) i.e. it only fails when compiling with the static library that I created, obviously the the SPU object compile fine and creates the static library file 'libspu.a'.

The only thing I can think that might be wrong is the 'ar' command does not work properly for cross compiled objects, is this correct? is there any other reason why I get this error? BTW I'm still new to c++.

[root@CVDEV SPU]# make
make: Warning: File `Makefile' has modification time 3.6e+04 s in the future
/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-g++ -Wall -I ../../SPU/Include -L ../../SPU -lspu BasicComponentsTest.cpp -o Test1
/tmp/cc6Ck7Xj.o: In function `main':
BasicComponentsTest.cpp:(.text+0x1e): undefined reference to `SimFrameProducer::SimFrameProducer(char*)'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
[root@CVDEV SPU]#

BasicCompontentsTest.cpp main application file

#include <cstdlib>
#include "SimFrameProducer.h"
using namespace std;

/*
 * 
 */
int main(int argc, char** argv) {
    SimFrameProducer* prod = new SimFrameProducer((char*)"Test1");

    prod->Start();
    prod->Stop();

    delete prod;

    return 0;
}

SimFrameProducer.h

#include "SPUBase.h"
#include "SPUFrameProducer.h"

class SimFrameProducer:public SPUFrameProducer, public SPUBase {
public:
    SimFrameProducer(char* instanceId);
    virtual ~SimFrameProducer();
    void Start();
    void Stop();
private:

};

SimFrameProducer.cpp

#include "SimFrameProducer.h"
#include "Include/SimFrameProducer.h"


SimFrameProducer::SimFrameProducer(char* instanceId):SPUBase((char*)"TYPE_SAMPLE", instanceId) {

}

void SimFrameProducer::Start(){

}

void SimFrameProducer::Stop(){

}

SimFrameProducer::~SimFrameProducer() {

}

Makefile main BasicComponentsTest application

CC=/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-g++
SPU_PATH=../../SPU
INC=-I $(SPU_PATH)/Include
LIB=-L $(SPU_PATH)

all: 
    $(CC) -Wall $(INC) $(LIB) -lspu BasicComponentsTest.cpp -o Test1

Makefile linking direct object instead of static library

CC=/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-g++
SPU_PATH=../../SPU
INC=-I $(SPU_PATH)/Include
LIB=-L $(SPU_PATH)

OBJS=$(SPU_PATH)/SPUBase.o \
$(SPU_PATH)/SPUFrame.o \
$(SPU_PATH)/SPUFrameProducer.o \
$(SPU_PATH)/FFTFrameProducer.o \
$(SPU_PATH)/SimFrameProducer.o

## Target: all
all: 
    $(CC) -Wall $(INC) $(OBJS) BasicComponentsTest.cpp -o Test1

Makefile for SPU lib

CC=/opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-g++
INC=-I Include
## Target: all
all: 
    $(CC) -Wall $(INC) -c SPUBase.cpp
    $(CC) -Wall $(INC) -c SPUFrame.cpp
    $(CC) -Wall $(INC) -c SPUFrameProducer.cpp
    $(CC) -Wall $(INC) -c FFTFrameProducer.cpp
    $(CC) -Wall $(INC) -c SimFrameProducer.cpp
    ar cr libspu.a SPUBase.o SPUFrame.o SPUFrameProducer.o FFTFrameProducer.o SimFrameProducer.o  
unixsmurf
  • 5,852
  • 1
  • 33
  • 40
Beraben Systems
  • 103
  • 1
  • 1
  • 9
  • The archive utility `ar` does little more that combine multiple files into a single file. That is not the cause of your problem. Given the make file your static library must be `../../SPU/libspu.a` - is that the case? – Clifford Oct 25 '14 at 06:58
  • yes, i do not get file not found error in the compile/link – Beraben Systems Oct 25 '14 at 07:00
  • Why are you not using the ar command supplied with your cross toolchain? Even if your host ar has support for your target architecture (does it?), it may be of a different version than your cross ar. – unixsmurf Oct 25 '14 at 12:13

2 Answers2

0

Your archive lacks an object-file index. The ar command line should be:

ar rcs libspu.a SPUBase.o SPUFrame.o SPUFrameProducer.o FFTFrameProducer.o SimFrameProducer.o

You were missing the s option, making your archive just a collection of files in a file (an archive - ar is not just for libraries - though that is invariably what it is used for) rather than a library.

Clifford
  • 88,407
  • 13
  • 85
  • 165
0

Found the problem it was the order of where I put the static library when building it, apparently the static library was excluded because it was perceived by the compiler as not used, when you put it after the c++ file it realizes that it needs it and uses it. All credits to this post

c++ undefined references with static library

Changed my code to the following to get it to work

$(CC) -Wall -o Test1 $(INC) $(LIB)  BasicComponentsTest.cpp -lspu
Community
  • 1
  • 1
Beraben Systems
  • 103
  • 1
  • 1
  • 9