PlatformIO Community

Error: ld returned 1 exit status

Hello,
My problem is this error.
I tried to fix it, but unfortunately i couldn’t because I don’t know exactly what the problem is

This is the error code:

.pio\build\esp32dev\src\web_control.cpp.o:(.literal._Z14httpClockSetupv+0x34): undefined reference to `webServer'
.pio\build\esp32dev\src\web_server.cpp.o:(.literal._Z7httpLogv+0x8): undefined reference to `webServer'
.pio\build\esp32dev\src\web_server.cpp.o:(.literal._Z16handleWebRequestv+0x8): undefined reference to `webServer'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\esp32dev\firmware.elf] Error 1

It seems like only web_control.cpp and web_server.cpp are affected so I’ll put the code too.

web_control.cpp:

#include "web_control.h"
#include "filesys.h"
#include "citylist.h"
#include "main.h"
#include "config.h"
#include <listObj.h>

void httpClockSetup();

void httpClockSetupSave();

void httpClockSetup() {
#ifdef WIFIDEBUG
    Serial.println("Handle Clock Setup");
#endif

    char tempstr[1024 * 3];  //Is that enough? How big is the stack actually???
    char tmp2[1024];  //Is that enough? How big is the stack actually???
    uint16_t citycnt = 0;

    snprintf(tempstr, sizeof(tempstr),
             "<!DOCTYPE html>\
   <title>LED Clock Setup</title>\
   <meta name=\"viewport\" content=\"initial-scale=1.0\">\
   <link rel=\"stylesheet\" href=\"pure-min.css\">\
  <form action=\"/saveledsetup\" class=\"pure-form pure-form-aligned\">\
  <fieldset>\
   <div class=\"pure-control-group\">\
    <label for=\"city\">City</label>\
       <select name=\"city\">");

#ifdef WIFIDEBUG
    Serial.println("Inserting City List");
#endif
    while (cities[citycnt].latitude != 0) {
        snprintf(tmp2, 1024, "<option value=\"%d\">%s</option>", citycnt, cities[citycnt].cityname);
        strncat(tempstr, tmp2, 2048);
        citycnt++;
        yield();
    }

    snprintf(tmp2, 1024,
             "</select>\
   <div class=\"pure-control-group\">\
    <label for=\"bday\">Brightness Day [%%]</label>\
    <input name=\"bday\" id=\"bday\" type=\"number\" min=\"005\" max=\"100\" required placeholder=\"80\">\
   </div>\
   <div class=\"pure-control-group\">\
    <label for=\"bnight\">Brightness Night [%%]</label>\
    <input name=\"bnight\" id=\"bnight\" type=\"number\" min=\"005\" max=\"100\" required placeholder=\"15\">\
   </div>\
   <div class=\"pure-control-group\">\
    <label for=\"ntpupd\">NTP Update Interval [min]</label>\
    <input name=\"ntpupd\" id=\"ntpupd\" type=\"number\" min=\"0001\" max=\"1440\" required placeholder=\"15\">\
   </div>\
   <div class=\"pure-control-group\">\
    <input type=\"submit\" value=\"Save\">\
   </div>\
</fieldset>\
</form>");
    strncat(tempstr, tmp2, 2048);

#ifdef WIFIDEBUG
    Serial.println("Serving Clock Setup Page");
    Serial.println(tempstr);
    Serial.println("");
#endif
    webServer.send(200, "text/html", tempstr);
}

void httpClockSetupSave() {
    config_t *pConfig = get_config_ptr();
    logline << webServer.client().remoteIP() << " connect ";
    appendLog();
    for (int ii = 0; ii < webServer.args(); ii++) {
        logline << ' ' << webServer.argName(ii) << ':' << webServer.arg(ii);
    }
    appendLog();

    //Store Values sent from Webpage
    pConfig->city_index = atoi(webServer.arg("city").c_str());
    pConfig->day_brightness = atoi(webServer.arg("bday").c_str());
    pConfig->night_brightness = atoi(webServer.arg("bnight").c_str());
    pConfig->NTP_Sync_interval = atoi(webServer.arg("ntpupd").c_str());

#ifdef WIFIDEBUG
    Serial.println("Saving Clock Config");
#endif
    save_config();
}

void register_Setup_pages() {
    webServer.on("/", httpClockSetup);
    webServer.on("/saveledsetup", httpClockSetupSave);
}

web_server:

#include <Arduino.h>
#include "web_server.h"
#include "filesys.h"
#include "main.h"

bool loadFromSpiffs(String path);

void httpDefault();

void handleWebRequest();

void httpPureCss();

void httpLogDelete();

bool loadFromSpiffs(String path) {
    String dataType = "text/plain";
    if (path.endsWith("/")) path += "index.htm";

    if (path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
    else if (path.endsWith(".html")) dataType = "text/html";
    else if (path.endsWith(".htm")) dataType = "text/html";
    else if (path.endsWith(".css")) dataType = "text/css";
    else if (path.endsWith(".js")) dataType = "application/javascript";
    else if (path.endsWith(".png")) dataType = "image/png";
    else if (path.endsWith(".gif")) dataType = "image/gif";
    else if (path.endsWith(".jpg")) dataType = "image/jpeg";
    else if (path.endsWith(".ico")) dataType = "image/x-icon";
    else if (path.endsWith(".xml")) dataType = "text/xml";
    else if (path.endsWith(".pdf")) dataType = "application/pdf";
    else if (path.endsWith(".zip")) dataType = "application/zip";
    File dataFile = SPIFFS.open(path.c_str(), "r");
    if (!dataFile) {
        path += ".gz";
        File file = SPIFFS.open(path.c_str(), "r");
        if (!file) {
            return false;
        }
    }
    if (webServer.hasArg("download")) dataType = "application/oclet-stream";

#ifdef WIFIDEBUG
    Serial.print("XMit File: ");
    Serial.print(path);
    Serial.print(" Type: ");
    Serial.print(dataType);
#endif
    if (webServer.streamFile(dataFile, dataType) != dataFile.size()) {
#ifdef WIFIDEBUG
        Serial.println("XMit File Size Missmatch");
#endif
    }

    dataFile.close();
    return true;
}

void httpLog() {
    logline << webServer.client().remoteIP() << " log";
    appendLog();
    logfile.seek(0, SeekSet);
    webServer.streamFile(logfile, "text/plain");
    logfile.seek(0, SeekEnd);
}

void httpLogDelete() {
    logfile.close();
    SPIFFS.remove("/log.txt");
    logfile = SPIFFS.open("/log.txt", "a+");
    logline << webServer.client().remoteIP() << "NEW LOG";
    appendLog();
}

void httpDefault() {
    logline << webServer.client().remoteIP() << " redirect";
    appendLog();
    webServer.sendHeader("Location", "http://WifiLogin.lan", true);
    webServer.send(302, "text/plain", "");
    webServer.client().stop();
}

void httpHome() {
    /*if (server.hostHeader() != String("WifiLogin.lan")) {
        return httpDefault();
    }*/
    logline << webServer.client().remoteIP() << " home";
    appendLog();
    File file = SPIFFS.open("/index.htm.gz", "r");
    //Handle file not existing....
    if (file) {
        webServer.streamFile(file, "text/html");
    } else {
        File file = SPIFFS.open("/index.htm.", "r");
        if (file) {
            webServer.streamFile(file, "text/html");
        } else {
            logline << webServer.client().remoteIP() << " missing index.htm";
            appendLog();
            handleWebRequest();
        }
    }
    file.close();
}

void httpPureCSS() {
    File file = SPIFFS.open("/pure-min.css.gz", "r");
    webServer.streamFile(file, "text/css");
    file.close();
}

void handleWebRequest() {
    if (loadFromSpiffs(webServer.uri())) return;

    String message = "File Not Detected\n\n";
    message += "URI: ";
    message += webServer.uri();
    message += "\nMethod: ";
    message += (webServer.method() == HTTP_GET) ? "GET" : "POST";
    message += "\nArguments: ";
    message += webServer.args();
    message += "\n";
    for (uint8_t i = 0; i < webServer.args(); i++) {
        message += " NAME:" + webServer.argName(i) + "\n VALUE:" + webServer.arg(i) + "\n";
    }
    webServer.send(404, "text/plain", message);
#ifdef WIFIDEBUG
    Serial.println(message);
#endif
}

void webserver_init() {
#ifdef WIFIDEBUG
    Serial.println("Registering WebServer Callbacks");
#endif
    webServer.on("/hotspot-detect.html", httpHome);
    webServer.on("/log.txt", httpLog);
    webServer.on("/log.delete", httpLogDelete);
    webServer.onNotFound(handleWebRequest);
#ifndef WIFIDEBUG
    Serial.println("Starting Server");
#endif
    webServer.begin();
}

Thank you very much in advance! :smiley:

Where do you declare and where do you define the webServer object? The error message says there is no such object defined in the code (but maybe declared with extern).

That object has to be created in a .cpp file somewhere.

Hey,
I declared it with extern in the main.h file and this file is included in both of the cpp files

Okay then you declared it but missed to define the object.

Just write

<type> webServer;

after the list of #includes in one of the .cpp files, where <type> is the actual type / class name of that thing.

Yeah i fixed it
My problem was that webServer was not declared correctly in the main.cpp file. I named it server instead of webServer