Page 1 of 2

Using CMake add_custom_command() to perform POST_BUILD action

Posted: Sat Jul 20, 2019 3:08 am
by william.ferguson.au
I want to be able to copy the main binary (and eventually the other binaries) to another folder post build.
Note: I don't want to generate the output in this other folder. Taking a copy is a necessarily separate and discrete step.

I tried using CMake "add_custom_command"

Code: Select all

add_custom_command(
        TARGET esp32
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:esp32> "E:/SomeFolder"
        COMMENT "Copying esp32 binary output to SomeFolder"
)
In both the root CMakeLists.txt (after project) and in the mina/CmakeLists.txt (after register_component), and while it builds, it doesn't like target 'esp32' so never copies. Output is:

Code: Select all

Loading defaults file E:/Source/esp32/wave_touchpad/sdkconfig.defaults...
-- IDF_VER: v3.3-beta1-849-g630ffde6b
-- Project version: 1
-- Could NOT find Perl (missing: PERL_EXECUTABLE)
-- Adding linker script E:/Source/esp32/wave_touchpad/build/esp-idf/esp32/esp32_out.ld
-- Adding linker script E:/Dev/Espressif/esp-idf/components/esp32/ld/esp32.rom.ld
-- Adding linker script E:/Dev/Espressif/esp-idf/components/esp32/ld/esp32.peripherals.ld
-- Adding linker script E:/Dev/Espressif/esp-idf/components/esp32/ld/esp32.rom.libgcc.ld
-- Adding linker script E:/Dev/Espressif/esp-idf/components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld
-- Building empty aws_iot component due to configuration
-- Component libraries:
CMake Error at CMakeLists.txt:31 (add_custom_command):
  No TARGET 'esp32' has been created in this directory.
Is this the correct way to execute a post build action with esp32 CMake?
And if so,
- What target am I looking for in order to make it work ?
- In which CMakeLists.txt should I add the command?

William

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Sat Jul 20, 2019 3:42 am
by william.ferguson.au
OK, this at least gets executed. But $TARGET_FILE:${IDF_PROJECT_EXECUTABLE}> resolves to foo-bar.elf
And I need foo-bar.bin

Code: Select all

project(foo-bar)

add_custom_command(
        TARGET ${IDF_PROJECT_EXECUTABLE}
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E echo idf_project_executable=${IDF_PROJECT_EXECUTABLE} target_file=$<TARGET_FILE:${IDF_PROJECT_EXECUTABLE}>
        COMMENT "Copying esp32 binary output to SomeFolder"
)
Generates:

Code: Select all

idf_project_executable=foo-bar.elf target_file=E:/Source/esp32/my_app/build/foo-bar.elf
How do I target the binary output instead of the elf?

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Sun Jul 21, 2019 2:03 am
by william.ferguson.au
Anyone know how I can target the bin file?
Surely someone has already done this.

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Mon Jul 22, 2019 3:07 am
by ESP_Angus
Hi william,

You should be able to attach the post-build actions to the gen_project_binary target, or the app target (which is the high-level target that builds all the app-related parts but not the bootloader, partition table, etc). app depends on gen_project_binary among other targets.

These targets are defined here:
https://github.com/espressif/esp-idf/bl ... .cmake#L87

If you want to get the binary file names from the IDF build system, you can do this with idf_build_get_property() - see a few lines up in this file - or you can hard code them in your project if you prefer.

EDIT: This answer assumes you're using IDF V4.0. The app target exists in v3.x but I'm not certain about the gen_project_binary target

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Tue Jul 23, 2019 7:05 pm
by william.ferguson.au
Hi Angus,

I'm using the esp-idf release/v3.3 branch 91f29bef172a082cbd8f0208ed1757ede0e1d635 (which still identifies as -- IDF_VER: v3.3-beta1-864-g91f29bef1 during the build for some reason).

I tried adding a custom command to the app target (in both the project folder and main folder) but it keeps coming back with:

Code: Select all

CMake Error at main/CMakeLists.txt:8 (add_custom_command):
  TARGET 'app' was not created in this directory.
This was the command I added:

Code: Select all

add_custom_command(
        TARGET app
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E echo bin=${build_dir}/${PROJECT_BIN}
        COMMENT "Copying esp32 binary output to SomeFolder"
)
NB this is on Windows 10.

