PlatformIO: Fix ESP-IDF generation. (fix #734) (#739)

diff --git a/examples/platformio/.gitignore b/examples/platformio/.gitignore
index bf8c477..6093aef 100644
--- a/examples/platformio/.gitignore
+++ b/examples/platformio/.gitignore
@@ -1,5 +1,5 @@
 .pio/
 .idea/
 cmake-build-*/
-CMakeLists.txt
+/CMakeLists.txt
 CMakeListsPrivate.txt
diff --git a/examples/platformio/platformio.ini b/examples/platformio/platformio.ini
index 5049c0f..7e119b8 100644
--- a/examples/platformio/platformio.ini
+++ b/examples/platformio/platformio.ini
@@ -33,3 +33,16 @@
 ; All path are relative to the `$PROJECT_DIR`
 custom_nanopb_protos =
     +<proto/pio_without_options.proto>
+
+
+[env:pio_esp32_idf]
+platform = espressif32
+board = firebeetle32
+framework = espidf
+lib_deps = Nanopb
+
+; Warning: the 'src_filter' option cannot be used with ESP-IDF. Select source files to build in the project CMakeLists.txt file.
+; So, we specified source files in src/CMakeLists.txt
+
+custom_nanopb_protos =
+    +<proto/pio_without_options.proto>
diff --git a/examples/platformio/src/CMakeLists.txt b/examples/platformio/src/CMakeLists.txt
new file mode 100644
index 0000000..40ab4b7
--- /dev/null
+++ b/examples/platformio/src/CMakeLists.txt
@@ -0,0 +1,3 @@
+idf_component_register(
+        SRCS
+        pio_esp32_idf.c)
diff --git a/examples/platformio/src/pio_esp32_idf.c b/examples/platformio/src/pio_esp32_idf.c
new file mode 100644
index 0000000..5e12ea5
--- /dev/null
+++ b/examples/platformio/src/pio_esp32_idf.c
@@ -0,0 +1,34 @@
+#include "pb_encode.h"
+#include "pb_decode.h"
+
+#include "test.h"
+
+#include "pio_without_options.pb.h"
+
+void app_main() {
+    int status = 0;
+
+    uint8_t buffer[256];
+    pb_ostream_t ostream;
+    pb_istream_t istream;
+    size_t written;
+
+    TestMessageWithoutOptions original = TestMessageWithoutOptions_init_zero;
+    original.number = 45;
+
+    ostream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+
+    TEST(pb_encode(&ostream, &TestMessageWithoutOptions_msg, &original));
+
+    written = ostream.bytes_written;
+
+    istream = pb_istream_from_buffer(buffer, written);
+
+    TestMessageWithoutOptions decoded = TestMessageWithoutOptions_init_zero;
+
+    TEST(pb_decode(&istream, &TestMessageWithoutOptions_msg, &decoded));
+
+    TEST(decoded.number == 45);
+
+    return status;
+}
diff --git a/generator/platformio_generator.py b/generator/platformio_generator.py
index 9f296bd..9fbbbbf 100644
--- a/generator/platformio_generator.py
+++ b/generator/platformio_generator.py
@@ -145,4 +145,10 @@
     # Add generated includes and sources to build environment
     #
     env.Append(CPPPATH=[generated_src_dir])
-    env.BuildSources(generated_build_dir, generated_src_dir)
+
+    # Fix for ESP32 ESP-IDF https://github.com/nanopb/nanopb/issues/734#issuecomment-1001544447
+    global_env = DefaultEnvironment()
+    already_called_env_name = "_PROTOBUF_GENERATOR_ALREADY_CALLED_" + env['PIOENV'].replace("-", "_")
+    if not global_env.get(already_called_env_name, False):
+        env.BuildSources(generated_build_dir, generated_src_dir)
+    global_env[already_called_env_name] = True