Search code examples
c++buildstatic-librarieswxwidgets

wxWidgets setup with mingw64 and vscode


I have tried everything from wxWiki to chatGPT and nothing solves my issue, please note that I do not need an alternative solution, and want to understand what I am missing in this implementation.

Steps I followed,

  • Step 1: Install mingw64 on my windows 11 x64 processor using mingw-builds-binaries. I chose the Release of 13.2.0-rt_v11-rev1 x86_64-13.2.0-release-win32-seh-ucrt-rt_v11-rev1.7z build.

  • Step2: Create project folder myWxProject [%project%], %project%/libs/wxWidgets [%wxWidgets%].

  • Step 3: Download the wxWidgets source files from Windows 7z v3.235. Extract the files into %wxWidgets%.

  • Step 4: Build the files using gcc make by going into %wxWidgets%/build/msw/ and running the command mingw32-make -f makefile.gcc BUILD=release SHARED=0 UNICODE=1 please note that even the next option BUILD=debug with the necessary changes to includes still gives the error.

  • Step 5: Add VSCode configurations c_cpp_properties.json to %project%/.vscode/

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}\\libs\\wxWidgets\\include",
                "${workspaceFolder}\\libs\\wxWidgets\\lib\\gcc_lib\\mswu"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "__WXMSW"
            ],
            "intelliSenseMode": "gcc-x64",
            "compilerPath": "C:\\mingw64\\bin\\g++.exe",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

and tasks.json to %project/.vscode/%

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "cpp-build-debug",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g",
                "${file}",
                "-o",
                "${workspaceFolder}\\cpp-build-debug\\${fileBasenameNoExtension}.exe",
                "-I",
                "${workspaceFolder}\\libs/wxWidgets\\include",
                "${workspaceFolder}\\libs/wxWidgets\\lib\\gcc_lib\\mswu",
                "-L",
                "${workspaceFolder}\\libs\\wxWidgets\\lib\\gcc_lib",
                "-lwxbase32u",
                "-lwxmsw32u_core",
                "-lwxmsw32u_adv"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}
// Start of wxWidgets "Hello World" Program
#include <wx/wx.h>
 
class MyApp : public wxApp
{
public:
    bool OnInit() override;
};
 
wxIMPLEMENT_APP(MyApp);
 
class MyFrame : public wxFrame
{
public:
    MyFrame();
 
private:
    void OnHello(wxCommandEvent& event);
    void OnExit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
};
 
enum
{
    ID_Hello = 1
};
 
bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame();
    frame->Show(true);
    return true;
}
 
MyFrame::MyFrame()
    : wxFrame(nullptr, wxID_ANY, "Hello World")
{
    wxMenu *menuFile = new wxMenu;
    menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
                     "Help string shown in status bar for this menu item");
    menuFile->AppendSeparator();
    menuFile->Append(wxID_EXIT);
 
    wxMenu *menuHelp = new wxMenu;
    menuHelp->Append(wxID_ABOUT);
 
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    menuBar->Append(menuHelp, "&Help");
 
    SetMenuBar( menuBar );
 
    CreateStatusBar();
    SetStatusText("Welcome to wxWidgets!");
 
    Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
    Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
    Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}
 
void MyFrame::OnExit(wxCommandEvent& event)
{
    Close(true);
}
 
void MyFrame::OnAbout(wxCommandEvent& event)
{
    wxMessageBox("This is a wxWidgets Hello World example",
                 "About Hello World", wxOK | wxICON_INFORMATION);
}
 
void MyFrame::OnHello(wxCommandEvent& event)
{
    wxLogMessage("Hello world from wxWidgets!");
}
  • Step 7: Finally run the cpp-build-debug task.

Error

In file included from %project%\libs/wxWidgets\include/wx/defs.h:45,
                 from %project%\libs/wxWidgets\include/wx/wx.h:14,
                 from %project%\helloWorld.cpp:2:
%project%\libs/wxWidgets\include/wx/platform.h:159:10: fatal error: wx/setup.h: No such file or directory
  159 | #include "wx/setup.h"
      |          ^~~~~~~~~~~~
compilation terminated.

The things I am sure of: I can ensure that there is a file called setup.h in the directory %wxWidgets%/lib/gcc_lib/mswu/wx/ but even though the folder is in include it does not find it. Something bizzare I had noticed, the extraction of the sources had a folder inside include %wxWidgets%/include/msvc which also contains a wx folder and a setup.h, if I understand it correct from this wiki this file is for the visual studio build setup, hence I will not be using it. I did try everything that came to my mind for the past couple of days and for the life of me could not figure out why it gives me this setup.h error.

I hope this information is enough. I can provide the entire built folder with my project if you want for the exact files in my system, but since its quite large I did not include it right now.

[EDIT] Additional information:

