From f40d9a0d80bcb0f97c7d1d4c2e984ee4d5bc372b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Heusipp?= Date: Mon, 23 Sep 2024 16:20:59 +0000 Subject: [PATCH] [Ref] mpt/main/main.hpp: Add main library that abstracts away platform-specific non-standard handling of main(), like Win32 wmain, MinGW missing prototypes, and DJGPP crt0 flags. git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@21699 56274372-70c3-4bfc-bfc3-4c3a0b034d27 --- Makefile | 2 + build/autotools/Makefile.am | 1 + build/autotools/autoconfiscate.sh | 2 + build/premake-xcode/mpt-libopenmpt.lua | 2 + build/premake/mpt-OpenMPT-NativeSupport.lua | 2 + build/premake/mpt-OpenMPT.lua | 4 + build/premake/mpt-PluginBridge.lua | 4 + build/premake/mpt-libopenmpt-small.lua | 2 + build/premake/mpt-libopenmpt.lua | 2 + build/premake/mpt-libopenmpt_test.lua | 2 + build/premake/mpt-updatesigntool.lua | 2 + src/mpt/main/main.hpp | 196 ++++++++++++++++++++ 12 files changed, 221 insertions(+) create mode 100644 src/mpt/main/main.hpp diff --git a/Makefile b/Makefile index 1c322e9fb2c..ce374317d95 100644 --- a/Makefile +++ b/Makefile @@ -1835,6 +1835,7 @@ bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION).makefile.tar: b svn export ./src/mpt/io_write bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/io_write #svn export ./src/mpt/json bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/json #svn export ./src/mpt/library bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/library + svn export ./src/mpt/main bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/main svn export ./src/mpt/mutex bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/mutex svn export ./src/mpt/out_of_memory bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/out_of_memory svn export ./src/mpt/osinfo bin/$(FLAVOUR_DIR)dist-tar/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/osinfo @@ -1935,6 +1936,7 @@ bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION).msvc.zip: bin/$ svn export ./src/mpt/io_write bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/io_write --native-eol CRLF #svn export ./src/mpt/json bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/json --native-eol CRLF #svn export ./src/mpt/library bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/library --native-eol CRLF + svn export ./src/mpt/main bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/main --native-eol CRLF svn export ./src/mpt/mutex bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/mutex --native-eol CRLF svn export ./src/mpt/out_of_memory bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/out_of_memory --native-eol CRLF svn export ./src/mpt/osinfo bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/src/mpt/osinfo --native-eol CRLF diff --git a/build/autotools/Makefile.am b/build/autotools/Makefile.am index d1cbb894918..8084f1bba81 100644 --- a/build/autotools/Makefile.am +++ b/build/autotools/Makefile.am @@ -238,6 +238,7 @@ MPT_FILES_SRC_MPT += src/mpt/io_read/filereader.hpp MPT_FILES_SRC_MPT += src/mpt/io_write/buffer.hpp #MPT_FILES_SRC_MPT += src/mpt/json/json.hpp #MPT_FILES_SRC_MPT += src/mpt/library/library.hpp +MPT_FILES_SRC_MPT += src/mpt/main/main.hpp MPT_FILES_SRC_MPT += src/mpt/mutex/mutex.hpp MPT_FILES_SRC_MPT += src/mpt/osinfo/class.hpp MPT_FILES_SRC_MPT += src/mpt/osinfo/dos_memory.hpp diff --git a/build/autotools/autoconfiscate.sh b/build/autotools/autoconfiscate.sh index 8b3ff3309ea..3b808024c64 100755 --- a/build/autotools/autoconfiscate.sh +++ b/build/autotools/autoconfiscate.sh @@ -89,6 +89,7 @@ svn export ./src/mpt/io_read bin/dist-autotools/src/mpt svn export ./src/mpt/io_write bin/dist-autotools/src/mpt/io_write #svn export ./src/mpt/json bin/dist-autotools/src/mpt/json #svn export ./src/mpt/library bin/dist-autotools/src/mpt/library +svn export ./src/mpt/main bin/dist-autotools/src/mpt/main svn export ./src/mpt/mutex bin/dist-autotools/src/mpt/mutex svn export ./src/mpt/out_of_memory bin/dist-autotools/src/mpt/out_of_memory svn export ./src/mpt/osinfo bin/dist-autotools/src/mpt/osinfo @@ -164,6 +165,7 @@ cp -r ./src/mpt/io_read bin/dist-autotools/src/mpt cp -r ./src/mpt/io_write bin/dist-autotools/src/mpt/io_write #cp -r ./src/mpt/json bin/dist-autotools/src/mpt/json #cp -r ./src/mpt/library bin/dist-autotools/src/mpt/library +cp -r ./src/mpt/main bin/dist-autotools/src/mpt/main cp -r ./src/mpt/mutex bin/dist-autotools/src/mpt/mutex cp -r ./src/mpt/out_of_memory bin/dist-autotools/src/mpt/out_of_memory cp -r ./src/mpt/osinfo bin/dist-autotools/src/mpt/osinfo diff --git a/build/premake-xcode/mpt-libopenmpt.lua b/build/premake-xcode/mpt-libopenmpt.lua index 723e6cef004..947010926ad 100755 --- a/build/premake-xcode/mpt-libopenmpt.lua +++ b/build/premake-xcode/mpt-libopenmpt.lua @@ -49,6 +49,8 @@ "../../src/mpt/json/**.hpp", "../../src/mpt/library/**.cpp", "../../src/mpt/library/**.hpp", + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/mpt/test/**.cpp", "../../src/mpt/test/**.hpp", "../../src/mpt/uuid_namespace/**.cpp", diff --git a/build/premake/mpt-OpenMPT-NativeSupport.lua b/build/premake/mpt-OpenMPT-NativeSupport.lua index 43e40ede33b..54d5e589a57 100755 --- a/build/premake/mpt-OpenMPT-NativeSupport.lua +++ b/build/premake/mpt-OpenMPT-NativeSupport.lua @@ -35,6 +35,8 @@ } excludes { "../../mptrack/wine/WineWrapper.cpp", + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/openmpt/fileformat_base/**.cpp", "../../src/openmpt/fileformat_base/**.hpp", "../../src/openmpt/soundfile_data/**.cpp", diff --git a/build/premake/mpt-OpenMPT.lua b/build/premake/mpt-OpenMPT.lua index 7677cf0ee1c..39d3aade16a 100755 --- a/build/premake/mpt-OpenMPT.lua +++ b/build/premake/mpt-OpenMPT.lua @@ -118,6 +118,10 @@ end "../../pluginBridge/BridgeWrapper.cpp", "../../pluginBridge/BridgeWrapper.h", } + excludes { + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", + } files { "../../mptrack/mptrack.rc", "../../mptrack/res/*.*", -- resource data files diff --git a/build/premake/mpt-PluginBridge.lua b/build/premake/mpt-PluginBridge.lua index e4cb3853ecf..f4b7e18daea 100755 --- a/build/premake/mpt-PluginBridge.lua +++ b/build/premake/mpt-PluginBridge.lua @@ -23,6 +23,8 @@ "../../common/versionNumber.h", } excludes { + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/openmpt/fileformat_base/**.cpp", "../../src/openmpt/fileformat_base/**.hpp", "../../src/openmpt/soundbase/**.cpp", @@ -83,6 +85,8 @@ "../../common/versionNumber.h", } excludes { + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/openmpt/fileformat_base/**.cpp", "../../src/openmpt/fileformat_base/**.hpp", "../../src/openmpt/soundbase/**.cpp", diff --git a/build/premake/mpt-libopenmpt-small.lua b/build/premake/mpt-libopenmpt-small.lua index 11c072f698c..8b786f52e9e 100755 --- a/build/premake/mpt-libopenmpt-small.lua +++ b/build/premake/mpt-libopenmpt-small.lua @@ -66,6 +66,8 @@ "../../src/mpt/json/**.hpp", "../../src/mpt/library/**.cpp", "../../src/mpt/library/**.hpp", + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/mpt/test/**.cpp", "../../src/mpt/test/**.hpp", "../../src/mpt/uuid_namespace/**.cpp", diff --git a/build/premake/mpt-libopenmpt.lua b/build/premake/mpt-libopenmpt.lua index aecdff6db5b..64a7d4e2954 100755 --- a/build/premake/mpt-libopenmpt.lua +++ b/build/premake/mpt-libopenmpt.lua @@ -52,6 +52,8 @@ "../../src/mpt/json/**.hpp", "../../src/mpt/library/**.cpp", "../../src/mpt/library/**.hpp", + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/mpt/test/**.cpp", "../../src/mpt/test/**.hpp", "../../src/mpt/uuid_namespace/**.cpp", diff --git a/build/premake/mpt-libopenmpt_test.lua b/build/premake/mpt-libopenmpt_test.lua index 2f4b93509c6..528c8a64858 100755 --- a/build/premake/mpt-libopenmpt_test.lua +++ b/build/premake/mpt-libopenmpt_test.lua @@ -78,6 +78,8 @@ "../../src/mpt/json/**.hpp", "../../src/mpt/library/**.cpp", "../../src/mpt/library/**.hpp", + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/mpt/uuid_namespace/**.cpp", "../../src/mpt/uuid_namespace/**.hpp", "../../test/mpt_tests_crypto.cpp", diff --git a/build/premake/mpt-updatesigntool.lua b/build/premake/mpt-updatesigntool.lua index 27f6aa3fd35..ebf029f354a 100755 --- a/build/premake/mpt-updatesigntool.lua +++ b/build/premake/mpt-updatesigntool.lua @@ -24,6 +24,8 @@ "../../installer/updatesigntool/*.h", } excludes { + "../../src/mpt/main/**.cpp", + "../../src/mpt/main/**.hpp", "../../src/openmpt/fileformat_base/**.cpp", "../../src/openmpt/fileformat_base/**.hpp", "../../src/openmpt/soundbase/**.cpp", diff --git a/src/mpt/main/main.hpp b/src/mpt/main/main.hpp new file mode 100644 index 00000000000..fd71d5ac700 --- /dev/null +++ b/src/mpt/main/main.hpp @@ -0,0 +1,196 @@ +/* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */ + +#ifndef MPT_MAIN_MAIN_HPP +#define MPT_MAIN_MAIN_HPP + + + +#include "mpt/base/check_platform.hpp" +#include "mpt/base/detect.hpp" +#include "mpt/base/integer.hpp" +#include "mpt/base/macros.hpp" +#include "mpt/base/namespace.hpp" +#include "mpt/string/types.hpp" +#include "mpt/string_transcode/transcode.hpp" + +#include +#include + +#if MPT_OS_DJGPP +#include +#endif // MPT_OS_DJGPP + +#if MPT_OS_DJGPP +#include +#endif // MPT_OS_DJGPP + +#if MPT_OS_WINDOWS +#include +#endif // MPT_OS_WINDOWS + + + +namespace mpt { +inline namespace MPT_INLINE_NS { + + + +namespace main { + + + +#if MPT_OS_DJGPP +/* Work-around */ +/* clang-format off */ +#define MPT_MAIN_PREFIX \ + extern "C" { \ + int _crt0_startup_flags = 0 \ + | _CRT0_FLAG_NONMOVE_SBRK /* force interrupt compatible allocation */ \ + | _CRT0_DISABLE_SBRK_ADDRESS_WRAP /* force NT compatible allocation */ \ + | _CRT0_FLAG_LOCK_MEMORY /* lock all code and data at program startup */ \ + | 0; \ + } \ +/* clang-format on */ +#endif /* MPT_OS_DJGPP */ + +#if !defined(MPT_MAIN_PREFIX) +#define MPT_MAIN_PREFIX +#endif + + + +#if MPT_OS_WINDOWS && defined(UNICODE) +#define MPT_MAIN_NAME wmain +#elif defined(MPT_OS_WINDOWS) +#define MPT_MAIN_NAME main +#endif + +#if !defined(MPT_MAIN_NAME) +#define MPT_MAIN_NAME main +#endif + + + +#if MPT_OS_WINDOWS && defined(UNICODE) +#define MPT_MAIN_ARGV_TYPE wchar_t +#elif defined(MPT_OS_WINDOWS) +#define MPT_MAIN_ARGV_TYPE char +#endif + +#if !defined(MPT_MAIN_NAME) +#define MPT_MAIN_ARGV_TYPE char +#endif + + + +#if MPT_OS_WINDOWS && (MPT_COMPILER_GCC || MPT_COMPILER_CLANG) +#if defined(UNICODE) +#define MPT_MAIN_DECL extern "C" int wmain(int argc, wchar_t * argv[]); +#endif +#endif + +#if !defined(MPT_MAIN_DECL) +#define MPT_MAIN_DECL +#endif + + + +#if MPT_OS_DJGPP +/* clang-format off */ +#define MPT_MAIN_PROLOG() \ + do { \ + _crt0_startup_flags &= ~_CRT0_FLAG_LOCK_MEMORY; \ + assert(mpt::platform::libc().is_ok()); \ + } while (0) \ +/**/ +/* clang-format on */ +#endif // MPT_OS_DJGPP + +#if !defined(MPT_MAIN_PROLOG) +#define MPT_MAIN_PROLOG() do { } while(0) +#endif + + + +#if MPT_OS_WINDOWS && (MPT_COMPILER_GCC || MPT_COMPILER_CLANG) +#if defined(UNICODE) +#define MPT_MAIN_DEF_PREFIX extern "C" +#endif +#endif // MPT_OS_WINDOWS && (MPT_COMPILER_GCC || MPT_COMPILER_CLANG) + +#if !defined(MPT_MAIN_DEF_PREFIX) +#define MPT_MAIN_DEF_PREFIX +#endif + + + +inline mpt::ustring transcode_arg(char * arg) { + return mpt::transcode(mpt::logical_encoding::locale, arg); +} + +#if !defined(MPT_COMPILER_QUIRK_NO_WCHAR) +inline mpt::ustring transcode_arg(wchar_t * arg) { + return mpt::transcode(arg); +} +#endif + +template +inline std::vector transcode_argv(int argc, Tchar * argv[]) { + std::vector args; + args.reserve(argc); + for (int arg = 0; arg < argc; ++arg) { + args.push_back(transcode_arg(argv[arg])); + } + return args; +} + + + +#if !defined(MPT_MAIN_POSTFIX) +#define MPT_MAIN_POSTFIX +#endif + + + +/* clang-format off */ +#define MPT_MAIN_IMPLEMENT_MAIN(ns) \ + MPT_MAIN_PREFIX \ + MPT_MAIN_DECL \ + MPT_MAIN_DEF_PREFIX int MPT_MAIN_NAME(int argc, MPT_MAIN_ARGV_TYPE * argv[]) { \ + MPT_MAIN_PROLOG(); \ + static_assert(std::is_same)>::value); \ + return static_cast(ns::main(mpt::main::transcode_argv(argc, argv))); \ + } \ + MPT_MAIN_POSTFIX \ +/**/ +/* clang-format on */ + + + +/* clang-format off */ +#define MPT_MAIN_IMPLEMENT_MAIN_NO_ARGS(ns) \ + MPT_MAIN_PREFIX \ + MPT_MAIN_DECL \ + MPT_MAIN_DEF_PREFIX int MPT_MAIN_NAME(int argc, MPT_MAIN_ARGV_TYPE * argv[]) { \ + MPT_MAIN_PROLOG(); \ + static_assert(std::is_same(ns::main()); \ + } \ + MPT_MAIN_POSTFIX \ +/**/ +/* clang-format on */ + + + +} // namespace main + + + +} // namespace MPT_INLINE_NS +} // namespace mpt + + + +#endif // MPT_MAIN_MAIN_HPP