I'm willing to try running this on v4.0, but not sure where I find v4.0 as there is no branch.
I tried esp-idf master, but it fails because it can't resolve component 'ethernet' (NB I don't have any such component).

Code: Select all

E:\Source\esp32\wave_touchpad>idf.py build
Checking Python dependencies...
Python requirements from E:\Dev\Espressif\esp-idf\requirements.txt are satisfied.
Executing action: all (aliases: build)
Running cmake in directory e:\source\esp32\wave_touchpad\build
Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED=1 -DESP_PLATFORM=1 --warn-uninitialized -DCCACHE_ENABLE=0 e:\source\esp32\wave_touchpad"...
Warn about uninitialized values.
-- Component directory E:/Dev/Espressif/esp-idf/components/aws_iot does not contain a CMakeLists.txt file. No component will be added
-- Component directory E:/Dev/Espressif/esp-idf/components/micro-ecc does not contain a CMakeLists.txt file. No component will be added
-- Project version: 1
-- Building ESP-IDF components for target esp32
CMake Error at E:/Dev/Espressif/esp-idf/tools/cmake/build.cmake:185 (message):
  Failed to resolve component 'ethernet'.
Call Stack (most recent call first):
  E:/Dev/Espressif/esp-idf/tools/cmake/build.cmake:211 (__build_resolve_and_add_req)
  E:/Dev/Espressif/esp-idf/tools/cmake/build.cmake:407 (__build_expand_requirements)
  E:/Dev/Espressif/esp-idf/tools/cmake/project.cmake:341 (idf_build_process)
  CMakeLists.txt:15 (project)


-- Configuring incomplete, errors occurred!
See also "E:/Source/esp32/wave_touchpad/build/CMakeFiles/CMakeOutput.log".
See also "E:/Source/esp32/wave_touchpad/build/CMakeFiles/CMakeError.log".
cmake failed with exit code 1
I tried against tag v4.0-dev and the build didn't crash like master, but it still gave

Code: Select all

CMake Error at CMakeLists.txt:25 (add_custom_command):
  TARGET 'app' was not created in this directory.
Side question:
What is the branch/tag policy with esp-idf?
Do tags slip? A name like v4.0-dev (and the fact that there is no v4.0 branch) implies that they do?
In which case what are the branches for?
And what esp-idf SCM labels should I be using to ensure that my build remains the same from one day to the next and machine to machine?

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Wed Jul 24, 2019 5:01 am
by ESP_Angus
Hi William,

Thanks for your patience in working through this.
william.ferguson.au wrote:
Tue Jul 23, 2019 7:05 pm
I'm using the esp-idf release/v3.3 branch 91f29bef172a082cbd8f0208ed1757ede0e1d635 (which still identifies as -- IDF_VER: v3.3-beta1-864-g91f29bef1 during the build for some reason).
This is a bug in CMake-based build system that's fixed on master but we didn't backport the fix to 3.3. CMake build system runs "git describe" not "git describe --tags". The difference is that without "--tags" only annotated tags are considered, and the beta3 tag was accidentally not annotated.

We're annotating all tags from now on (and master branch build system uses "git describe --tags", so if we do accidentally create a non-annotated tag in the future then it won't trigger this inconsistency.)
william.ferguson.au wrote:
Tue Jul 23, 2019 7:05 pm
I tried adding a custom command to the app target (in both the project folder and main folder) but it keeps coming back with:

Code: Select all

CMake Error at main/CMakeLists.txt:8 (add_custom_command):
  TARGET 'app' was not created in this directory.
This was the command I added:

Code: Select all

add_custom_command(
        TARGET app
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E echo bin=${build_dir}/${PROJECT_BIN}
        COMMENT "Copying esp32 binary output to SomeFolder"
)
NB this is on Windows 10.
I see, sorry for the bad advice before. I'll try to find a recipe to do this reliably and get back to you.
william.ferguson.au wrote:
Tue Jul 23, 2019 7:05 pm
I tried esp-idf master, but it fails because it can't resolve component 'ethernet' (NB I don't have any such component).
I'm not sure what caused this. The "ethernet" component is in v3.x but not v4.x (it was renamed esp_eth in master). I tried building with the 3.3 commit you're using and then switching to master branch and building again, but it builds fine for me.

