Merge branch 'cmake-c++11-stl' of git://github.com/MaartenBent/wxWidgets

CMake: Improve STL checks, improve C++17/20 support.

See https://github.com/wxWidgets/wxWidgets/pull/1782

Closes #18718.
This commit is contained in:
Vadim Zeitlin
2020-04-12 16:37:57 +02:00
15 changed files with 66 additions and 56 deletions

View File

@@ -77,20 +77,12 @@ endmacro()
function(wx_set_common_target_properties target_name) function(wx_set_common_target_properties target_name)
cmake_parse_arguments(wxCOMMON_TARGET_PROPS "DEFAULT_WARNINGS" "" "" ${ARGN}) cmake_parse_arguments(wxCOMMON_TARGET_PROPS "DEFAULT_WARNINGS" "" "" ${ARGN})
if(DEFINED wxBUILD_CXX_STANDARD AND NOT wxBUILD_CXX_STANDARD STREQUAL COMPILER_DEFAULT) if(APPLE AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9 AND wxHAS_CXX11)
# TODO: implement for older CMake versions ? if(CMAKE_GENERATOR STREQUAL "Xcode")
set_target_properties(${target_name} PROPERTIES CXX_STANDARD ${wxBUILD_CXX_STANDARD}) set_target_properties(${target_name} PROPERTIES XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY libc++)
if( else()
APPLE AND target_compile_options(${target_name} PUBLIC "-stdlib=libc++")
CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9 AND target_link_libraries(${target_name} PRIVATE "-stdlib=libc++")
(wxBUILD_CXX_STANDARD EQUAL 11 OR wxBUILD_CXX_STANDARD EQUAL 14)
)
if(CMAKE_GENERATOR STREQUAL "Xcode")
set_target_properties(${target_name} PROPERTIES XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY libc++)
else()
target_compile_options(${target_name} PUBLIC "-stdlib=libc++")
target_link_libraries(${target_name} PRIVATE "-stdlib=libc++")
endif()
endif() endif()
endif() endif()
set_target_properties(${target_name} PROPERTIES set_target_properties(${target_name} PROPERTIES

View File

@@ -8,6 +8,15 @@
# Licence: wxWindows licence # Licence: wxWindows licence
############################################################################# #############################################################################
if(DEFINED wxBUILD_CXX_STANDARD AND NOT wxBUILD_CXX_STANDARD STREQUAL COMPILER_DEFAULT)
set(CMAKE_CXX_STANDARD ${wxBUILD_CXX_STANDARD})
endif()
if(NOT CMAKE_CXX_STANDARD EQUAL 98)
set(wxHAS_CXX11 TRUE)
else()
set(wxHAS_CXX11 FALSE)
endif()
if(MSVC) if(MSVC)
# Determine MSVC runtime library flag # Determine MSVC runtime library flag
set(MSVC_LIB_USE "/MD") set(MSVC_LIB_USE "/MD")

View File

@@ -36,15 +36,17 @@ endif()
if(MSVC) if(MSVC)
wx_option(wxBUILD_MSVC_MULTIPROC "Enable multi-processor compilation for MSVC") wx_option(wxBUILD_MSVC_MULTIPROC "Enable multi-processor compilation for MSVC")
else() endif()
# Other compilers support setting the C++ standard, present it an option to the user
if(NOT MSVC OR MSVC_VERSION GREATER 1800)
# support setting the C++ standard, present it an option to the user
if(DEFINED CMAKE_CXX_STANDARD) if(DEFINED CMAKE_CXX_STANDARD)
set(wxCXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD}) set(wxCXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD})
else() else()
set(wxCXX_STANDARD_DEFAULT COMPILER_DEFAULT) set(wxCXX_STANDARD_DEFAULT COMPILER_DEFAULT)
endif() endif()
wx_option(wxBUILD_CXX_STANDARD "C++ standard used to build wxWidgets targets" wx_option(wxBUILD_CXX_STANDARD "C++ standard used to build wxWidgets targets"
${wxCXX_STANDARD_DEFAULT} STRINGS COMPILER_DEFAULT 98 11 14 17) ${wxCXX_STANDARD_DEFAULT} STRINGS COMPILER_DEFAULT 98 11 14 17 20)
endif() endif()
if(WIN32) if(WIN32)

View File

