Using a precompiled library *.a

I need to use precompiled library with extension *.a in my project. To specify, I use BME 680 from Bosch and I am trying to compile this code: The BSEC Software | Bosch Sensortec
How should I do this? PlatformIO says that:
bsec_integration.c:(.text.bsec_iot_init+0xaf): undefined reference to bsec_init' bsec_integration.c:(.text.bsec_iot_init+0xea): undefined reference to bsec_set_configuration’
bsec_integration.c:(.text.bsec_iot_init+0x120): undefined reference to bsec_set_state' bsec_integration.c:(.text.bsec_iot_init+0x187): undefined reference to bsec_update_subscription’
.pioenvs/d1_mini_pro/src/bsec_integration.o:(.text.bsec_iot_loop+0x1c): undefined reference to bsec_sensor_control' .pioenvs/d1_mini_pro/src/bsec_integration.o:(.text.bsec_iot_loop+0x2c): undefined reference to bsec_do_steps’
.pioenvs/d1_mini_pro/src/bsec_integration.o:(.text.bsec_iot_loop+0x30): undefined reference to bsec_get_state' .pioenvs/d1_mini_pro/src/bsec_integration.o: In function bsec_iot_loop’:

    bsec_integration.c:(.text.bsec_iot_loop+0xa3): undefined reference to `bsec_sensor_control'
    bsec_integration.c:(.text.bsec_iot_loop+0x28e): undefined reference to `bsec_do_steps'
    bsec_integration.c:(.text.bsec_iot_loop+0x39a): undefined reference to `bsec_get_state'
    collect2: error: ld returned 1 exit status
    *** [.pioenvs/d1_mini_pro/firmware.elf] Error 1
1 Like

Modify the linker flags for GCC/G++ to add the library search path and the linker command itself. You can do this by adding a build_flags entry to your platformio.ini file, see platformio documentation. For GCC, you need to at least add -L directory/to/archive and -l*name_of_archive_file*

1 Like

Hi emil!

Did you manage to compile your project with the libalgobsec.a.
I had the same problem, that I had to include the file. But when I hit compile, platformio said:
avr/bin/ld: skipping incompatible lib/libalgobsec.a when searching for -lalgobsec
Any help appreciated.

Best regards

That error message indicates you are using the wrong architecture version of the libalgobsec.a file, you need the AVR(8?) one. Which file in algo\bin\ have you selected exactly and where is stored? What microcontroller are you running on? What’s your exact platformio.ini?

I thought so, but I copied the file from: BSEC_1.4.5.1_Generic_Release_20171214/algo/bin/avr/libalgobsec.a
I want to compile it for Arduino Pro Mini (Atmega328P).

The file is currently stored in the lib folder of the PlatformIO project.
build_flags = -L/Users/philipp/Documents/PlatformIO/Projects/180225-200851-pro8MHzatmega328/lib/ -lalgobsec

That file doesn’t exist. There are 3 sub folders for AVR8_megaAVR, AVR8_XMEGA and AVR32. Which one did you choose? For your ATMega328P you need the file from the megaAVR folder (see here). Also make sure to take the other header files from there.

Ah you are right, sorry I didn’t copy the full path in the post before…
I took all files from BSEC_1.4.5.1_Generic_Release_20171214/algo/bin/avr/AVR8_megaAVR

Do you have any other ideas? Have you already used the library with an atmega?

You are right, I get the same error when using an Arduino Nano project. None of the “avr” files are accepted by the linker. Weird.

When I use the ESP32 library and example code it works flawlessly.

xtensa-esp32-elf-g++ -o .pioenvs\esp32dev\firmware.elf -nostdlib -Wl,-static -u call_user_start_cpu0 -Wl,--undefined=uxTopUsedPriority -Wl,--gc-sections -Wl,-LC:\Users\Maxi\Documents\ESPTesting\lib\BSEC_1_4_5_1\bin -Wl,-EL -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.spiram_incompatible_fns.ld -u ld_include_panic_highint_hdl -u __cxa_guard_dummy -u __cxx_fatal_exception -Wl,-T"esp32_out.ld" .pioenvs\esp32dev\src\bme680.c.o .pioenvs\esp32dev\src\bsec_integration.c.o .pioenvs\esp32dev\src\main.cpp.o -LC:\Users\Maxi\.platformio\packages\framework-arduinoespressif32\tools\sdk\lib -LC:\Users\Maxi\.platformio\packages\framework-arduinoespressif32\tools\sdk\ld -L.pioenvs\esp32dev -Wl,--start-group .pioenvs\esp32dev\liba1b\libWire.a .pioenvs\esp32dev\lib6e2\libBSEC_1_4_5_1.a .pioenvs\esp32dev\libFrameworkArduinoVariant.a .pioenvs\esp32dev\libFrameworkArduino.a -lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lhal -lnewlib -ldriver -lbootloader_support -lpp -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -lmdns -lvfs -lsoc -lcore -lsdmmc -lcoap -ltcpip_adapter -lc_nano -lrtc -lspi_flash -lwpa2 -lesp32 -lapp_update -lnghttp -lspiffs -lespnow -lnvs_flash -lesp_adc_cal -llog -lexpat -lm -lc -lheap -lmbedtls -llwip -lnet80211 -lpthread -ljson -lstdc++ -lalgobsec -Wl,--end-group
xtensa-esp32-elf-size -B -d .pioenvs\esp32dev\firmware.elf
"c:\python27\python.exe" "C:\Users\Maxi\.platformio\packages\tool-esptoolpy\" --chip esp32 elf2image --flash_mode dio --flash_freq 40m --flash_size 4MB -o .pioenvs\esp32dev\firmware.bin .pioenvs\esp32dev\firmware.elf v2.1
text	   data	    bss	    dec	    hex	filename
161494	  39148	   3888	 204530	  31ef2	.pioenvs\esp32dev\firmware.elf
 [SUCCESS] Took 16.43 seconds 

But for some reason the avr-g++ linker doesn’t like the file. Although I checked by doing readelf -h <lib..> what’s in there looks good.

$ readelf -h libalgobsec.a

File: libalgobsec.a(Bsec.o)
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Atmel AVR 8-bit microcontroller
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          12804 (bytes into file)
  Flags:                             0x86, avr:6, link-relax
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         48
  Section header string table index: 45

Don’t know what’s wrong there, maybe wrong linker flags or linker error on our side, or error on their side. Will check.

This doesn’t even work within Arduino IDE for the Arduino Uno. Same “skipping incompatible” thing.

I added -lalgobsec to recipe.c.combine.pattern line in my arduino-1.8.3\hardware\arduino\avr\platform.txt file, copied the lib from algo\bin\avr\AVR8_megaAVR\libalgobsec.a inside arduino-1.8.3\hardware\tools\avr\lib\gcc\avr\4.9.2.


Archiving built core (caching) in: C:\Users\Maxi\AppData\Local\Temp\arduino_cache_780443\core\core_arduino_avr_nano_cpu_atmega328_e2262a9fc872b629452720cdd8d9a0a6.a
Linking everything together...
"C:\Users\Maxi\Downloads\arduino-1.8.3\hardware\tools\avr/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p  -o "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/sketch_feb25a.ino.elf" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\sketch\bme680.c.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\sketch\bsec_integration.c.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\sketch\sketch_feb25a.ino.cpp.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\libraries\Wire\Wire.cpp.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\libraries\Wire\utility\twi.c.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/core\core.a" "-LC:\Users\Maxi\AppData\Local\Temp\arduino_build_233905" -lm -lalgobsec
c:/users/maxi/downloads/arduino-1.8.3/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: skipping incompatible c:/users/maxi/downloads/arduino-1.8.3/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2\libalgobsec.a when searching for -lalgobsec

c:/users/maxi/downloads/arduino-1.8.3/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: cannot find -lalgobsec

collect2.exe: error: ld returned 1 exit status

I suggest that you write to creators of this library, as this is not PIO bug . As I demonstrated this worked with their ESP32 archive okay but not with the AVR version, neither in the Arduino IDE nor in PIO with the (modified) procedure given in the PDF file at docs/BST-BME680-AN008-45.pdf page 15.

EDIT: AHA! Using the Arduino IDE I was able to play with the boards. It does build for the ATMega2850! Why not for the ATMega328P? No idea, ask Bosch.

Archiving built core (caching) in: C:\Users\Maxi\AppData\Local\Temp\arduino_cache_780443\core\core_arduino_avr_megaADK_e2262a9fc872b629452720cdd8d9a0a6.a
Linking everything together...
"C:\Users\Maxi\Downloads\arduino-1.8.3\hardware\tools\avr/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections,--relax -mmcu=atmega2560  -o "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/sketch_feb25a.ino.elf" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\sketch\bme680.c.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\sketch\bsec_integration.c.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\sketch\sketch_feb25a.ino.cpp.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\libraries\Wire\Wire.cpp.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905\libraries\Wire\utility\twi.c.o" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/core\core.a" "-LC:\Users\Maxi\AppData\Local\Temp\arduino_build_233905" -lm -lalgobsec
"C:\Users\Maxi\Downloads\arduino-1.8.3\hardware\tools\avr/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0  "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/sketch_feb25a.ino.elf" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/sketch_feb25a.ino.eep"
"C:\Users\Maxi\Downloads\arduino-1.8.3\hardware\tools\avr/bin/avr-objcopy" -O ihex -R .eeprom  "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/sketch_feb25a.ino.elf" "C:\Users\Maxi\AppData\Local\Temp\arduino_build_233905/sketch_feb25a.ino.hex"
Bibliothek Wire in Version 1.0 im Ordner: C:\Users\Maxi\Downloads\arduino-1.8.3\hardware\arduino\avr\libraries\Wire  wird verwendet
Der Sketch verwendet 46492 Bytes (18%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 3062 Bytes (37%) des dynamischen Speichers, 5130 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

Also works in PIO as expected when using ATMega2850.

PLATFORM: Atmel AVR > Arduino Mega or Mega 2560 ATmega2560 (Mega 2560)
SYSTEM: ATMEGA2560 16MHz 8KB RAM (248KB Flash)
Library Dependency Finder ->
Collected 25 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Wire> v1.0 (C:\Users\Maxi\.platformio\packages\framework-arduinoavr\libraries\__cores__\arduino\Wire)
|-- <BSEC_1_4_5_1> (C:\Users\Maxi\Documents\stackoverflow_testing\lib\BSEC_1_4_5_1)
avr-g++ -o .pioenvs\nanoatmega328\firmware.elf -Os -mmcu=atmega2560 -Wl,--gc-sections -flto -fuse-linker-plugin -Wl,-LC:\Users\Maxi\Documents\stackoverflow_testing\lib\BSEC_1_4_5_1\bin .pioenvs\nanoatmega328\src\bme680.c.o .pioenvs\nanoatmega328\src\bsec_integration.c.o .pioenvs\nanoatmega328\src\main.cpp.o -L.pioenvs\nanoatmega328 -Wl,--start-group .pioenvs\nanoatmega328\lib7e6\libWire.a .pioenvs\nanoatmega328\lib8f3\libBSEC_1_4_5_1.a .pioenvs\nanoatmega328\libFrameworkArduinoVariant.a .pioenvs\nanoatmega328\libFrameworkArduino.a -lm -lalgobsec -Wl,--end-group
avr-objcopy -O ihex -R .eeprom .pioenvs\nanoatmega328\firmware.elf .pioenvs\nanoatmega328\firmware.hex
avr-size --mcu=atmega2560 -C -d .pioenvs\nanoatmega328\firmware.elf
AVR Memory Usage
Device: atmega2560

Program:   47260 bytes (18.0% Full)
(.text + .data + .bootloader)

Data:       3062 bytes (37.4% Full)
(.data + .bss + .noinit)

 [SUCCESS] Took 2.71 seconds 

Thank you very very much for your help. I didn’t get any notification emails that you replied, thats why I answer now.

Ok so it seems there is no way around, but to ask Bosch for help.

Thanks, best regards,


Well I reached Bosch at their GitHub repo.
It looks like this library is just not made for 328P.
Please find the conversation here

Best regards