undefined reference to memcpy, memmove, memset, ...

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: undefined reference to memcpy, memmove, memset, ...

Postby ESP_Angus » Mon Sep 11, 2017 3:00 am

jumjum123 wrote:Thanks for the feedback, downloaded latest version from github and still got undefined reference
Did you do a clean build (ie "make clean") before you rebuilt?
jumjum123 wrote: Next added
-T(ESP_IDF_PATH)/components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld
Now got undefined reference for esp_pthread_init

Next added
-L$(ESP_APP_TEMPLATE_PATH)/build/pthread \
-I$(ESP_IDF_PATH)/components/pthread/include \
-lheap \

Compiling runs fine. Size of binary is about 30k less than before.
That's... strange. This stuff should all be taken care of by the build system behind the scenes.

Are you able to please email me a zip file of your project directory by any chance (including the sdkconfig and the "build" directory)? angus at espressif dot com.
Would there be any way to find changes like this, instead of my simple textsearch, trial & error ?
I don't really know, as this seems like a regression in the build system. We run a number of automated build tests, but clearly they missed something.

There are some debugging tips here which can give some insight but it's a pretty tedious amount of information to filter through:
https://esp-idf.readthedocs.io/en/lates ... ke-process

(At the moment "make V=1" isn't working due to a regression last week. This will be fixed on github very soon.)
kolban wrote: To the best of my knowledge, the "internals" of the build system supplied be ESP-IDF aren't documented/broken apart and the high level expectation is to use the build environment to create ESP32 applications. That said, there should be no mystery nor magic in the build meaning that if you write your own scripts or build your own Makefile that does the same as the ESP-IDF build system, you should be just fine.
Correct, there are a few details in the docs linked above but not a lot. The build system .mk files do have a lot of comments in them, but the IDF build system uses almost every feature GNU Make has so it relies on some prior familiarity (and/or close readings of the GNU Make manual).
To perform "regression" checks, get yourself to a working environment and take a copy of the Makefiles necessary to build a regular ESP-IDF environment. Put them somewhere safe. Now, when ever you grab a new copy of the master ESP-IDF, you can perform a file diff against those few files and the ones you had saved when it was working. That way you will at least be "made aware" when a change is made to the build environment so that you can reflect any necessary changes back into your own build environment.
Git can also do this, ie:

Code: Select all

git fetch origin
git diff origin/master..HEAD -- make
Outputs a diff between the "remote" master branch (origin/master) and the branch you have checked out (HEAD), limited to the "make" subdirectory of the source. If you like the changes then you can then "git pull" them into your local branch.

In general, if you follow the directions in the build system docs then the only problems you should have after an update are due to bugs.

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: undefined reference to memcpy, memmove, memset, ...

Postby MartyMacGyver » Wed Sep 27, 2017 10:09 am

What's the status of this issue? I was on a version of the IDF from about 3 weeks back and just stumbled on this (decided to use memset()). It failed to build in the IDF even after doing `make clean` first. I updated to the very latest (including the newer toolchain) - same process, same issue:

Code: Select all

/ESP32-Digital-RGB-LED-Drivers-MFF/esp-idf/demo1/components/ws2812/ws2812.cpp: In function 'void ws2812_resetPixels(strand_t*)':
/ESP32-Digital-RGB-LED-Drivers-MFF/esp-idf/demo1/components/ws2812/ws2812.cpp:214:71: error: 'memset' was not declared in this scope
   memset(pStrand->pixels, 0, pStrand->numPixels * sizeof(pixelColor_t));
                                                                       ^
make[1]: *** [/c/esp-idf/make/component_wrapper.mk:243: ws2812.o] Error 1
make: *** [/c/esp-idf/make/project.mk:421: component-ws2812-build] Error 2
make: *** Waiting for unfinished jobs....
The ESP-IDF version of the `demo1` project at https://github.com/MartyMacGyver/ESP32- ... ED-Drivers on branch `feature-multistrand` commit ` b9e947f` demonstrates this effect.

I can work around this with a less efficient equivalent operation while investigation work continues.

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: undefined reference to memcpy, memmove, memset, ...

Postby MartyMacGyver » Wed Sep 27, 2017 10:45 am

Followup: Given there are demo esp-idf apps that presumably build OK, I looked at the includes of a simple one. By process of elimination I found that `#include <string.h>` fixes the problem.

A deeper search through the msys32 cross-compiler installation reveals that only /usr/include/string.h (and its other three instances) has memset defined thus:

Code: Select all

_PTR _EXFUN(memset,(_PTR, int, size_t));
The other related functions are similarly defined.

Then I stumbled on a note in /usr/include/gawkapi.h:

Code: Select all

 * The following types and/or macros and/or functions are referenced
 * in this file.  For correct use, you must therefore include the
 * corresponding standard header file BEFORE including this file.
 *
 * FILE			- <stdio.h>
 * NULL			- <stddef.h>
 * memset(), memcpy()	- <string.h>
 * size_t		- <sys/types.h>
 * struct stat		- <sys/stat.h>
 *
 * Due to portability concerns, especially to systems that are not
 * fully standards-compliant, it is your responsibility to include
 * the correct files in the correct way. This requirement is necessary
 * in order to keep this file clean, instead of becoming a portability
 * hodge-podge as can be seen in the gawk source code.
Why would memset, etc. be mediated by string.h? I did a bit more reading and came across this, confirming this isn't a bug but a subtlety of memset, etc.:
https://stackoverflow.com/questions/978 ... t-in-stdli

Most likely `string.h` was being included by some other dependency before and that's why it "just worked", when that was really just a side-effect that went away in a recent idf commit.

tl;dr - Make sure you include <string.h> if you want memset, memcpy, memcmp, memmove, and memchr to work consistently.

(That'd be a handly little note for the reference...)

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: undefined reference to memcpy, memmove, memset, ...

Postby kolban » Wed Sep 27, 2017 1:43 pm

Howdy,
When I look at a Unix man page for memset() ... see:

https://linux.die.net/man/3/memset

I find that it is defined in <string.h>

apparently it is also defined in <string.h> in the POSIX standard:

http://pubs.opengroup.org/onlinepubs/96 ... emset.html
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: undefined reference to memcpy, memmove, memset, ...

Postby MartyMacGyver » Wed Sep 27, 2017 7:59 pm

Yes, that's what I learned after I got the same undefined reference error the original poster got.

Had I included string.h (or something else that includes it) I'd never have had reason to look for this answer. That said, it didn't occur to me to look at the Linux man pages for this problem.

Who is online

Users browsing this forum: Gaston1980, Google [Bot] and 215 guests