1.5.0 build failure with 32-bit mingw

29 views
Skip to first unread message

imacarthur

unread,
Mar 11, 2025, 6:28:26 AMMar 11
to fltk.coredev
All,

I've been running the fltk-1.5 code thorugh some of my older compilers...

First off I did a 64-bit build with an older TDM-gcc: gcc version 5.1.0 (tdm64-1)
That went pretty well and the code seems to be working fine.

Then I tried a 32-bit build, using an older Msys/mingw32 build: gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

That did *not* go so well:

[ 34%] Building CXX object src/CMakeFiles/fltk.dir/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx.obj
In file included from d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:19:0:
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H: In member function 'virtual char* Fl_WinAPI_System_Driver::strdup                                              (const char*)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H:116:52: error: '::_strdup' has not been declared
   char* strdup(const char *s) FL_OVERRIDE { return ::_strdup(s); }
                                                    ^~
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx: In member function 'virtual FILE* Fl_WinAPI_System_Driver::fope                                              n(const char*, const char*)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:224:29: error: '_wfopen' was not declared in this scope
   return _wfopen(wbuf, wbuf1);
                             ^
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx: In member function 'virtual int Fl_WinAPI_System_Driver::execvp                                              (const char*, char* const*)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:240:20: error: '_wexecvp' was not declared in this scope
   _wexecvp(wbuf, ar);   // STR #3040
                    ^
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx: In member function 'virtual int Fl_WinAPI_System_Driver::rename                                              (const char*, const char*)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:299:30: error: '_wrename' was not declared in this scope
   return _wrename(wbuf, wbuf1);
                              ^
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx: In member function 'virtual int Fl_WinAPI_System_Driver::args_t                                              o_utf8(int, char**&)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:333:29: error: '_strdup' was not declared in this scope
         argv[i] = _strdup("");
                             ^
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:337:27: error: '_strdup' was not declared in this scope
       argv[i] = _strdup("");
                           ^
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx: In member function 'virtual const char* Fl_WinAPI_System_Driver                                              ::home_directory_name()':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:1007:14: error: '::strdup' has not been declared
       home = ::strdup(h);
              ^~
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:1012:14: error: '::strdup' has not been declared
       home = ::strdup(h);
              ^~
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:1015:12: error: '::strdup' has not been declared
     home = ::strdup("~/"); // last resort
            ^~
make[2]: *** [src/CMakeFiles/fltk.dir/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx.obj] Error 1
make[1]: *** [src/CMakeFiles/fltk.dir/all] Error 2
make: *** [all] Error 2


And so forth...

As an aside, I looked at the fltk-config that is made (since I use it a lot) and I note that, even though I had the build set to RELEASE, the optim flags are not set (I expected something like -O3 -DNDEBUG for example) and I'm not all that sure the lib was actually built with the release settings either...

imacarthur

unread,
Mar 11, 2025, 6:51:31 AMMar 11
to fltk.coredev

Is it feasible that the new compiler settings are #defining __STRICT_ANSI__ now, or possible _NO_OLDNAMES, where we didn't before?

If __STRICT_ANSI__ were set, the mingw headers I have for this compiler would disable _strdup and _wfopen, for example, that might go some way to explaining this.

Albrecht Schlosser

unread,
Mar 11, 2025, 9:51:39 AMMar 11
to fltkc...@googlegroups.com
On 3/11/25 11:28 Ian wrote:
I've been running the fltk-1.5 code thorugh some of my older compilers...

First off I did a 64-bit build with an older TDM-gcc: gcc version 5.1.0 (tdm64-1)
That went pretty well and the code seems to be working fine.

Great, thanks for testing and feedback.

Then I tried a 32-bit build, using an older Msys/mingw32 build: gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

That did *not* go so well:

[ 34%] Building CXX object src/CMakeFiles/fltk.dir/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx.obj
In file included from d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:19:0:
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H: In member function 'virtual char* Fl_WinAPI_System_Driver::strdup                                              (const char*)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H:116:52: error: '::_strdup' has not been declared
   char* strdup(const char *s) FL_OVERRIDE { return ::_strdup(s); }
                                                    ^~
[... more errors elided ...]


d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx: In member function 'virtual const char* Fl_WinAPI_System_Driver                                              ::home_directory_name()':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:1007:14: error: '::strdup' has not been declared
       home = ::strdup(h);
              ^~

And so forth...

I see the same here.
$ gcc --version
gcc.exe (MinGW.org GCC Build-2) 9.2.0

$ mingw-get ... package list ... shows
mingw32-w32api-dev  5.4.2  The MinGW API for 32-Bit MS-Windows

$ grep -1 '__W32API_.*VERSION' /mingw/include/w32api.h
 *
 *   __W32API_VERSION = 1,000,000 * major + 1,000 * minor + patch
 *
--
 */
#define __W32API_VERSION           5004002L
#define __W32API_MAJOR_VERSION           5
#define __W32API_MINOR_VERSION           4
#define __W32API_PATCHLEVEL              2


The only obvious change I'm aware of in the new master branch (1.5) is that CMake automatically adds '-std=c++11'. I'm not sure what the compiler and/or the MinGW headers do with this setting...


As an aside, I looked at the fltk-config that is made (since I use it a lot) and I note that, even though I had the build set to RELEASE, the optim flags are not set (I expected something like -O3 -DNDEBUG for example) and I'm not all that sure the lib was actually built with the release settings either...

Did you look at the commandline, or where did you get that from? CMake should use the CMAKE_CXX_FLAGS_RELEASE (cache) variable to set the flags. We don't set it automatically in any FLTK specific "...OPTIM" variables (this can be done by the user).

I'll investigate further later...

imacarthur

unread,
Mar 11, 2025, 11:17:58 AMMar 11
to fltk.coredev
On Tuesday, 11 March 2025 at 13:51:39 UTC Albrecht-S wrote:
Then I tried a 32-bit build, using an older Msys/mingw32 build: gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

That did *not* go so well:

[ 34%] Building CXX object src/CMakeFiles/fltk.dir/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx.obj
In file included from d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx:19:0:
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H: In member function 'virtual char* Fl_WinAPI_System_Driver::strdup                                              (const char*)':
d:/Support/fltk-1.5/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H:116:52: error: '::_strdup' has not been declared
   char* strdup(const char *s) FL_OVERRIDE { return ::_strdup(s); }
                                                    ^~
I see the same here.
$ gcc --version gcc.exe (MinGW.org GCC Build-2) 9.2.0

Hmm, OK, I need to do some more tests then, but I could have sworn I tested with mingw gcc-9.2.0 and it worked...
#define __W32API_VERSION 5004002L #define __W32API_MAJOR_VERSION 5 #define __W32API_MINOR_VERSION 4 #define __W32API_PATCHLEVEL 2
OK, my mingw-gcc-6.3.0 setup has this WIN32 API version

#define __W32API_VERSION           5000002L
#define __W32API_MAJOR_VERSION           5
#define __W32API_MINOR_VERSION           0
#define __W32API_PATCHLEVEL              2

So that is older than you have.

 The TDM tools (and I think the mingw64 toolchain) use a different version of the win32 headers, so I guess that accounts for why the "older" TDM compiler worked.
FWIW, the TDM headers have:
#define __W32API_VERSION 3.14
#define __W32API_MAJOR_VERSION 3
#define __W32API_MINOR_VERSION 14
The only obvious change I'm aware of in the new master branch (1.5) is that CMake automatically adds '-std=c++11'. I'm not sure what the compiler and/or the MinGW headers do with this setting...

Looking at the include files (string.h specifically for _strdup) then it looks like it would be setting __STRICT_ANSI__ that would break it. There's a specific check for that in string.h (for the mingw32 header) that is absent from the TBM version of string.h.

