-1

I have a precompiled lib (.a extension) that I want to use integrated on the ESP8266 RTOS SDK examples.

There is a folder on following path (ESP8266_RTOS_SDK\components\esp8266\lib) where there are 22 .a files inside. I have put my lib there, but the compiler is like it is not recognizing the functions of my lib.

I have read something about edit some makefiles. Should I really do this? If yes, I would like to know which is the file to edit? (on which path it is placed)

EDIT

This is my working folder:

enter image description here

I was oriented by Espressif (developer of ESP8266) to make like shown below on component.mk, but it does not worked, compilation keeps showing "undefined reference" for the function of the lib.

enter image description here

Then I created an environment variable called COMPONENT_PATH on Windows, being the path the same as shown in the first picture.

enter image description here

Is there anything wrong with this?

EDIT 2

Created folder "include" inside main:

enter image description here

Added on top of C code: #include "include/lib123.h", which contains only one line: int sum (int a, int b);

Added on main a call: int result = sum(1,2);

Got compiler error: undefined reference to 'sum'

EDIT 3

For every compile try, the following file get updated inside folder \esp\tcp_server\build.

I won't place here directly because the file has more than 10.000 lines: https://raw.githubusercontent.com/jefersonpehls/esp8266_freeRTOS_firebase/master/tcp_server.map

EDIT4

When I try to make, this is what is shown:

make
Toolchain path: /opt/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc
Toolchain version: crosstool-ng-1.22.0-100-ge567ec7b
Compiler version: 5.2.0
Python requirements from C:/msys32/home/sandr/esp/ESP8266_RTOS_SDK/requirements.txt are satisfied.
LD build/tcp_server.elf
C:/msys32/home/sandr/esp/tcp_server/build/main\libmain.a(tcp_server_v5.o):(.literal.app_main+0x24): undefined reference to `sum'
C:/msys32/home/sandr/esp/tcp_server/build/main\libmain.a(tcp_server_v5.o): In function `app_main':
C:/msys32/home/sandr/esp/tcp_server/main/tcp_server_v5.c:382: undefined reference to `sum'
collect2.exe: error: ld returned 1 exit status
make: *** [C:\msys32\home\sandr\esp\ESP8266_RTOS_SDK/make/project.mk:510: /home/sandr/esp/tcp_server/build/tcp_server.elf] Error 1

EDIT 5

Here is the complete steps I use to make

sandr@DESKTOP-MA6RTB6 MINGW32 ~
$ cd ~/esp/tcp_server

sandr@DESKTOP-MA6RTB6 MINGW32 ~/esp/tcp_server
$ export PATH="$PATH:/opt/xtensa-lx106-elf/bin"

sandr@DESKTOP-MA6RTB6 MINGW32 ~/esp/tcp_server
$ make
Toolchain path: /opt/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc
Toolchain version: crosstool-ng-1.22.0-100-ge567ec7b
Compiler version: 5.2.0
Python requirements from C:/msys32/home/sandr/esp/ESP8266_RTOS_SDK/requirements.txt are satisfied.
LD build/tcp_server.elf
C:/msys32/home/sandr/esp/tcp_server/build/main\libmain.a(tcp_server_v5.o):(.literal.app_main+0x24): undefined reference to `sum'
C:/msys32/home/sandr/esp/tcp_server/build/main\libmain.a(tcp_server_v5.o): In function `app_main':
C:/msys32/home/sandr/esp/tcp_server/main/tcp_server_v5.c:382: undefined reference to `sum'
collect2.exe: error: ld returned 1 exit status
make: *** [C:\msys32\home\sandr\esp\ESP8266_RTOS_SDK/make/project.mk:510: /home/sandr/esp/tcp_server/build/tcp_server.elf] Error 1

EDIT 6

This is the content of esp\tcp_server\Makefile

#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#

PROJECT_NAME := tcp_server

EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common


include $(IDF_PATH)/make/project.mk

This is the content of esp\tcp_server\main\component.mk

#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files 
# in directory, adding 'include' to include path.)

COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_ADD_LDFLAGS += $(COMPONENT_PATH)/lib123.a

and IDF_PATH is C:\msys32\home\sandr\esp\ESP8266_RTOS_SDK

EDIT 7

This is $(IDF_PATH)/make/project.mk

https://github.com/jefersonpehls/esp8266_freeRTOS_firebase/blob/master/project.mk