@@ -213,7 +213,7 @@ wx_list_add_prefix(WIDGETS_RC_FILES icons/
stattext.xpm text.xpm timepick.xpm toggle.xpm stattext.xpm text.xpm timepick.xpm toggle.xpm
) )
wx_add_sample(widgets IMPORTANT ${SAMPLE_WIDGETS_SRC} wx_add_sample(widgets IMPORTANT ${SAMPLE_WIDGETS_SRC}
DATA ${WIDGETS_RC_FILES} textctrl.cpp DATA ${WIDGETS_RC_FILES} textctrl.cpp ../image/toucan.png
) )
wx_add_sample(wizard DEPENDS wxUSE_WIZARDDLG) wx_add_sample(wizard DEPENDS wxUSE_WIZARDDLG)
wx_add_sample(wrapsizer) wx_add_sample(wrapsizer)

View File

@@ -23,11 +23,7 @@ include(CheckTypeSize)
include(CMakePushCheckState) include(CMakePushCheckState)
include(TestBigEndian) include(TestBigEndian)
if( if(APPLE AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9 AND wxHAS_CXX11)
APPLE AND
CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9 AND
(CMAKE_CXX_STANDARD EQUAL 11 OR CMAKE_CXX_STANDARD EQUAL 14)
)
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-stdlib=libc++") set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-stdlib=libc++")
endif() endif()
@@ -147,7 +143,7 @@ wx_check_c_source_compiles(
stdio.h stdio.h
) )
#TODO: wxNO_VARIADIC_MACROS #TODO: wxNO_VARIADIC_MACROS
if(wxUSE_STL) if(wxUSE_STL AND NOT wxHAS_CXX11)
wx_check_cxx_source_compiles(" wx_check_cxx_source_compiles("
std::vector<int> moo; std::vector<int> moo;
std::list<int> foo; std::list<int> foo;
@@ -172,6 +168,12 @@ if(wxUSE_STL)
HAVE_STD_STRING_COMPARE HAVE_STD_STRING_COMPARE
string string
) )
wx_check_cxx_source_compiles(
"std::wstring s;"
HAVE_STD_WSTRING
string
)
endif() endif()
# Check for availability of GCC's atomic operations builtins. # Check for availability of GCC's atomic operations builtins.
@@ -588,13 +590,6 @@ check_include_file(w32api.h HAVE_W32API_H)
check_include_file(wchar.h HAVE_WCHAR_H) check_include_file(wchar.h HAVE_WCHAR_H)
check_include_file(wcstr.h HAVE_WCSTR_H) check_include_file(wcstr.h HAVE_WCSTR_H)
wx_check_cxx_source_compiles(
"std::wstring s;"
HAVE_STD_WSTRING
string
)
if(wxUSE_DATETIME) if(wxUSE_DATETIME)
# check for timezone variable # check for timezone variable
# doesn't exist under Darwin / Mac OS X which uses tm_gmtoff instead # doesn't exist under Darwin / Mac OS X which uses tm_gmtoff instead

View File

@@ -171,6 +171,9 @@ Currently the following symbols exist:
wxBitmapToggleButton class is available in addition to wxToggleButton.} wxBitmapToggleButton class is available in addition to wxToggleButton.}
@itemdef{wxHAS_CONFIG_TEMPLATE_RW, Defined if the currently used compiler @itemdef{wxHAS_CONFIG_TEMPLATE_RW, Defined if the currently used compiler
supports template Read() and Write() methods in wxConfig.} supports template Read() and Write() methods in wxConfig.}
@itemdef{wxHAS_MEMBER_DEFAULT, Defined if the currently used compiler supports
C++11 @c =default. @c wxMEMBER_DEFAULT is defined as this keyword in this
case, and as nothing otherwise.}
@itemdef{wxHAS_LARGE_FILES, Defined if wxFile supports files more than 4GB in @itemdef{wxHAS_LARGE_FILES, Defined if wxFile supports files more than 4GB in
size (notice that you must include @c wx/filefn.h before testing for this size (notice that you must include @c wx/filefn.h before testing for this
symbol).} symbol).}

View File

@@ -38,9 +38,9 @@ public:
wxAnimation(); wxAnimation();
explicit wxAnimation(const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY); explicit wxAnimation(const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY);
#if __cplusplus >= 201103 #ifdef wxHAS_MEMBER_DEFAULT
wxAnimation(const wxAnimation&) = default; wxAnimation(const wxAnimation&) wxMEMBER_DEFAULT;
wxAnimation& operator=(const wxAnimation&) = default; wxAnimation& operator=(const wxAnimation&) wxMEMBER_DEFAULT;
#endif #endif
bool IsOk() const; bool IsOk() const;