I have the same issue when compiling the minimal program from the samples. This was once again built by gcc-make mingw32-make -f makefile.gcc after navigating into the minimal sample folder.


Solution

  • Quite a lot of issues in the above code including not having -I for all my includes as mentioned by @Xaviou. I want to answer this question in such a way that someone could reproduce a wxWidgets development environment on VSCode.

    Assuming this is your project folder structure and the build files are to be in ./build.

    C:.
    │   App.cpp
    │   App.h
    │   MainFrame.cpp
    │   MainFrame.h
    │
    ├───.vscode
    │       c_cpp_properties.json
    │
    └───build
            App.o
            MainFrame.o
            Makefile
            my_app.exe
    

    First of all we need to populate c_cpp_properties.json (needs the C/C++ extension by Microsoft to work). This step is to avoid one's itelli-sense not go nuts.

    {
        "configurations": [
            {
                "name": "Win32",
                "includePath": [
                    "[your-wxWidgets-folder]\\include\\",
                    "[your-wxWidgets-folder]\\gcc_lib\\mswud\\"
                ],
                "defines": [
                    "_DEBUG",
                    "UNICODE",
                    "_UNICODE"
                ],
                "cStandard": "c17",
                "cppStandard": "gnu++17",
                "intelliSenseMode": "windows-gcc-x64",
                "forcedInclude": [
                    "[your-wxWidgets-folder]\\include\\wx\\wx.h"
                ]
            }
        ],
        "version": 4
    }
    

    The force include was necessary for me since one of the extension I installed took precedence over the files in the include directly.

    Now VSCode intelli-sense would not complain if you include a header. For building a file, I switched to a make file as seen in the tree rather than VSCode tasks but the flags and the libraries will not change either way.

        wxWidgets_install_dir = [your-wxWidgets-folder]
        
        wxWidgets_general_include_dir = $(wxWidgets_install_dir)\\include
        
        wxWidgets_os_specific_includes = $(wxWidgets_install_dir)\\lib\\gcc_lib\\mswud\\
        
        wxWidgets_library_dir = $(wxWidgets_install_dir)\\lib\\gcc_lib\\
        
        wxWidgets_library_includes = -lwxmsw32ud_xrc -lwxmsw32ud_richtext -lwxbase32ud_net -lwxmsw32ud_media -lwxmsw32ud_aui -lwxmsw32ud_ribbon -lwxmsw32ud_html -lwxmsw32ud_adv -lwxbase32ud_xml -lwxmsw32ud_core -lwxbase32ud -lwxscintillad -lwxtiffd -lwxjpegd -lwxpngd -lwxzlibd -lwxregexud -lwxexpatd -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lwsock32 -lodbc32 -lversion -lws2_32 -lwininet -loleacc -luxtheme
        
        
        cc = g++
        wxWidgets_defines = -D_UNICODE -D__WXMSW__ -D_DEBUG
        objects = MainFrame.o App.o
        
        # Rules
        all: my_app
        
        # Compile rules
        %.o: ../%.cpp ../%.h
            $(cc) $(wxWidgets_defines) -c -I"$(wxWidgets_general_include_dir)" -I"$(wxWidgets_os_specific_includes)" -o $@ $<
        
        # Link rule
        my_app: $(objects)
            $(cc) $(wxWidgets_defines) -o my_app $(objects) -L"$(wxWidgets_library_dir)" $(wxWidgets_library_includes)
            
        # Clean rule
        clean:
            del *.o my_app
    

    The order of library includes at least when compiled with mingw-make is really important. And from some page flips of the documentation this seems to be the order for most of the libs in wxWidgets, so use whichever library you want or just include everything if build time is not an issue for you.

    //wxWidgets libs
    -lwxmsw32ud_xrc
    -lwxmsw32ud_richtext
    -lwxbase32ud_net
    -lwxmsw32ud_media
    -lwxmsw32ud_aui
    -lwxmsw32ud_ribbon
    -lwxmsw32ud_html
    -lwxmsw32ud_adv
    -lwxbase32ud_xml
    -lwxmsw32ud_core
    -lwxbase32ud
    -lwxscintillad
    -lwxtiffd
    -lwxjpegd
    -lwxpngd
    -lwxzlibd
    -lwxregexud
    -lwxexpatd
    
    //msw libs
    -lkernel32
    -luser32
    -lgdi32
    -lcomdlg32
    -lwinspool
    -lwinmm
    -lshell32
    -lshlwapi
    -lcomctl32
    -lole32
    -loleaut32
    -luuid
    -lrpcrt4
    -ladvapi32
    -lwsock32
    -lodbc32
    -lversion
    -lws2_32
    -lwininet
    -loleacc
    -luxtheme
    

    Hope this helps, people in the future :) I now switched to cmake and clion for my development since I know whats actually going on in the build process.