title: PlatformIO failed to build: undefined reference to http_parser_init
body: <p>I am trying to set up over the air updates(OTA) updates using the example within the ESP-IDF framework library in PlaformIO. The ota simple_example main.c file imports a .h file called esp_http_client.h. esp_http_client imports another .h file called http_parser.h which is where the function http_parser_init is defined. I am building this project in PlaformIO in VScode so I checked the c_cpp_properties.json and both the http_parser.c and http_parser.h directories were included. I noticed that sometimes there are bugs with the c_cpp_properties file so I also included the the http_parser.h file directory in the platform.ini file. </p>
  
  <p><strong>I also run into the error:</strong></p>
  
  <p>undefined reference to http_parser_execute</p>
  
  <p>undefined reference to http_parser_url_init</p>
  
  <p>undefined reference to http_parser_parse_url</p>
  
  <p>which are all functions found in the http_parser.h file </p>
  
  <p><strong>Here is the code for the main.c file that I'm using</strong> </p>
  
  <pre><code>#include "freertos/FreeRTOS.h"
  #include "freertos/task.h"
  #include "freertos/event_groups.h"
  #include &lt;stdio.h&gt;
  #include "esp_system.h"
  #include "esp_wifi.h"
  #include "esp_event_loop.h"
  #include "esp_log.h"
  #include "esp_ota_ops.h"
  #include "esp_http_client.h"
  #include "esp_flash_partitions.h"
  #include "esp_partition.h"
  
  #include "nvs.h"
  #include "nvs_flash.h"
  #include "main.h"
  #define WIFI_SSID SSID
  #define WIFI_PASS PASSWORD
  #define SERVER_URL FIRMWARE_UPG_URL
  #define BUFFSIZE 1024
  #define HASH_LEN 32 /* SHA-256 digest length */
  
  static const char *TAG = "native_ota_example";
  /*an ota data write buffer ready to write to the flash*/
  static char ota_write_data[BUFFSIZE + 1] = { 0 };
  //  uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
  //  uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
  
  
  /* FreeRTOS event group to signal when we are connected &amp; ready to make a request */
  static EventGroupHandle_t wifi_event_group;
  
  /* The event group allows multiple bits for each event,
     but we only care about one event - are we connected
     to the AP with an IP? */
  const int CONNECTED_BIT = BIT0;
  
  static esp_err_t event_handler(void *ctx, system_event_t *event)
  {
      switch (event-&gt;event_id) {
      case SYSTEM_EVENT_STA_START:
          esp_wifi_connect();
          break;
      case SYSTEM_EVENT_STA_GOT_IP:
          xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
          break;
      case SYSTEM_EVENT_STA_DISCONNECTED:
          /* This is a workaround as ESP32 WiFi libs don't currently
             auto-reassociate. */
          esp_wifi_connect();
          xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
          break;
      default:
          break;
      }
      return ESP_OK;
  }
  
  static void initialise_wifi(void)
  {
      tcpip_adapter_init();
      wifi_event_group = xEventGroupCreate();
      ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
      wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
      ESP_ERROR_CHECK( esp_wifi_init(&amp;cfg) );
      ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
      wifi_config_t wifi_config = {
          .sta = {
              .ssid = SSID,
              .password = PASSWORD,
          },
      };
      ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
      ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
      ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &amp;wifi_config) );
      ESP_ERROR_CHECK( esp_wifi_start() );
  }
  
  static void http_cleanup(esp_http_client_handle_t client)
  {
      esp_http_client_close(client);
      esp_http_client_cleanup(client);
  }
  
  static void __attribute__((noreturn)) task_fatal_error()
  {
      ESP_LOGE(TAG, "Exiting task due to fatal error...");
      (void)vTaskDelete(NULL);
  
      while (1) {
          ;
      }
  }
  
  void print_sha256 (const uint8_t *image_hash, const char *label)
  {
      char hash_print[HASH_LEN * 2 + 1];
      hash_print[HASH_LEN * 2] = 0;
      for (int i = 0; i &lt; HASH_LEN; ++i) {
          sprintf(&amp;hash_print[i * 2], "%02x", image_hash[i]);
      }
      ESP_LOGI(TAG, "%s: %s", label, hash_print);
  }
  
  static void ota_example_task(void *pvParameter)
  {
  
      esp_err_t err;
      /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */
      esp_ota_handle_t update_handle = 0 ;
      const esp_partition_t *update_partition = NULL;
  
      ESP_LOGI(TAG, "Starting OTA example...");
  
      const esp_partition_t *configured = esp_ota_get_boot_partition();
      const esp_partition_t *running = esp_ota_get_running_partition();
  
      if (configured != running) {
          ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",
                   configured-&gt;address, running-&gt;address);
          ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)");
      }
      ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
               running-&gt;type, running-&gt;subtype, running-&gt;address);
  
      /* Wait for the callback to set the CONNECTED_BIT in the
         event group.
      */
      xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                          false, true, portMAX_DELAY);
      ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to Server....");
  
      esp_http_client_config_t config = {
          .url = SERVER_URL,
          // .cert_pem = (char *)server_cert_pem_start,
      };
      esp_http_client_handle_t client = esp_http_client_init(&amp;config);
      if (client == NULL) {
          ESP_LOGE(TAG, "Failed to initialise HTTP connection");
          task_fatal_error();
      }
      err = esp_http_client_open(client, 0);
      if (err != ESP_OK) {
          ESP_LOGE(TAG, "Failed to open HTTP connection: 1");
          esp_http_client_cleanup(client);
          task_fatal_error();
      }
      esp_http_client_fetch_headers(client);
  
      update_partition = esp_ota_get_next_update_partition(NULL);
      ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
               update_partition-&gt;subtype, update_partition-&gt;address);
      assert(update_partition != NULL);
  
      err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &amp;update_handle);
      if (err != ESP_OK) {
          ESP_LOGE(TAG, "esp_ota_begin failed 3");
          http_cleanup(client);
          task_fatal_error();
      }
      ESP_LOGI(TAG, "esp_ota_begin succeeded");
  
      int binary_file_length = 0;
      /*deal with all receive packet*/
      while (1) {
          int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);
          if (data_read &lt; 0) {
              ESP_LOGE(TAG, "Error: SSL data read error");
              http_cleanup(client);
              task_fatal_error();
          } else if (data_read &gt; 0) {
              err = esp_ota_write( update_handle, (const void *)ota_write_data, data_read);
              if (err != ESP_OK) {
                  http_cleanup(client);
                  task_fatal_error();
              }
              binary_file_length += data_read;
              ESP_LOGD(TAG, "Written image length %d", binary_file_length);
          } else if (data_read == 0) {
              ESP_LOGI(TAG, "Connection closed,all data received");
              break;
          }
      }
      ESP_LOGI(TAG, "Total Write binary data length : %d", binary_file_length);
  
      if (esp_ota_end(update_handle) != ESP_OK) {
          ESP_LOGE(TAG, "esp_ota_end failed!");
          http_cleanup(client);
          task_fatal_error();
      }
  
      if (esp_ota_get_running_partition() == update_partition) {
          ESP_LOGI(TAG, "The current running firmware is same as the firmware just downloaded");
          int i = 0;
          ESP_LOGI(TAG, "When a new firmware is available on the server, press the reset button to download it");
          while(1) {
              ESP_LOGI(TAG, "Waiting for a new firmware ... %d", ++i);
              vTaskDelay(2000 / portTICK_PERIOD_MS);
          }
      }
  
      err = esp_ota_set_boot_partition(update_partition);
      if (err != ESP_OK) {
          ESP_LOGE(TAG, "esp_ota_set_boot_partition failed 2!");
          http_cleanup(client);
          task_fatal_error();
      }
      ESP_LOGI(TAG, "Prepare to restart system!");
      esp_restart();
      return ;
  }
  
  
  void app_main()
  {
  
      // Initialize NVS.
      nvs_flash_init();
          // OTA app partition table has a smaller NVS partition size than the non-OTA
          // partition table. This size mismatch may cause NVS initialization to fail.
          // If this happens, we erase NVS partition and initialize NVS again.
          ESP_ERROR_CHECK(nvs_flash_erase());
          nvs_flash_init();
  
  
      initialise_wifi();
      xTaskCreate(&amp;ota_example_task, "ota_example_task", 8192, NULL, 5, NULL);
  }
  </code></pre>
  
  <p>The http_parser.h: <a href="https://github.com/espressif/esp-idf/tree/master/components/nghttp/port/include" rel="nofollow noreferrer">file</a> </p>
  
  <p>The esp_http_client: <a href="https://github.com/espressif/esp-idf/tree/master/components/esp_http_client/include" rel="nofollow noreferrer">file</a></p>
  
  <p>I don't understand where I'm supposed to define these functions when they are defined in the esp_parser.h file or what I'm supposed to do to not get this error.</p>