abomin3v3l
  • 167
  • 1
  • 10
  • 2
    Post _text_, not _pictures of text_. – Clifford Mar 29 '20 at 07:33
  • 1
    "undefined reference" is a linker error, not a compiler error. Post the entire build log rather than _describing_ it. It was essential diagnostic information - all of it, not just the final error message. – Clifford Mar 29 '20 at 12:05
  • 1
    The map file is not what we need here. The _build log_ is all the text output to the console _during_ a build. i.e. the text that _includes_ the error message you are _describing_. – Clifford Mar 30 '20 at 13:32
  • 1
    `LD build/tcp_server.elf` is the linker command line. It is odd that it uses uppercase, but it includes none of the flags that you have set up in component.mk. Somehow you need to make the ld command line look something like that in my answer. For that you'll have to have better knowledge of how your build is set-up or tell use at least how you are building it - what commands are issued and the content of project and/or make files (as text, not pictures of text). – Clifford Mar 30 '20 at 14:08
  • @Clifford Edited. I have to say that I am very new to command line, currently I have difficult to understand the commands – abomin3v3l Mar 30 '20 at 14:17
  • 1
    you need to add to your question the text content of ~/esp/tcp_server/makefile, and ~/esp/tcp_server/main/component.mk – Clifford Mar 30 '20 at 14:23
  • @Clifford Edited – abomin3v3l Mar 30 '20 at 14:31
  • 1
    Sorry - now it is apparent that we need post $(IDF_PATH)/make/project.mk I have no idea what IDF path resolves to, but nothing in what you have posted includes component.mk. This could get very complicated, I think it is a question about the Expressif build system - the question of why the symbol is undefined is straightforward - you are not linking the library. How you are expected to do that in the Expressif build system I cannot tell you without downloading the whole shebang, and I am not about to do that. – Clifford Mar 30 '20 at 19:06
  • @Clifford Hi. I edited again. Posted the content of $(IDF_PATH)/make/project.mk. Anyway, thanks for you help. – abomin3v3l Mar 30 '20 at 19:47
  • IDF_PATH is the SDK directory (EDIT 6 on topic) – abomin3v3l Mar 30 '20 at 20:00

1 Answers1

3

It is the job of the linker rather then the compiler to link object library code.

Simply placing a library in a folder is insufficient, the linker needs to know the path to the library and the library name. The file need not be in the same folder as other libraries, although that will avoid the need to add an additional library path to your linker command line.

If using the GNU toolchain the linker (ld) registers library paths using the -L<searchdir> switch, and for a library named libXXX.a, the switch to link it is -lXXX.

e.g.:

ld -o program.elf main.o module.o -L.\MyLibraries -llinkthis.a

will link liblinkthis.a in the MyLibraries sub-folder of the build directory.

If using the gcc or g++ driver to compile and link, these switches can be passed to the driver and will be used to invoke ld. For example:

gcc main.c -o main.o -c
gcc module.c -o module.o -c
gcc -L.\MyLibraries -llinkthis.a main.o module.o -o program.elf 

or for a single source build:

gcc main.c -L.\MyLibraries -llinkthis.a -o program.elf

For other toolchains refer to the toolchain/linker documentation on linking static libraries.

For complex builds with many modules then certainly you should use a makefile or similar build management tool, or (more easily) an IDE with a project/build manager. An IDE will likely allow you to add libraries and paths via dialog boxes rather then having to know all the individual switches for your toolchain, make and similar tools can be more flexible for complex builds, but are somewhat arcane. However using make is not really directly related to the question of how to link a static library.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • is the linker who converters the .o in .a? Is it in this conversion that I need to try to hide the symbols? – abomin3v3l Mar 29 '20 at 00:25
  • 1
    @abomin3v3l In your edit, you are trying to link include/lib123.a, but lib123.a is not in the sub-directory "include". In fact there is no "include". My answer stands as a general description of how to link. The make file needs to generate the command lines as I suggested. You just need -l123, since your library is in your build directory. – Clifford Mar 29 '20 at 07:32
  • 1
    @abomin3v3l the linker dies not _convert_ anything, it _links_. It combines multiple object files, determines their location in the image, and resolves symbolic links between object code with actual addresses. – Clifford Mar 29 '20 at 07:38
  • What should be the correct path of lib123.a? Is my environment variable path correct? And why "include/lib123.a"? From where you got that "include/"? Thanks for helping! – abomin3v3l Mar 29 '20 at 09:59
  • 1
    @abomin3v3l The build log will tell all (by showing the commands generated by make), but you have not provided that. "_but it does not work_" is not a useful diagnostic; the messages output by the build are. – Clifford Mar 29 '20 at 12:01