I have no idea whether setting  '-std=c++11' might be asserting  __STRICT_ANSI__ but that may be so?


imacarthur

unread,
Mar 11, 2025, 11:29:27 AMMar 11
to fltk.coredev
On Tuesday, 11 March 2025 at 15:17:58 UTC imacarthur wrote:


I have no idea whether setting  '-std=c++11' might be asserting  __STRICT_ANSI__ but that may be so?



Hmmm, an old discussion, starting here:   https://gcc.gnu.org/legacy-ml/gcc-help/2020-01/msg00079.html

That suggests that this is so, and that it breaks mingw32 (but not, say, Linux) builds in what sounds like similar circumstances to ours... (Though it also maybe sounds like the gcc maintainers are thinking of breaking linux builds too...)
Dunno if we can undef __STRICT_ANSI__ to make it work, or something...



 

imacarthur

unread,
Mar 11, 2025, 11:40:12 AMMar 11
to fltk.coredev
And apparently if we go for "-std=gnu++11" instead, it will work, becuase that sets c++11 syntax but allows the gnu extensions.

I have not tried this!

imacarthur

unread,
Mar 11, 2025, 11:51:56 AMMar 11
to fltk.coredev
On Tuesday, 11 March 2025 at 15:40:12 UTC imacarthur wrote:
And apparently if we go for "-std=gnu++11" instead, it will work, because that sets c++11 syntax but allows the gnu extensions.

I have not tried this!

I've tried it now.
Didn't work...

BUT: setting -U__STRICT_ANSI__ on the CFLAGS and CXXFLAGS does appear to work.

So, in may last build, I added "-std=gnu++11" only to the CXXFLGS (which did not work) then I ALSO added "-U__STRICT_ANSI__" to the CXXFLAGS and to the CFLAGS and the build seems to have worked.

Not pretty, but at least I have a working build now!

Albrecht Schlosser

unread,
Mar 11, 2025, 3:28:39 PMMar 11
to fltkc...@googlegroups.com
On 3/11/25 16:51 imacarthur wrote:
On Tuesday, 11 March 2025 at 15:40:12 UTC imacarthur wrote:
And apparently if we go for "-std=gnu++11" instead, it will work, because that sets c++11 syntax but allows the gnu extensions.

I've tried it now.
Didn't work...

BUT: setting -U__STRICT_ANSI__ on the CFLAGS and CXXFLAGS does appear to work.

So, in may last build, I added "-std=gnu++11" only to the CXXFLGS (which did not work) then I ALSO added "-U__STRICT_ANSI__" to the CXXFLAGS and to the CFLAGS and the build seems to have worked.

Not pretty, but at least I have a working build now!

OK, thanks for testing and reporting this. Short history of setting C++ standard options in 1.5:

Matt added to CMakeLists.txt in commit 3068c7a0af0afbad572f88e074235853fd8be34c:
  set(CMAKE_CXX_STANDARD 11)
  set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

This sets '-std=c++11' unconditionally (at least C++11) - or maybe '-std=gnu++11' (?). This is maybe not finally defined...

Later, in commit 42a04c064d4b31c3a85210311f3ada163c406a25, I changed these commands to:
if(NOT DEFINED CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 11)
endif()

if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
  set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
endif()

if(NOT DEFINED CMAKE_CXX_EXTENSIONS)
  set(CMAKE_CXX_EXTENSIONS OFF)
endif()

The intention was (and still is):

(A) Disable GNU extensions for better portability.
(B) Enable the (CMake) user to set their own options.

As it seems now, (A) causes the issue we are seeing.

But fortunately (B) can be used to override it, and for me the commands below work with my MinGW installation.

Can you please test whether this works for you as well?

```
cd /path/to/fltk-root
cmake . -B temp -G "Unix Makefiles" \
  -D CMAKE_BUILD_TYPE=Release \
  -D CMAKE_CXX_EXTENSIONS=ON \          # THIS is needed !
  -D CMAKE_EXE_LINKER_FLAGS_INIT='-static-libgcc -static-libstdc++'

cd temp
make -j4 # modify this as you like/need
```

