Go Down

Topic: could you help me with these errors building with CMake? (Read 557 times) previous topic - next topic

burdickjp

I'm trying to get CMake working on an up-to-date Arch Linux install, and am getting some errors. I can get CMake's example to build, and I can get some library's examples to build, but no this sketch. I'd appreciate some help.

Here's my CMake file:
Code: [Select]
set(CMAKE_TOOLCHAIN_FILE /home/jeff/projects/electronics/arduino/arduinoCMake/cmake/ArduinoToolchain.cmake)
cmake_minimum_required(VERSION 2.8)



set(ARDUINO_DEFAULT_BOARD micro) # Default Board ID, when not specified
set(ARDUINO_DEFAULT_PORT /dev/ttyUSB0) # Default Port, when not specified

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libraries)
link_directories(/usr/share/arduino/libraries)

project(dashDigital C CXX)

generate_arduino_firmware(dashDigitalNew
BOARD micro
   SKETCH dashDigitalNew.ino
   PROGRAMMER avrisp
   NO_AUTOLIBS)


Here's the error I'm getting:
Quote
Linking CXX executable dashDigitalNew.elf
CMakeFiles/dashDigitalNew.dir/dashDigitalNew_dashDigitalNew.ino.cpp.obj: In function `loop':
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:147: undefined reference to `LiquidCrystal::setCursor(unsigned char, unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:150: undefined reference to `TinyGPSPlus::TinyGPSPlus()'                                                          
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:151: undefined reference to `LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'                                                        
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `CAN'                                                                                
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `CAN'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `MCP_CAN::begin(unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::begin(unsigned char, unsigned char, unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::clear()'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::createChar(unsigned char, unsigned char*)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::setCursor(unsigned char, unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::write(unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::setCursor(unsigned char, unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::write(unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::write(unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `LiquidCrystal::setCursor(unsigned char, unsigned char)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `CAN'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `CAN'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `MCP_CAN::readMsgBuf(unsigned char*, unsigned char*)'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `CAN'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `CAN'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `MCP_CAN::getCanId()'
/home/jeff/projects/electronics/dashDigital/code/dashDigitalNew.ino:180: undefined reference to `TinyGPSPlus::encode(char)'
collect2: error: ld returned 1 exit status
CMakeFiles/dashDigitalNew.dir/build.make:91: recipe for target 'dashDigitalNew.elf' failed
make[2]: *** [dashDigitalNew.elf] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/dashDigitalNew.dir/all' failed
make[1]: *** [CMakeFiles/dashDigitalNew.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2

burdickjp

Here's my sketch:
Code: [Select]
// GPS libs
#include <TinyGPS++.h>

// CAN bus libs
#include <SPI.h>
#include <mcp_can.h>

// disp libs
#include <LiquidCrystal.h>

// Connect the GPS TX (transmit) pin to micro RX
// Connect the GPS RX (receive) pin to micro TX
TinyGPSPlus gps;

// init CAN bus vars
unsigned char Flag_Recv = 0;
byte len = 1;
byte buf[8];
char str[20];

// init disp
LiquidCrystal lcd(
 6,  // RS
 7,  // E
 5,  // DB4
 4,  // DB5
 3,  // DB6
 2   //yaourt  DB7
);

// define custom characters for bar graph
byte charsCust[4][8] = {
 { B10000,
   B10000,
   B10000,
   B10000,
   B10000,
   B10000,
   B10000,
   B10000 },

 { B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000 },

 { B11100,
   B11100,
   B11100,
   B11100,
   B11100,
   B11100,
   B11100,
   B11100 },

 { B11110,
   B11110,
   B11110,
   B11110,
   B11110,
   B11110,
   B11110,
   B11110 },
};

unsigned int caseCan;

// def array size for input smoothing
const int sizeArray = 8;

// def struct for displaying fields
struct fieldDisp {
 boolean isFloat;
 boolean hasField;
 byte lenField;
 byte fieldX;
 byte fieldY;
 boolean roughBar;
 boolean smoothBar;
 byte lenBar;
 byte barX;
 byte barY;
 unsigned int barMax;
 byte index;
 unsigned int input;
 unsigned long total;
 unsigned int average[2];
 unsigned int raw[sizeArray];
};

// def disp vars
fieldDisp rpm =       { false, true,  4,  0, 1, false, true, 20, 0, 0, 8500};
fieldDisp tempH2O =   { false, true,  3,  4, 3, false, false};
fieldDisp vel =       { false, true,  3, 13, 1, false, false};
fieldDisp lambda =    { true,  true,  3,  4, 2, false, false};
fieldDisp levelFuel = { false, false, 4, 16, 2, false, true,  4, 16, 2, 255};

void setup()
{
 // connect serial at 115200
 Serial1.begin(9600);

 // 9600 NMEA is the default baud rate for MTK - some use 4800
 //ss.begin(9600);
 Serial1.println("PMTK_SET_NMEA_OUTPUT_RMCONLY");
 Serial1.println("PMTK_SET_NMEA_UPDATE_5HZ");
 
 // start can bus
 // baudrate = 500k
 if(CAN_OK == CAN.begin(CAN_500KBPS))
 {
//    Serial.println("CAN BUS Shield init ok!");
 }
 else
 {
//    Serial.println("CAN BUS Shield init fail");
 }

 // start display
 lcd.begin(20, 4);
 lcd.clear();
 
 // write custom chars for bar graphs to LCD
 for ( byte b = 0; b < 4; b++ ){
   lcd.createChar( b, charsCust[b] );
 }

 // write static data to LCD
 printDisp("RPM",5,1);
 printDisp("M/h",17,1);
 printDisp("A/F",0,2);
 printDisp("H2O",0,3);
 printDisp("C",8,3);
 printDisp("oil P",10,3);
 printDisp("fuel",16,3);

 //this is a funky character, so the printDisp function doesn't work
 lcd.setCursor(7,3);
 lcd.write(byte(223));
}

void loop()
{
 // read and parse data from CAN Bus
 CAN.readMsgBuf(&len, buf);
 caseCan = CAN.getCanId();
 switch (caseCan) {
case 1520:
 // RPMs are the 7th and 8th byte from CAN ID 1520
 rpm.input = 256*buf[6]+buf[7];
 break;
case 1522:
 // temperature is the 7th and 8th byte from CAN ID 1522
 // it is stored in F and must be divided by 10
 // convert from f to c because f is stupid
 tempH2O.input = (( 256*buf[6] + buf[7])/10 -32) *5/9;
 break;
case 1551:
 //convert from AFR to lambda but keep as an int. Will convert to fload before displaying
 lambda.input = buf[0] /0.147;
 break;
 }

 // read GPS speed
 while (Serial1.available() > 0)
   gps.encode(Serial1.read());
 vel.input = gps.speed.mph();

 // read fuel level
 unsigned int adcFuel = analogRead(A0);
 if (adcFuel >=371) {
   if (adcFuel >=673) levelFuel.input = 0;
   else levelFuel.input = map(adcFuel, 673, 371, 0, 127);
 }
 if (adcFuel <371) {
   if (adcFuel <= 51) levelFuel.input = 255;
   else levelFuel.input = map(adcFuel, 371, 51, 128, 255);
 }
 //Serial.println( levelFuel.raw[levelFuel.index] );

 // print fields to display
 printField( rpm );
 printField( lambda );
 printField( tempH2O );
 printField( vel );
 printField( levelFuel );
}
void printField( struct fieldDisp &field )
{
 field.total -= field.raw[field.index];
 field.raw[field.index] = field.input;
 field.total += field.input;
 ++field.index;
 field.average[0] = field.total / sizeArray;

 // print rough bar if field has it
 if (field.roughBar == true) {
   if(field.raw[field.index] != field.raw[field.index -1]){
     drawBar(field.raw[field.index], field.barMax, field.lenBar, field.barX, field.barY);
   }
 }

 // print smoothed values for the things which involve smoothed values
 if (field.average[0] != field.average[1]){
   if (field.hasField == true){
     lcd.setCursor( field.fieldX, field.fieldY );
     if (field.isFloat == true) {
       // always prints 3 digits so no need to adjust positioning
       lcd.print( float(field.average[0]) /1000 );
     }
     else {
       // this is a hacked way of doing this, but I couldn't figure out
       // the printf structure to make it work the less hacked way
       if (field.lenField > 3 && field.average[0] < 1000) lcd.print(" ");
       if (field.lenField > 2 && field.average[0] < 100) lcd.print(" ");
       if (field.lenField > 1 && field.average[0] < 10) lcd.print(" ");
//        if (field.average[0] < 1) lcd.print(0);
//        else {
         lcd.print( field.average[0]);
//        }
     }
   }
   if (field.smoothBar == true) {
       drawBar(field.average[0], field.barMax, field.lenBar, field.barX, field.barY);
   }
   field.average[1] = field.average[0];
 }

 // roll over counter for smoothing array
 if (field.index >= sizeArray) {
   field.index = 0;
 }
}

// sets cursor and prints string
// str is string to print
// x and y are the starting characters of the string
void printDisp(char str[], byte x, byte y)
{
 lcd.setCursor(x,y);
 lcd.print(str);
}

// a lot of this came from the LcdBarGraph library
void drawBar( unsigned int value, unsigned int valueMax, byte len, byte x, byte y) {
 byte fullChars;
 byte partChar;
 if (value >= valueMax) {
   fullChars = len;
   partChar = 0;
 }
 else {
   // calculate the number of columns which are full
   fullChars = (long)value * len / valueMax;
   // calculate the partial character
   partChar = ((long)value * len * 5 / valueMax) % 5;
 }
 lcd.setCursor(x,y);

 // write filled chars
 for(byte i=0; i<fullChars; i++) {
   lcd.write(255);
 }

 // write partial char
 if (partChar > 0) {
   lcd.write(byte(partChar -1));
   ++fullChars;
 }

 // write remainder of bar with blank characters
 if (fullChars < len){
   for (byte i=fullChars; i < len; i++){
     lcd.write(" ");
   }
 }
}

burdickjp

When I came back to this a few days later I saw that my CMakeLists had a line "no_autolibs". When I looked it up in the documentation it seemed to correspond with my problem, and upon removal it compiles without trouble.

Go Up