Maybe some stale content in IDF_PATH? Does "git status" in the IDF_PATH directory show anything?
Side question:
What is the branch/tag policy with esp-idf?
Some explanation can be found here:
https://docs.espressif.com/projects/esp ... nt-version
Do tags slip? A name like v4.0-dev (and the fact that there is no v4.0 branch) implies that they do?
In which case what are the branches for?
This should answer this question, please let me know if anything is still unclear: https://docs.espressif.com/projects/esp ... t-workflow

Specifically: v4.0 is still in development (v4.0-dev), so there is no v4.0 release or prerelease yet. Until we start beta testing (and master becomes v4.1-dev) then there will be no release/v4.0 branch. This step will happen in the week or two, probably.
And what esp-idf SCM labels should I be using to ensure that my build remains the same from one day to the next and machine to machine?
Some details here, but again please let me know if any remaining questions:
https://docs.espressif.com/projects/esp ... start-with

In all cases, if the output of either "git describe --tags --dirty" is the same for two IDF directories (and the word "dirty" doesn't appear in the output, indicating no local IDF changes are "dirtying" the working directory) then the IDF code is all the same. Or you can use git commit hashes to identify them, also.

If you're looking for consistency then I'd recommend checking out a stable version or a prerelease tag, as described at link above.

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Wed Jul 24, 2019 7:21 am
by william.ferguson.au
Thanks Angus.

'git status' isn't showing anything on master that would explain the "Failed to resolve component 'Ethernet'"

Code: Select all

E:\Dev\Espressif\esp-idf>git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .idea/
        cmake-build-debug/
        components/aws_iot/
        components/bt/lib/
        components/esp32/lib/
        components/micro-ecc/

nothing added to commit but untracked files present (use "git add" to track)

E:\Dev\Espressif\esp-idf>

E:\Dev\Espressif\esp-idf>git describe --tags --dirty
v4.0-dev-1287-gd7e659df2
NB even after deleting all the untracked files it still fails.

And thanks for the links to the versioning page.
I understand the process for branches and tags for release and pre-release. It seems clear that tags don't slip (which is good IMHO), and branches are the moving part (again good).

I am looking for consistency in the build, but the must haves are:
- CMake
- Being able to do post build actions.
So can't settle until then.

Looking forward to your help on the post build action.

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Wed Jul 24, 2019 9:24 am
by ESP_Angus
william.ferguson.au wrote:
Wed Jul 24, 2019 7:21 am
NB even after deleting all the untracked files it still fails.
If you rename the project's existing build directory to something else (rather than deleting it, for debugging purposes) and run a 100% clean build of the project, does it pass?

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Wed Jul 24, 2019 9:38 am
by william.ferguson.au
A 100% clean build of my project (not esp-idf)?
No, still fails with the same error.

Code: Select all

-- Building ESP-IDF components for target esp32
CMake Error at E:/Dev/Espressif/esp-idf/tools/cmake/build.cmake:185 (message):
  Failed to resolve component 'ethernet'.
Call Stack (most recent call first):
  E:/Dev/Espressif/esp-idf/tools/cmake/build.cmake:211 (__build_resolve_and_add_req)
  E:/Dev/Espressif/esp-idf/tools/cmake/build.cmake:407 (__build_expand_requirements)
  E:/Dev/Espressif/esp-idf/tools/cmake/project.cmake:341 (idf_build_process)
  CMakeLists.txt:15 (project)


-- Configuring incomplete, errors occurred!
See also "E:/Source/esp32/wave_touchpad/build/CMakeFiles/CMakeOutput.log".
See also "E:/Source/esp32/wave_touchpad/build/CMakeFiles/CMakeError.log".
cmake failed with exit code 1

Re: Using CMake add_custom_command() to perform POST_BUILD action

Posted: Wed Jul 24, 2019 11:14 am
by ESP_Angus
So this is with the build directory totally deleted or renamed?

Is there a component in your project (main, or another component) that lists "ethernet" as a requirement in its CMakeLists.txt? I checked the IDF version you're using (d7e659df2) and there's no mention of "ethernet" component in any CMake files - so the only explanations I can think of are that the "build" directory has some old data which is not being refreshed, or the project is requiring this somehow.