0

I'm trying to convert an SFML application to wxWidgets. I build wxWidgets and ran the minimal sample according to this thread: How to set up wxWidgets 3.1.0 with Visual Studio 2015

It works perfectly when I use Visual Studio with its appropriate solution, but when I try to use the given CMakeLists.txt to generate a solution with CMake, that solution does not work, giving a link error:

error LNK2019: symbole externe non résolu "public: static void __cdecl _WX_LIST_HELPER_wxMenuItemList::DeleteFunction(class wxMenuItem *)" (?DeleteFunction@_WX_LIST_HELPER_wxMenuItemList@@SAXPEAVwxMenuItem@@@Z) référencé dans la fonction "public: __cdecl wxMenuItemList::~wxMenuItemList(void)" (??1wxMenuItemList@@QEAA@XZ)

It should be understandable even in French. I searched everywhere and can't make it work, so here I am asking for your help.

I also tried to compare the properties of both solutions and make them as resemblant as possible, but it still isn't working.

Thank you.

EDIT: It's good to mark as duplicate, but that doesn't explain me why it works with given solution, but not with CMake generated solution, nor what's the difference and how to resolve it.

EDIT2: Here's the CMakeLists.txt:

    #############################################################################
# Name:        samples/minimal/CMakeListst.txt
# Purpose:     Sample CMake file to show usage of cmake for wxWidgets users
# Author:      Tobias Taschner
# Created:     2016-10-23
# Copyright:   (c) 2016 wxWidgets development team
# Licence:     wxWindows licence
#############################################################################

#
# This file is just a sample to show using cmake from an application
# If you want to build the minimal and other samples please use the
# wxBUILD_SAMPLES option when using cmake on the library
#

# Declare the minimum required CMake version
cmake_minimum_required(VERSION 2.8.12)

# Name the project
project(minimal)

# Request the required wxWidgets libs
find_package(wxWidgets 3.1 COMPONENTS core base REQUIRED)

# Include the wxWidgets use file to initialize various settings
include(${wxWidgets_USE_FILE})

# Define a variable containing a list of source files for the project
set(SRC_FILES
    minimal.cpp
    )

# if(WIN32)
#     # Include a RC file for windows
#     list(APPEND SRC_FILES sample.rc)
# elseif(APPLE)
#     # Add an icon for the apple .app file
#     list(APPEND SRC_FILES ../../src/osx/carbon/wxmac.icns)
# endif()

# Define the build target for the executable
add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE ${SRC_FILES})
# Link required libraries to the executable
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})

if(APPLE)
    set_target_properties(${PROJECT_NAME} PROPERTIES
        RESOURCE "../../src/osx/carbon/wxmac.icns"
        MACOSX_BUNDLE_ICON_FILE wxmac.icns
        MACOSX_BUNDLE_COPYRIGHT "Copyright wxWidgets"
        MACOSX_BUNDLE_GUI_IDENTIFIER "org.wxwidgets.minimal"
        )
endif()

and minimal.cpp, the only file:

    /////////////////////////////////////////////////////////////////////////////
// Name:        minimal.cpp
// Purpose:     Minimal wxWidgets sample
// Author:      Julian Smart
// Modified by:
// Created:     04/01/98
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------

// the application icon (under Windows it is in resources and even
// though we could still include the XPM here it would be unused)
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif

// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------

// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
    // override base class virtuals
    // ----------------------------

    // this one is called on application startup and is a good place for the app
    // initialization (doing it here and not in the ctor allows to have an error
    // return: if OnInit() returns false, the application terminates)
    virtual bool OnInit() wxOVERRIDE;
};

// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
    // ctor(s)
    MyFrame(const wxString& title);

    // event handlers (these functions should _not_ be virtual)
    void OnQuit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);

private:
    // any class wishing to process wxWidgets events must use this macro
    wxDECLARE_EVENT_TABLE();
};

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

// IDs for the controls and the menu commands
enum
{
    // menu items
    Minimal_Quit = wxID_EXIT,

    // it is important for the id corresponding to the "About" command to have
    // this standard value as otherwise it won't be handled properly under Mac
    // (where it is special and put into the "Apple" menu)
    Minimal_About = wxID_ABOUT
};

// ----------------------------------------------------------------------------
// event tables and other macros for wxWidgets
// ----------------------------------------------------------------------------

// the event tables connect the wxWidgets events with the functions (event
// handlers) which process them. It can be also done at run-time, but for the
// simple menu events like this the static method is much simpler.
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
EVT_MENU(Minimal_About, MyFrame::OnAbout)
wxEND_EVENT_TABLE()

// Create a new application object: this macro will allow wxWidgets to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also implements the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
wxIMPLEMENT_APP(MyApp);

// ============================================================================
// implementation
// ============================================================================

// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------