View File

@@ -285,6 +285,14 @@ typedef short int WXTYPE;
#define wxOVERRIDE #define wxOVERRIDE
#endif /* HAVE_OVERRIDE */ #endif /* HAVE_OVERRIDE */
/* same for defaulted member function keyword */
#if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14)
#define wxHAS_MEMBER_DEFAULT
#define wxMEMBER_DEFAULT = default
#else
#define wxMEMBER_DEFAULT
#endif
/* /*
Support for nullptr is available since MSVS 2010, even though it doesn't Support for nullptr is available since MSVS 2010, even though it doesn't
define __cplusplus as a C++11 compiler. define __cplusplus as a C++11 compiler.
@@ -2994,7 +3002,7 @@ typedef const void* WXWidget;
/* macros to define a class without copy ctor nor assignment operator */ /* macros to define a class without copy ctor nor assignment operator */
/* --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- */
#if defined(__cplusplus) && __cplusplus >= 201103L #if defined(__cplusplus) && (__cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14))
#define wxMEMBER_DELETE = delete #define wxMEMBER_DELETE = delete
#else #else
#define wxMEMBER_DELETE #define wxMEMBER_DELETE

View File

@@ -66,11 +66,9 @@ public:
operator HSTRING() const { return m_hstring; }; operator HSTRING() const { return m_hstring; };
static const TempStringRef Make(const wxString &str); TempStringRef(const wxString& str);
private: private:
TempStringRef(const wxString &str);
HSTRING m_hstring; HSTRING m_hstring;
HSTRING_HEADER m_header; HSTRING_HEADER m_header;

View File

@@ -267,8 +267,8 @@ public:
wxUniCharRef& operator=(const wxUniCharRef& c) wxUniCharRef& operator=(const wxUniCharRef& c)
{ if (&c != this) *this = c.UniChar(); return *this; } { if (&c != this) *this = c.UniChar(); return *this; }
#if __cplusplus >= 201103 #ifdef wxHAS_MEMBER_DEFAULT
wxUniCharRef(const wxUniCharRef&) = default; wxUniCharRef(const wxUniCharRef&) wxMEMBER_DEFAULT;
#endif #endif
#define wxUNICHAR_REF_DEFINE_OPERATOR_EQUAL(type) \ #define wxUNICHAR_REF_DEFINE_OPERATOR_EQUAL(type) \

View File

@@ -1070,9 +1070,9 @@ bool RegTreeCtrl::TreeNode::OnExpand()
case wxRegKey::Type_Dword: case wxRegKey::Type_Dword:
{ {
long l; long ldw;
m_pKey->QueryValue(str, &l); m_pKey->QueryValue(str, &ldw);
strItem << l; strItem << ldw;
} }
wxFALLTHROUGH; wxFALLTHROUGH;

View File