Works well and issues only one warning (which I didn't see before), but that's a different story.
The demo programs can be executed from the Windows Explorer, i.e. there are no MinGW dependencies.

So, what did we learn? Using MinGW we may need to use GNU extensions but that's not the case when using MSYS2/MinGW-w64. This needs further investigation...


BTW: optimization options are included for this "Release" build:

[100%] Building CXX object test/CMakeFiles/hello.dir/hello.cxx.obj
cd C:/git/fltk/master/build/temp/test && C:/MinGW/bin/c++.exe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -Dhello_EXPORTS @CMakeFiles/hello.dir/includes_CXX.rsp -O3 -DNDEBUG -std=gnu++11 -MD -MT test/CMakeFiles/hello.dir/hello.cxx.obj -MF CMakeFiles/hello.dir/hello.cxx.obj.d -o CMakeFiles/hello.dir/hello.cxx.obj -c C:/git/fltk/master/test/hello.cxx

imacarthur

unread,
Mar 12, 2025, 1:02:29 PMMar 12
to fltk.coredev
On Tuesday, 11 March 2025 at 19:28:39 UTC Albrecht-S wrote:

Can you please test whether this works for you as well?

```
cd /path/to/fltk-root cmake . -B temp -G "Unix Makefiles" \ -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_CXX_EXTENSIONS=ON \ # THIS is needed ! -D CMAKE_EXE_LINKER_FLAGS_INIT='-static-libgcc -static-libstdc++' cd temp make -j4 # modify this as you like/need ```

OK, so I tested with:

cmake -G "MSYS Makefiles" -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_EXTENSIONS=ON -D CMAKE_EXE_LINKER_FLAGS_INIT='-static-libgcc -static-libstdc++' ..

And that created a build that works OK.
The CMAKE_CXX_EXTENSIONS=ON must be working, as I see in the compiler command I get (amongst others!)    -O3 -DNDEBUG -std=gnu++11
Whereas before I was getting -std=c++11

I note that neither CMAKE_CXX_EXTENSIONS nor CMAKE_EXE_LINKER_FLAGS_INIT seem to be settable from the cmake-gui, which is a nuisance since I use that quite a lot... Oh well.


So, what did we learn? Using MinGW we may need to use GNU extensions but that's not the case when using MSYS2/MinGW-w64. This needs further investigation...

As far as I can tell, this is because the mingw32 folks and the mingw64 folks use different win32api header files. The mingw32 ones seem to be making some effort to be std compliant, the mingw64 versions perhaps less so.
 


BTW: optimization options are included for this "Release" build:

[100%] Building CXX object test/CMakeFiles/hello.dir/hello.cxx.obj
cd C:/git/fltk/master/build/temp/test && C:/MinGW/bin/c++.exe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -Dhello_EXPORTS @CMakeFiles/hello.dir/includes_CXX.rsp -O3 -DNDEBUG -std=gnu++11 -MD -MT test/CMakeFiles/hello.dir/hello.cxx.obj -MF CMakeFiles/hello.dir/hello.cxx.obj.d -o CMakeFiles/hello.dir/hello.cxx.obj -c C:/git/fltk/master/test/hello.cxx

Yes, OK I see that too.

What I really meant was that fltk-config is maybe awry?
e.g.:
$ fltk-config --help
    :
        [--optim]         return compiler optimization used to compile FLTK
    :

Then if I do  fltk-config --optim it returns empty...

 But that is perhaps because I was setting the build type to release in the cmake-gui.
Turns out that if I set the mode to release from the command line, I get:

$ fltk-config --optim
-O3 -Wall -Wunused -Wno-format-y2k -fno-exceptions -fno-strict-aliasing -ffunction-sections -fdata-sections

Which IS what I wanted!

Albrecht Schlosser

unread,
Mar 12, 2025, 6:10:49 PMMar 12
to fltkc...@googlegroups.com
On 3/12/25 18:02 imacarthur wrote:
On Tuesday, 11 March 2025 at 19:28:39 UTC Albrecht-S wrote:

Can you please test whether this works for you as well?

```
cd /path/to/fltk-root cmake . -B temp -G "Unix Makefiles" \ -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_CXX_EXTENSIONS=ON \ # THIS is needed ! -D CMAKE_EXE_LINKER_FLAGS_INIT='-static-libgcc -static-libstdc++' cd temp make -j4 # modify this as you like/need ```

OK, so I tested with:

cmake -G "MSYS Makefiles" -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_EXTENSIONS=ON -D CMAKE_EXE_LINKER_FLAGS_INIT='-static-libgcc -static-libstdc++' ..

And that created a build that works OK.
The CMAKE_CXX_EXTENSIONS=ON must be working, as I see in the compiler command I get (amongst others!)    -O3 -DNDEBUG -std=gnu++11
Whereas before I was getting -std=c++11

Great, thanks, that's what I wanted to achieve.


I note that neither CMAKE_CXX_EXTENSIONS nor CMAKE_EXE_LINKER_FLAGS_INIT seem to be settable from the cmake-gui, which is a nuisance since I use that quite a lot... Oh well.

(1) CMAKE_CXX_EXTENSIONS: I did not yet find out how this is set/implemented within CMake. I don't see it as a CMake cache variable and wonder how this can be changed. This is true for all CMAKE_CXX_STANDARD related settings as well, it's not obvious how they can be changed after the initial configure pass. In this point I agree with your statement above.

(2) CMAKE_EXE_LINKER_FLAGS_INIT: the suffix '_INIT' is a CMake convention that this particular parameter (cache variable) without '_CACHE' will be set only in the very first run of CMake, before CMake applies compiler or platform related additional settings. If you want to change it in cmake-gui, just change CMAKE_EXE_LINKER_FLAGS or the built type related variables like CMAKE_EXE_LINKER_FLAGS_DEBUG or CMAKE_EXE_LINKER_FLAGS_RELEASE. This part is documented (in CMake) and shouldn't be an issue.


So, what did we learn? Using MinGW we may need to use GNU extensions but that's not the case when using MSYS2/MinGW-w64. This needs further investigation...

As far as I can tell, this is because the mingw32 folks and the mingw64 folks use different win32api header files. The mingw32 ones seem to be making some effort to be std compliant, the mingw64 versions perhaps less so.

Yes, this may be true.

Other than that I got the impression that the "classic" MinGW is no longer maintained actively. I can still run `mingw-get` (w/o arguments, i.e. the UI tool) or the commandline version `mingw-get ... update` etc. but I didn't see any updates for a while. According to wikipedia the current web site is https://osdn.net/projects/mingw/ but this doesn't seem to be maintained, it has several  issues. Whatever I do, I only see the same non-functional site, something like an index, but no link works. I remember that I tried to dig deeper but then I found missing (invalid) certs and whatever.

Ian, do you know more about current MinGW updates/downloads/infos etc.? I think you're actively using it, but where do you get updates (or a new installation) from?


BTW: optimization options are included for this "Release" build:

[100%] Building CXX object test/CMakeFiles/hello.dir/hello.cxx.obj
cd C:/git/fltk/master/build/temp/test && C:/MinGW/bin/c++.exe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -Dhello_EXPORTS @CMakeFiles/hello.dir/includes_CXX.rsp -O3 -DNDEBUG -std=gnu++11 -MD -MT test/CMakeFiles/hello.dir/hello.cxx.obj -MF CMakeFiles/hello.dir/hello.cxx.obj.d -o CMakeFiles/hello.dir/hello.cxx.obj -c C:/git/fltk/master/test/hello.cxx

Yes, OK I see that too.

What I really meant was that fltk-config is maybe awry?
e.g.:
$ fltk-config --help
    :
        [--optim]         return compiler optimization used to compile FLTK
    :

Then if I do  fltk-config --optim it returns empty...

 But that is perhaps because I was setting the build type to release in the cmake-gui.
Turns out that if I set the mode to release from the command line, I get:

$ fltk-config --optim
-O3 -Wall -Wunused -Wno-format-y2k -fno-exceptions -fno-strict-aliasing -ffunction-sections -fdata-sections

Which IS what I wanted!

... but I don't know why this is so, if it was not caused by anything else. Keep in mind that the commandline can be applied multiple times and that parameters are cached in the CMake cache. This can sometimes be confusing.

That said, I'm aware that there's a long-standing issue with 'optim' flags in the new CMake build vs. old configure builds.

The problem with CMake is that it has some so-called multi-config generators. In such generators there's not *one* setting for optimization but there are typically four (or more, or less) different settings related to the different build types of the IDE. This is not only true for Visual Studio but for all IDE's and Ninja that have a mulit-config generator. Which optimization settings should be applied to fltk-config? I don't know.

Currently there is partial support for FLTK_OPTION_OPTIM but I can't tell (off the top of my head) where it is actually applied and whether you'll find its value in the generated fltk-config file. As I wrote, it's a long-standing issue and not really resolved yet. Before we can actually implement it we need to define how optimization settings should be applied - and how they would affect the generated fltk-config script...

Note that `FLTK_OPTION_OPTIM` is currently documented in README.CMake.txt but this does NOT clearly define how it is applied:

```
FLTK_OPTION_OPTIM - default EMPTY
    Extra optimization flags for the C and C++ compilers, for instance
    "-Wall -Wno-deprecated-declarations". Example:
    cmake -D FLTK_BUILD_EXAMPLES=on -D FLTK_OPTION_OPTIM="-Wall -Wextra -pedantic" ..
```

I see that it is implemented "somehow" by means of add_definitions() - which is deprecated and marked with FIXME:
```
# *FIXME* add_definitions()
add_definitions(${FLTK_OPTION_OPTIM})
```

Explanation: although this works for building the FLTK library (this is a global or directory option applied to all libs and executables subsequently built) these settings are not automatically "exported" to user projects that use the library - which should be done somehow in the "Modern CMake" approach.

These details need more work, and the first step would (should!) be to define how these options *shall* work w/o forgetting that there are multi-config CMake generators. Finally there are also default CMake options like `CMAKE_CXX_FLAGS` (global) and `CMAKE_CXX_FLAGS_DEBUG`, `CMAKE_CXX_FLAGS_RELEASE` etc. (per config) that are defined by CMake internally (depending on the chosen compiler and platform) and added to the build if - and only if - CMAKE_BUILD_TYPE has been specified (not empty) for a single-config generator like "Unix Makefiles" or added per config in a multi-config generator (e.g. IDE).

Are you now confused? That's intentional.  ;-)  It is confusing.

Suggestions on how to deal with these issues would be appreciated...

Albrecht Schlosser

unread,
Mar 12, 2025, 6:51:53 PMMar 12
to fltkc...@googlegroups.com
Correction:


(2) CMAKE_EXE_LINKER_FLAGS_INIT: the suffix '_INIT' is a CMake convention that this particular parameter (cache variable) without '_CACHE' will be set only in the very first run of CMake, before CMake applies compiler or platform related additional settings.

should read:

(2) CMAKE_EXE_LINKER_FLAGS_INIT: the suffix '_INIT' is a CMake convention that this particular parameter (cache variable) without '_INIT' will be set only in the very first run of CMake, before CMake applies compiler or platform related additional settings.

This implies that CMAKE_EXE_LINKER_FLAGS_INIT sets CMAKE_EXE_LINKER_FLAGS in the first CMake execution but is ignored in subsequent executions on the same build tree. Actually the docs say: "This variable is meant to be set by a toolchain file."

Albrecht Schlosser

unread,
Mar 13, 2025, 2:11:46 PMMar 13
to fltkc...@googlegroups.com
On 3/12/25 23:10 'Albrecht Schlosser' wrote:
On 3/12/25 18:02 imacarthur wrote:
... I tested with:

cmake -G "MSYS Makefiles" -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_EXTENSIONS=ON -D CMAKE_EXE_LINKER_FLAGS_INIT='-static-libgcc -static-libstdc++' ..
...
I note that neither CMAKE_CXX_EXTENSIONS nor CMAKE_EXE_LINKER_FLAGS_INIT seem to be settable from the cmake-gui, which is a nuisance since I use that quite a lot... Oh well.

(1) CMAKE_CXX_EXTENSIONS: I did not yet find out how this is set/implemented within CMake. I don't see it as a CMake cache variable and wonder how this can be changed. This is true for all CMAKE_CXX_STANDARD related settings as well, it's not obvious how they can be changed after the initial configure pass. In this point I agree with your statement above.

I investigated how to set CMAKE_CXX_EXTENSIONS, and the result is that it seems to be handled internally by CMake as a non-cache variable by default. But this doesn't mean that you can't set and change it by using cmake-gui. You can always define your own variable and set its value in the GUI, and it will be used throughout the configure, generate, and finally the build process.

To simplify this for the "standard user" I decided to set these C++ standard related variables in the cache, but beware: it *may* be possible that this must be reverted for better interoperation if FLTK is included as a subproject.

No matter if these variables are cached or not, I also added their values to the configuration summary at the end of the CMake configure pass:
-- Use std::                      Yes - obsolete: always enabled since FLTK 1.5.0
-- CMAKE_CXX_STANDARD             11
-- CMAKE_CXX_STANDARD_REQUIRED    Yes
-- CMAKE_CXX_EXTENSIONS           No

I decided to use the raw CMake variable names so users can easily find them in the cache and change them.

Note: I did not change the default value for MinGW because I can't distinguish MinGW and MSYS2/MinGW-w64 builds (unfortunately both set `MINGW` and `MSYS`). Otherwise I could have set a different default value - I left it `OFF` for better portability, as written before.

If you set up a new MinGW build, the recommended method is to specify `-D CMAKE_CXX_EXTENSIONS=ON` on the commandline. If you "forgot" it you can still change it in cmake-gui. The other two variables are set as shown above (but you can change them or specify them on the commandline).

This is all still in development and needs documentation, but I'm waiting until it's finally decided how to proceed.

Related change: I found a way to set a build property that the required C++ standard (as set by the FLTK build) is inherited by consumers of the library, see commit log:
```
commit c18c39071a4dc0ace4fc5e23c61f3aa7ddd8c679
Author: Albrecht Schlosser
Date:   Thu Mar 13 17:58:26 2025 +0100

    CMake: improve setting C++ standard and configuration summary

    CMake/fl_add_library.cmake: set target_compile_features(.. cxx_std_NN)
      which is inherited by consumers of the library.
      This prevents CMake user projects from failing if they would
      otherwise compile with an older C++ standard.
    ...
```

I hope this helps, feedback would be appreciated.

imacarthur

unread,
Mar 14, 2025, 7:07:51 AMMar 14
to fltk.coredev
On Thursday, 13 March 2025 at 18:11:46 UTC Albrecht-S wrote:

I investigated how to set CMAKE_CXX_EXTENSIONS, and the result is that it seems to be handled internally by CMake as a non-cache variable by default. But this doesn't mean that you can't set and change it by using cmake-gui. You can always define your own variable and set its value in the GUI, and it will be used throughout the configure, generate, and finally the build process.

To simplify this for the "standard user" I decided to set these C++ standard related variables in the cache, but beware: it *may* be possible that this must be reverted for better interoperation if FLTK is included as a subproject.

OK - I think this works. To test, I did a clean configure where I did not set any of the "special things" on the command line, then set them all in the cmake-gui (CMAKE_CXX_EXTENSIONS et al now show up there) and did the build. 
This worked and the result was as intended.

 

No matter if these variables are cached or not, I also added their values to the configuration summary at the end of the CMake configure pass:
-- Use std:: Yes - obsolete: always enabled since FLTK 1.5.0 -- CMAKE_CXX_STANDARD 11 -- CMAKE_CXX_STANDARD_REQUIRED Yes -- CMAKE_CXX_EXTENSIONS No I decided to use the raw CMake variable names so users can easily find them in the cache and change them.

This seems reasonable to me.
It's a pity we'll have to set CMAKE_CXX_EXTENSIONS "manually" each time, but so long as we know, all is fine!
 

Note: I did not change the default value for MinGW because I can't distinguish MinGW and MSYS2/MinGW-w64 builds (unfortunately both set `MINGW` and `MSYS`). Otherwise I could have set a different default value - I left it `OFF` for better portability, as written before.

FWIW, at least in the Msys / Msys2 shells I can test the value of MSYSTEM and I see either of :

$ echo $MSYSTEM
MINGW32

vs:

$ echo $MSYSTEM
MINGW64

So that might be a way to tell? I'm not sure how widely supported that flag is, and presumably only works in an Msys-based shell anyway...


As regards what fltk-config ought to return for the "--optim" flags, I'd imagine that (for non-multi-config cases) it might just return whatever the current target settings are.
That would at least be (somewhat) consistent with what the fltk-config --help says:
           [--optim]         return compiler optimization used to compile FLTK

For the multi-config cases... maybe the "release" mode flags?
Not sure. I _imagine_ that's what folks would want if they were just using the lib, and if they were doing some debug or etc. they'd likely be overriding the defaults anyway?

Albrecht Schlosser

unread,
Mar 15, 2025, 7:40:12 PMMar 15
to fltkc...@googlegroups.com
On 3/14/25 12:07 imacarthur wrote:
On Thursday, 13 March 2025 at 18:11:46 UTC Albrecht-S wrote:

No matter if these variables are cached or not, I also added their values to the configuration summary at the end of the CMake configure pass:
-- Use std:: Yes - obsolete: always enabled since FLTK 1.5.0 -- CMAKE_CXX_STANDARD 11 -- CMAKE_CXX_STANDARD_REQUIRED Yes -- CMAKE_CXX_EXTENSIONS No I decided to use the raw CMake variable names so users can easily find them in the cache and change them.

This seems reasonable to me.
It's a pity we'll have to set CMAKE_CXX_EXTENSIONS "manually" each time, but so long as we know, all is fine!
 
Note: I did not change the default value for MinGW because I can't distinguish MinGW and MSYS2/MinGW-w64 builds (unfortunately both set `MINGW` and `MSYS`). Otherwise I could have set a different default value - I left it `OFF` for better portability, as written before.

FWIW, at least in the Msys / Msys2 shells I can test the value of MSYSTEM and I see either of :

$ echo $MSYSTEM
MINGW32

vs:

$ echo $MSYSTEM
MINGW64

So that might be a way to tell? I'm not sure how widely supported that flag is, and presumably only works in an Msys-based shell anyway...

CMake can query environment variables, hence we ought to be able to use this. I'll try to check this soon.


As regards what fltk-config ought to return for the "--optim" flags, I'd imagine that (for non-multi-config cases) it might just return whatever the current target settings are.
That would at least be (somewhat) consistent with what the fltk-config --help says:
           [--optim]         return compiler optimization used to compile FLTK

For the multi-config cases... maybe the "release" mode flags?
Not sure. I _imagine_ that's what folks would want if they were just using the lib, and if they were doing some debug or etc. they'd likely be overriding the defaults anyway?

Something along that line. Good points, thanks for your input, I'll think about it...

Reply all
Reply to author
Forward
0 new messages