Author Topic: wxWidgets project wizard.script for supporting msys2's prebuild wx library  (Read 5249 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6036
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Hi, in my daily work, I used the wx libraries installed by the pacman command under msys2 gcc environment. But our wxWidgets project wizard does not support creating a project for those libraries. I have just modify the wizard.script, and here is the patch file:

Code
diff --git a/wizard.script b/wizard.script
index 679e184..233d284 100644
--- a/wizard.script
+++ b/wizard.script
@@ -51,6 +51,8 @@ GuiAppType <- 1; // Default to Dialog. 0-Dialog, 1-Frame
 AddlLibList <- _T(""); // Contains the complete list
 multi_thread_dynamic <- true; //Default to Multi-thread. For MSVC only.
 
+IsMsys2Lib <- true; // when we are using the header files and libraries from Msys2 installed by pacman
+
 
 function BeginWizard()
 {
@@ -75,17 +77,20 @@ function BeginWizard()
         Wizard.AddProjectPathPage();
         Wizard.AddPage(_T("WxProjDetails"));
         Wizard.AddPage(_T("WxGuiSelect"));
-        if (PLATFORM == PLATFORM_MSW)
+
+
+        // if we are working under the msys2 environment, the header files and lib files are similar to the Unix type
+        if (PLATFORM == PLATFORM_MSW && !IsMsys2Lib)
             Wizard.AddGenericSelectPathPage(_T("WxPath"), wxpath_msg, _("wxWidgets' location:"), _T("$(#wx)"));
 
         // we need the compiler selection before wx settings, because we 'll have
         // to validate the settings. To do this we must know the compiler beforehand...
         Wizard.AddCompilerPage(_T(""), _T("*"), true, true);
-        if (PLATFORM == PLATFORM_MSW)
+        if (PLATFORM == PLATFORM_MSW && !IsMsys2Lib)
             Wizard.AddPage(_T("WxConf")); // only for windows
         else
             Wizard.AddPage(_T("WxConfUnix")); // just PCH option
-        if (PLATFORM == PLATFORM_MSW)
+        if (PLATFORM == PLATFORM_MSW && !IsMsys2Lib)
         {
             Wizard.AddPage(_T("WxConfAdvOpt")); // Wizard page to select target type
             Wizard.AddPage(_T("WxAddLib")); // Add additional wx libraries
@@ -103,17 +108,17 @@ function BeginWizard()
                                               _("Please select the wxWidgets version you want to use."),
                                               _T("wxWidgets 3.0;wxWidgets 3.1;wxWidgets 3.2;wxWidgets 3.3"),
                                               WxVersion); // select wxwidgets version
-        if (PLATFORM == PLATFORM_MSW)
+        if (PLATFORM == PLATFORM_MSW && !IsMsys2Lib)
             Wizard.AddGenericSelectPathPage(_T("WxPath"), wxpath_msg, _("wxWidgets' location:"), _T("$(#wx)"));
 
         // we need the compiler selection before wx settings, because we 'll have
         // to validate the settings. To do this we must know the compiler beforehand...
         Wizard.AddBuildTargetPage(_T(""), false, true, _T(""), _T("*"), true);
-        if (PLATFORM == PLATFORM_MSW)
+        if (PLATFORM == PLATFORM_MSW && !IsMsys2Lib)
             Wizard.AddPage(_T("WxConf")); // only for windows
         else
             Wizard.AddPage(_T("WxConfUnix")); // just PCH option
-        if (PLATFORM == PLATFORM_MSW)
+        if (PLATFORM == PLATFORM_MSW && !IsMsys2Lib)
         {
             Wizard.AddPage(_T("WxConfAdvOpt")); // Wizard page to select target type
             Wizard.AddPage(_T("WxAddLib")); // Add additional wx libraries
@@ -605,12 +610,26 @@ function SetupProject(project)
     local libdir;
     SetupAddlLibs();
     // set project options
-    if (PLATFORM != PLATFORM_MSW)
+    if (PLATFORM != PLATFORM_MSW || IsMsys2Lib)
     {
         if (ChoiceWxUnixLib == 0)
         {
-            project.AddCompilerOption(_T("`wx-config --cflags`"));
-            project.AddLinkerOption(_T("`wx-config --libs`"));
+            if (IsMsys2Lib)
+            {
+                // WX_CONFIG is a Code::Blocks global variable which can be set under
+                // MENU->Settings->Global Variable Editor, e.g. it could be:
+                // wx-config-msys2.exe --prefix=$(TARGET_COMPILER_DIR)
+                // in the above setting, you should supply wx-config-msys2.exe which can be built from
+                // https://github.com/eranif/wx-config-msys2
+                project.AddCompilerOption(_T("`$(#WX_CONFIG) --cflags`"));
+                project.AddLinkerOption(_T("`$(#WX_CONFIG) --libs`"));
+                project.AddResourceCompilerOption(_T("`$(#WX_CONFIG) --rcflags`"));
+            }
+            else
+            {
+                project.AddCompilerOption(_T("`$(#WX_CONFIG) --cflags`"));
+                project.AddLinkerOption(_T("`$(#WX_CONFIG) --libs base,core`"));
+            }
         }
         else
         {
@@ -929,7 +948,7 @@ function SetupTarget(target, is_debug)
         LibDebugSuffix = _T("");
 
     /* For Linux / Mac */
-    if (PLATFORM != PLATFORM_MSW)
+    if (PLATFORM != PLATFORM_MSW || IsMsys2Lib)
     {
         if (ChoiceWxUnixLib == 1)
         {


The patch is very simple, it first add a new variable named "IsMsys2Lib", and by I set it to "true". The wx library supplied by msys2/gcc is using some kinds of Linux format, so I change some code of the wizard.script to follow the condition of the PLATFORM == Unix branch.

To build the generated project, you have to define your global variable named "wx_config".

In my case, it refer to something like below:

Code
wx-config-msys2.exe --prefix=$(TARGET_COMPILER_DIR)

Note that the "wx-config-msys2.exe" can be built from the github repo: https://github.com/eranif/wx-config-msys2  (Thanks eranif)

You can define the "wx_config" to other strings, for example: Re: codeblocks cbp projects for wx samples, in this post, if you would like to use a wx library build you self, you can define the string as:

Code
wx-config.exe --prefix=F:/code/wxWidgets-3.2.1 --wxcfg=gcc_dll/mswu

Note the "wx-config.exe" can also be built from the github repo: https://github.com/eranif/wx-config-msys2

Basically, you have to create a user defined wizard.script file under you C::B's APPDATA folder, usually:
Code
%APPDATA%\CodeBlocks\share\codeblocks\templates\wizard\wxwidgets
If you do not understand where you %APPDATA% locates, you can see this as a reference: wxpbguide/cb/wizard at master PBfordev/wxpbguide (Thanks PB)

See this thread New Variable to support wx-config in MSys2 MinGW to understand how the global variable can be defined and used to support building. (Thanks stahta01)

I have attach the wizard file if you are lazy to apply my patch.  :)

If you have any issue, comments are welcome!
« Last Edit: March 13, 2023, 04:58:11 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Wouldn't it be possible to let the user select if he wants to use a msys installation at the beginning of the wizard with a UI? Like he can select the wx version?
This should probably added for every wizard.... I too prefer the msys way of things nowadays....

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6036
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Wouldn't it be possible to let the user select if he wants to use a msys installation at the beginning of the wizard with a UI? Like he can select the wx version?
Yes, I can do this. wxWidgets library is different from other libraries. For other libraries, they usually use the "pkg-config.exe" to config the include file search and linker options. The "pkg-config.exe" is already in msys2/mingw64/bin, so it is easy. For wxWidgets, I have to use a hack about the "#wx_config".

Quote
This should probably added for every wizard.... I too prefer the msys way of things nowadays....
Yes, many libraries are supplied by msys2, and I hope we can support all of them.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6036
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
This is the v2 of the modified wizard.script.

I add a new option page named wxBuildPlatform where a ChoiceList is used.

Code
        Wizard.AddGenericSingleChoiceListPage(_T("wxBuildPlatform"),
                                              _("Please select the wxWidgets build platform want to use"),
                                              _T("Windows;Windows-MSYS2 or Unix"),
                                              IsMsys2Lib); // select wxwidgets build platform

So that the adding of library pages will mainly depends on the user selection. Some of the code are moving from BeginWizard() to OnLeave_WxGuiSelect(), because those pages are added dynamically depends on the previous user choice.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6036
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
FYI:

I modify the Code::Blocks' opencv project wizard to linking msys2's opencv library(currently, its opencv4)

I put the wizard.script here: https://gist.github.com/asmwarrior/93c3f6f0efa8a826c206446632d856f1

Also, the source code should be updated like below:

Code
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main(int argc, char *argv[])
{
    Mat img = imread("arnold_schwarzenegger.jpg", IMREAD_COLOR);
    if(img.empty())
       return -1;
    namedWindow("arnold_schwarzenegger", WINDOW_AUTOSIZE );
    imshow("arnold_schwarzenegger", img);
    waitKey(0);
    return 0;
}

The IMREAD_COLOR and WINDOW_AUTOSIZE is new options for opencv4. Our old wizard using the opencv2 options.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.