@@ -59,7 +59,7 @@ wxArrayString::wxArrayString(size_t sz, const wxString* a)
#include "wx/arrstr.h" #include "wx/arrstr.h"
#if __cplusplus >= 201103L #if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14)
int wxArrayString::Index(const wxString& str, bool bCase, bool WXUNUSED(bFromEnd)) const int wxArrayString::Index(const wxString& str, bool bCase, bool WXUNUSED(bFromEnd)) const
{ {
@@ -153,7 +153,7 @@ wxStringCompareLess<F> wxStringCompare(F f)
void wxArrayString::Sort(CompareFunction function) void wxArrayString::Sort(CompareFunction function)
{ {
std::sort(begin(), end(), std::sort(begin(), end(),
#if __cplusplus >= 201103L #if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14)
[function](const wxString& s1, const wxString& s2) [function](const wxString& s1, const wxString& s2)
{ {
return function(s1, s2) < 0; return function(s1, s2) < 0;
@@ -185,7 +185,7 @@ int wxSortedArrayString::Index(const wxString& str,
wxSortedArrayString::const_iterator wxSortedArrayString::const_iterator
it = std::lower_bound(begin(), end(), str, it = std::lower_bound(begin(), end(), str,
#if __cplusplus >= 201103L #if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14)
[](const wxString& s1, const wxString& s2) [](const wxString& s1, const wxString& s2)
{ {
return s1 < s2; return s1 < s2;

View File

@@ -64,7 +64,7 @@ public:
m_impl = NULL; m_impl = NULL;
} }
// DesktopToastActivatedEventHandler // DesktopToastActivatedEventHandler
IFACEMETHODIMP Invoke(IToastNotification *sender, IInspectable* args); IFACEMETHODIMP Invoke(IToastNotification *sender, IInspectable* args);
// DesktopToastDismissedEventHandler // DesktopToastDismissedEventHandler
@@ -170,7 +170,7 @@ public:
HRESULT CreateToast(IXmlDocument *xml) HRESULT CreateToast(IXmlDocument *xml)
{ {
HRESULT hr = ms_toastMgr->CreateToastNotifierWithId(rt::TempStringRef::Make(ms_appId), &m_notifier); HRESULT hr = ms_toastMgr->CreateToastNotifierWithId(rt::TempStringRef(ms_appId), &m_notifier);
if ( SUCCEEDED(hr) ) if ( SUCCEEDED(hr) )
{ {
wxCOMPtr<IToastNotificationFactory> factory; wxCOMPtr<IToastNotificationFactory> factory;
@@ -215,7 +215,7 @@ public:
if ( SUCCEEDED(hr) ) if ( SUCCEEDED(hr) )
{ {
wxCOMPtr<IXmlNodeList> nodeList; wxCOMPtr<IXmlNodeList> nodeList;
hr = (*toastXml)->GetElementsByTagName(rt::TempStringRef::Make("text"), &nodeList); hr = (*toastXml)->GetElementsByTagName(rt::TempStringRef("text"), &nodeList);
if ( SUCCEEDED(hr) ) if ( SUCCEEDED(hr) )
{ {
hr = SetNodeListValueString(0, m_title, nodeList, *toastXml); hr = SetNodeListValueString(0, m_title, nodeList, *toastXml);
@@ -244,7 +244,7 @@ public:
{ {
wxCOMPtr<IXmlText> inputText; wxCOMPtr<IXmlText> inputText;
HRESULT hr = xml->CreateTextNode(rt::TempStringRef::Make(str), &inputText); HRESULT hr = xml->CreateTextNode(rt::TempStringRef(str), &inputText);
if ( SUCCEEDED(hr) ) if ( SUCCEEDED(hr) )
{ {
wxCOMPtr<IXmlNode> inputTextNode; wxCOMPtr<IXmlNode> inputTextNode;

View File

@@ -166,15 +166,14 @@ int RTCore::ms_isAvailable = -1;
// wxWinRT::TempStringRef // wxWinRT::TempStringRef
// //
const TempStringRef TempStringRef::Make(const wxString &str)
{
return TempStringRef(str);
}
TempStringRef::TempStringRef(const wxString &str) TempStringRef::TempStringRef(const wxString &str)
: m_hstring(NULL), m_header()
{ {
if ( !RTCore::IsAvailable() ) if ( !RTCore::IsAvailable() )
{
wxLogDebug("Can not create string reference without WinRT"); wxLogDebug("Can not create string reference without WinRT");
return;
}
// This creates a fast-pass string which must not be deleted using WindowsDeleteString // This creates a fast-pass string which must not be deleted using WindowsDeleteString
HRESULT hr = RTCore::Get().WindowsCreateStringReference( HRESULT hr = RTCore::Get().WindowsCreateStringReference(
@@ -221,7 +220,7 @@ bool GetActivationFactory(const wxString& activatableClassId, REFIID iid, void *
if ( !RTCore::IsAvailable() ) if ( !RTCore::IsAvailable() )
return false; return false;
HRESULT hr = RTCore::Get().RoGetActivationFactory(TempStringRef::Make(activatableClassId), iid, factory); HRESULT hr = RTCore::Get().RoGetActivationFactory(TempStringRef(activatableClassId), iid, factory);
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
wxLogDebug("RoGetActivationFactory failed %.8x", hr); wxLogDebug("RoGetActivationFactory failed %.8x", hr);

View File

@@ -135,7 +135,11 @@ static void TestAssertHandler(const wxString& file,
// so we'd just die without any useful information -- abort instead. // so we'd just die without any useful information -- abort instead.
abortReason << assertMessage << "in a worker thread."; abortReason << assertMessage << "in a worker thread.";
} }
#if __cplusplus >= 201703L || wxCHECK_VISUALC_VERSION(14)
else if ( uncaught_exceptions() )
#else
else if ( uncaught_exception() ) else if ( uncaught_exception() )
#endif
{ {
// Throwing while already handling an exception would result in // Throwing while already handling an exception would result in
// terminate() being called and we wouldn't get any useful information // terminate() being called and we wouldn't get any useful information