// 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
    // call the base class initialization method, currently it only parses a
    // few common command-line options but it could be do more in the future
    if (!wxApp::OnInit())
        return false;

    // create the main application window
    MyFrame *frame = new MyFrame("Minimal wxWidgets App");

    // and show it (the frames, unlike simple controls, are not shown when
    // created initially)
    frame->Show(true);

    // success: wxApp::OnRun() will be called which will enter the main message
    // loop and the application will run. If we returned false here, the
    // application would exit immediately.
    return true;
}

// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------

// frame constructor
MyFrame::MyFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    // set the frame icon
    SetIcon(wxICON(sample));

#if wxUSE_MENUS
    // create a menu bar
    wxMenu *fileMenu = new wxMenu;

    // the "About" item should be in the help menu
    wxMenu *helpMenu = new wxMenu;
    helpMenu->Append(Minimal_About, "&About\tF1", "Show about dialog");

    fileMenu->Append(Minimal_Quit, "E&xit\tAlt-X", "Quit this program");

    // now append the freshly created menu to the menu bar...
    wxMenuBar *menuBar = new wxMenuBar();
    menuBar->Append(fileMenu, "&File");
    menuBar->Append(helpMenu, "&Help");

    // ... and attach this menu bar to the frame
    SetMenuBar(menuBar);
#else // !wxUSE_MENUS
    // If menus are not available add a button to access the about box
    wxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
    wxButton* aboutBtn = new wxButton(this, wxID_ANY, "About...");
    aboutBtn->Bind(wxEVT_BUTTON, &MyFrame::OnAbout, this);
    sizer->Add(aboutBtn, wxSizerFlags().Center());
#endif // wxUSE_MENUS/!wxUSE_MENUS

#if wxUSE_STATUSBAR
    // create a status bar just for fun (by default with 1 pane only)
    CreateStatusBar(2);
    SetStatusText("Welcome to wxWidgets!");
#endif // wxUSE_STATUSBAR
}


// event handlers

void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    // true is to force the frame to close
    Close(true);
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxMessageBox(wxString::Format
    (
        "Welcome to %s!\n"
        "\n"
        "This is the minimal wxWidgets sample\n"
        "running under %s.",
        wxVERSION_STRING,
        wxGetOsDescription()
    ),
        "About wxWidgets minimal sample",
        wxOK | wxICON_INFORMATION,
        this);
}
  • One problem is you have not included the `CMakeLists.txt` in your question. Although even if you do I think it may be too much work to debug this. – drescherjm Dec 30 '18 at 16:20
  • 2
    @πάντα ῥεῖ: I see you like to use duphammer for any question mentioning "undefined referenced", marking as a target that "universal undefined reference" question. That target could be appropriate for the CMake code, which doesn't contain `target_link_libraries` call at all. But if CMake code **does** contain that call, and uses appropriate library in it, that "universal" question actually doesn't help: the problem is most likely **CMake-specific**: from missing some variable/parameter till even a bug in the 3d-party project. Please, do no close such questions without any comment. – Tsyvarev Dec 30 '18 at 17:20
  • @Tsyvarev The original question didn't even show the CMakeLists.txt. Feel free to vote for reopening the question. – πάντα ῥεῖ Dec 30 '18 at 17:22
  • Yes, given question did not contain the code at the moment of closing. But I saw other questions with a code, which has been closed by you. In some cases this was a correct action, but in some other cases - very disputable. Well, know I have duphammer too :), so processing such cases shouldn't be a difficult task. – Tsyvarev Dec 30 '18 at 17:26
  • @Tsyvarev Good thing, we can balance each other ;-) And don't miss the ping next time please. – πάντα ῥεῖ Dec 30 '18 at 17:31
  • @Ryngetsu, why do you want CMake as an intermediate solution? Just use provided MSVC solution and be happy. Keep in mind that CMake support in wxWidgets still have a lot of issues and the problems like this should be reported directly to wx-dev ML. – Igor Dec 30 '18 at 18:34
  • @Igor That would be okay for the minimal sample, but I don't want to run visual studio for my application, I want to use CMake to generate a solution for it. –  Dec 30 '18 at 22:02
  • @Ryngetsu, the official recommended way of starting new project is to copy minimal sample directory and add files to it then recompile. So you don't need CMake 3-level to generate anything. – Igor Dec 31 '18 at 05:08
  • @Igor The thing is that I want my application to be cross-platform, so CMake was the easier way to do this. –  Dec 31 '18 at 08:21
  • @Rynho, minimal sample has Visual Studio projects already. It also has Xcode template and gcc Makefile. You can also use Anjuta on Linux as it does have a template for wxWidgets. Or you can use `wx-config` to build the program on *nix/Mac. In any case the default things is available for you. Moreover, in 3.1.2 there is a MSVC template for starting a new project and I think Vadim wrote something on wxBlog about its usage. – Igor Dec 31 '18 at 14:06

0 Answers0