From 2fedaa63a6720247822327d41bb909513be1c2f1 Mon Sep 17 00:00:00 2001 From: Rafael Kitover Date: Thu, 25 Apr 2019 16:22:07 +0000 Subject: [PATCH] support FreeBSD Make some changes to support out-of-the-box builds on FreeBSD: - set cmake OpenGL type to `LEGACY`, the new `GLVND` type produces unusable binaries on FreeBSD - on FreeBSD add -I/usr/local/include to compiler flags, why this is necessary I don't know - look for llvm tools such as `llvm-ar` in `/usr/local/llvm-devel/bin`, LTO works - improve the `find_wx_util()` cmake function to handle `wx-config` scripts named in the form e.g. `wxgtk3u-3.1-config` - add FreeBSD support to `installdeps` - make some minor changes to included headers based on macros such as `__FreeBSD__` to compile on FreeBSD, including adding a `BSD.h` header with some defines for e.g. `fseeko64` - move the cmake X11 detection to before the wx compile tests, because otherwise the extra compile flags for the wx tests make the X11 tests fail - make some minor changes to fix wx 2.8 compatibilty again, we don't actually use 2.8 for FreeBSD but I was testing it Signed-off-by: Rafael Kitover --- CMakeLists.txt | 9 +++++++-- cmake/LLVMToolchain.cmake | 12 ++++++++++++ cmake/VbamFunctions.cmake | 18 ++++++++++++++---- installdeps | 18 ++++++++++++++++-- src/common/BSD.h | 11 +++++++++++ src/common/ConfigManager.cpp | 1 + src/common/Patch.cpp | 8 +++++--- src/gba/GBALink.cpp | 4 ++-- src/wx/CMakeLists.txt | 36 +++++++++++++++++++++++++----------- src/wx/guiinit.cpp | 5 +++-- src/wx/opts.h | 6 +++--- src/wx/panel.cpp | 4 +++- src/wx/wxvbam.cpp | 14 +++++++------- src/wx/wxvbam.h | 2 +- 14 files changed, 110 insertions(+), 38 deletions(-) create mode 100644 src/common/BSD.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 374f9deb..fef3ed12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ set(LTO_DEFAULT ON) # lto produces buggy binaries for 64 bit win32 # and we generally don't want it when debugging because it makes linking slow -if((WIN32 AND CMAKE_COMPILER_IS_GNUCXX AND AMD64) OR CMAKE_BUILD_TYPE MATCHES Debug) +if(CMAKE_BUILD_TYPE MATCHES Debug OR (WIN32 AND CMAKE_COMPILER_IS_GNUCXX AND AMD64)) set(LTO_DEFAULT OFF) endif() @@ -198,7 +198,7 @@ endif() # Look for some dependencies using CMake scripts find_package(ZLIB REQUIRED) -set(OpenGL_GL_PREFERENCE GLVND) +set(OpenGL_GL_PREFERENCE LEGACY) find_package(OpenGL REQUIRED) @@ -504,6 +504,11 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(MY_C_FLAGS ${MY_C_FLAGS} ${MY_C_OPT_FLAGS} -Wno-error) endif() + # for some reason this is necessary + if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD) + set(MY_C_FLAGS -I/usr/local/include ${MY_C_FLAGS}) + endif() + foreach(C_COMPILE_FLAG ${MY_C_FLAGS}) add_compile_options(${C_COMPILE_FLAG}) endforeach() diff --git a/cmake/LLVMToolchain.cmake b/cmake/LLVMToolchain.cmake index 0953f968..166c8d62 100644 --- a/cmake/LLVMToolchain.cmake +++ b/cmake/LLVMToolchain.cmake @@ -14,6 +14,18 @@ function(use_llvm_toolchain) OUTPUT_STRIP_TRAILING_WHITESPACE ) + # for FreeBSD + if(NOT prog_path MATCHES "^/") + get_filename_component( + abs_path ${prog_path} ABSOLUTE + BASE_DIR /usr/local/llvm-devel/bin + ) + + if(EXISTS ${abs_path}) + set(prog_path ${abs_path}) + endif() + endif() + if(prog_path MATCHES "^/") if(tool STREQUAL ld) set(tool linker) diff --git a/cmake/VbamFunctions.cmake b/cmake/VbamFunctions.cmake index e6628c82..ca19da4e 100644 --- a/cmake/VbamFunctions.cmake +++ b/cmake/VbamFunctions.cmake @@ -70,16 +70,16 @@ endfunction() function(find_wx_util var util) # on win32, including cross builds we prefer the plain utility name first from PATH if(WIN32) - set(conf_suffixes "" gtk4 gtk3) + set(conf_suffixes "" gtk4u gtk4 gtk3u gtk3 gtk2u gtk2) set(major_versions "" 4 3 2) else() - set(conf_suffixes gtk4 gtk3 "") + set(conf_suffixes gtk4u gtk4 gtk3u gtk3 gtk2u gtk2"") set(major_versions 4 3 2 "") endif() foreach(conf_suffix IN LISTS conf_suffixes) foreach(major_version IN LISTS major_versions) - foreach(minor_version RANGE 100 0 -1) + foreach(minor_version RANGE 100 -1 -1) unset(suffix) if(conf_suffix) set(suffix "-${conf_suffix}") @@ -87,7 +87,7 @@ function(find_wx_util var util) if(major_version) set(suffix "${suffix}-${major_version}") - if(NOT minor_version EQUAL 0) + if(NOT minor_version EQUAL -1) set(suffix "${suffix}.${minor_version}") endif() endif() @@ -96,6 +96,16 @@ function(find_wx_util var util) set(exe NOTFOUND CACHE INTERNAL "" FORCE) find_program(exe NAMES "${util}${suffix}") + # try infix variant, as on FreeBSD + if(NOT EXISTS ${exe}) + string(REGEX REPLACE "^-" "" suffix "${suffix}") + + string(REGEX REPLACE "-" "${suffix}-" try ${util}) + + set(exe NOTFOUND CACHE INTERNAL "" FORCE) + find_program(exe NAMES ${try}) + endif() + if(EXISTS ${exe}) # check that the utility can be executed cleanly # in case we find e.g. the wrong architecture binary diff --git a/installdeps b/installdeps index 54542d26..19441980 100755 --- a/installdeps +++ b/installdeps @@ -45,6 +45,9 @@ check_os() { Darwin) os=mac ;; + FreeBSD) + os=freebsd + ;; MINGW*|MSYS*) os=windows ;; @@ -174,6 +177,17 @@ linux_installdeps() { fi } +freebsd_installdeps() { + installing + + check sudo pkg update + + # currently the wx30 and wx31 packages produce GTK errors on CURRENT (as of 04/2019) + check sudo pkg install -y llvm-devel cmake ccache nasm ffmpeg gettext-tools gettext png pkgconf sdl2 sfml wx31-gtk3 iconv zip ninja + + build_instructions +} + # the -j flag for make parameter, empty if 1 jobs_flag() { if [ $(num_cpus) -gt 1 ]; then @@ -197,7 +211,7 @@ num_cpus() { _num_cpus=$(nproc) elif [ $os = linux -o $os = windows ]; then _num_cpus=$(grep '^processor *:' /proc/cpuinfo | wc -l) - elif [ $os = mac ]; then + elif [ $os = mac ] || [ $os = freebsd ]; then _num_cpus=$(sysctl -n hw.ncpu) fi @@ -1055,7 +1069,7 @@ macports_installdeps() { installing check sudo port -v selfupdate - check sudo port -v install cmake ccache nasm ffmpeg gettext libpng pkgconfig libsdl2 sfml wxWidgets-3.0 libiconv ccache + check sudo port -v install cmake ccache nasm ffmpeg gettext libpng pkgconfig libsdl2 sfml wxWidgets-3.0 libiconv check sudo port select wxWidgets wxWidgets-3.0 build_instructions diff --git a/src/common/BSD.h b/src/common/BSD.h new file mode 100644 index 00000000..c0121d39 --- /dev/null +++ b/src/common/BSD.h @@ -0,0 +1,11 @@ +#ifndef VBAM_BSD_H +#define VBAM_BSD_H + +#define fopen64 fopen +#define fseeko64 fseeko +#define fseek64 fseek +#define ftell64 ftell +#define ftello64 ftello + +#endif // VBAM_BSD_H + diff --git a/src/common/ConfigManager.cpp b/src/common/ConfigManager.cpp index 11a74c9c..fe363736 100644 --- a/src/common/ConfigManager.cpp +++ b/src/common/ConfigManager.cpp @@ -16,6 +16,7 @@ extern "C" { #include #include #include +#include #include "../common/Patch.h" #include "../common/ConfigManager.h" diff --git a/src/common/Patch.cpp b/src/common/Patch.cpp index 03839f2e..e120166a 100644 --- a/src/common/Patch.cpp +++ b/src/common/Patch.cpp @@ -7,12 +7,14 @@ #include "Patch.h" +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include +#include "BSD.h" +#endif + #ifndef __LIBRETRO__ #ifdef __GNUC__ -#if defined(BSD) || defined(__NetBSD__) -#include -#endif #if defined(__APPLE__) || defined(BSD) || defined(__NetBSD__) typedef off_t __off64_t; /* off_t is 64 bits on BSD. */ #define fseeko64 fseeko diff --git a/src/gba/GBALink.cpp b/src/gba/GBALink.cpp index ba7c2691..5af73205 100644 --- a/src/gba/GBALink.cpp +++ b/src/gba/GBALink.cpp @@ -3,8 +3,8 @@ #include #include -// malloc.h does not seem to exist on Mac OS 10.7 -#ifdef __APPLE__ +// malloc.h does not seem to exist on Mac OS 10.7 and is an error on FreeBSD +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) #include #else #include diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index 9e99bffb..46bd4100 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -63,6 +63,18 @@ if(ENABLE_FAUDIO) set(FAUDIO_LIBS FAudio) endif() +# on unix we have to check for X11 before we overwrite all the compile/link +# flags with the wx tests +if(NOT WIN32 AND NOT APPLE) + find_package(X11) + + if(X11_X11_LIB AND X11_Xscreensaver_LIB) + include_directories(${X11_INCLUDE_DIR}) + set(EXTRA_X11_LIBS ${X11_X11_LIB} ${X11_Xscreensaver_LIB}) + add_definitions(-DHAVE_XSS) + endif() +endif() + # on VS with vcpkg we can't use FindwxWidgets, we have to set everything up # manually because the package is broken if(WIN32 AND CMAKE_TOOLCHAIN_FILE MATCHES vcpkg AND (X86_32 OR AMD64)) @@ -193,7 +205,19 @@ else() set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_FLAGS} ${CMAKE_REQUIRED_DEFINITIONS}) # find the right C++ ABI version for wxWidgets, this is also necessary for the OpenGL check following - if((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) AND NOT CMAKE_CROSSCOMPILING) + + # on FreeBSD the ABI check segfaults and always fails, and we don't + # need it because everything is built with clang + set(ABI_CHECK FALSE) + + if((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) + AND NOT CMAKE_CROSSCOMPILING + AND NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD) + + set(ABI_CHECK TRUE) + endif() + + if(ABI_CHECK) set(WX_ABI_FOUND_MATCH FALSE) include(CheckCXXSourceRuns) @@ -691,16 +715,6 @@ if(WIN32) endif() endif() -if(NOT WIN32 AND NOT APPLE) - find_package(X11) - - if(X11_X11_LIB AND X11_Xscreensaver_LIB) - include_directories(${X11_INCLUDE_DIR}) - set(EXTRA_X11_LIBS ${X11_X11_LIB} ${X11_Xscreensaver_LIB}) - add_definitions(-DHAVE_XSS) - endif() -endif() - link_directories(${CMAKE_BINARY_DIR}) set(VBAM_ICON vbam.icns) diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index 02ac5213..df1c73a6 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -7,6 +7,7 @@ #include "wxvbam.h" +#include #include #include #include @@ -89,7 +90,7 @@ public: return; if (!server) { - bool valid = SetLinkServerHost(gopts.link_host.c_str()); + bool valid = SetLinkServerHost(gopts.link_host.utf8_str()); if (!valid) { wxMessageBox(_("You must enter a valid host name"), @@ -3835,7 +3836,7 @@ bool MainFrame::BindControls() bool isv = !gopts.link_host.empty(); if (isv) { - isv = SetLinkServerHost(gopts.link_host.c_str()); + isv = SetLinkServerHost(gopts.link_host.utf8_str()); } if (!isv) { diff --git a/src/wx/opts.h b/src/wx/opts.h index b28c4365..03905939 100644 --- a/src/wx/opts.h +++ b/src/wx/opts.h @@ -103,10 +103,10 @@ extern struct opt_desc { } opts[]; // Initializer for struct opt_desc -opt_desc new_opt_desc(wxString opt = "", const char* cmd = NULL, wxString desc = "", - wxString* stropt = NULL, int* intopt = NULL, wxString enumvals = "", +opt_desc new_opt_desc(wxString opt = wxT(""), const char* cmd = NULL, wxString desc = wxT(""), + wxString* stropt = NULL, int* intopt = NULL, wxString enumvals = wxT(""), double min = 0, double max = 0, bool* boolopt = NULL, - double* doubleopt = NULL, uint32_t* uintopt = NULL, wxString curstr = "", + double* doubleopt = NULL, uint32_t* uintopt = NULL, wxString curstr = wxT(""), int curint = 0, double curdouble = 0, uint32_t curuint = 0); extern const int num_opts; diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 3d68acb2..1e30bd1a 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -1051,8 +1051,10 @@ void GameArea::OnIdle(wxIdleEvent& event) #endif Layout(); - SendSizeEvent(); +#if wxCHECK_VERSION(2, 9, 0) + SendSizeEvent(); +#endif if (pointer_blanked) w->SetCursor(wxCursor(wxCURSOR_BLANK)); diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index 74b239df..0efee6f3 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -479,32 +479,32 @@ void wxvbamApp::OnInitCmdLine(wxCmdLineParser& cl) static wxCmdLineEntryDesc opttab[] = { { wxCMD_LINE_OPTION, NULL, t("save-xrc"), N_("Save built-in XRC file and exit"), - wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE }, + wxCMD_LINE_VAL_STRING, 0 }, { wxCMD_LINE_OPTION, NULL, t("save-over"), N_("Save built-in vba-over.ini and exit"), - wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE }, + wxCMD_LINE_VAL_STRING, 0 }, { wxCMD_LINE_SWITCH, NULL, t("print-cfg-path"), N_("Print configuration path and exit"), - wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE }, + wxCMD_LINE_VAL_NONE, 0 }, { wxCMD_LINE_SWITCH, t("f"), t("fullscreen"), N_("Start in full-screen mode"), - wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE }, + wxCMD_LINE_VAL_NONE, 0 }, #if !defined(NO_LINK) && !defined(__WXMSW__) { wxCMD_LINE_SWITCH, t("s"), t("delete-shared-state"), N_("Delete shared link state first, if it exists"), - wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE }, + wxCMD_LINE_VAL_NONE, 0 }, #endif // stupid wx cmd line parser doesn't support duplicate options // { wxCMD_LINE_OPTION, t("o"), t("option"), // _("Set configuration option; = or help for list"), { wxCMD_LINE_SWITCH, t("o"), t("list-options"), N_("List all settable options and exit"), - wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE }, + wxCMD_LINE_VAL_NONE, 0 }, { wxCMD_LINE_PARAM, NULL, NULL, N_("ROM file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_PARAM, NULL, NULL, N_("="), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_NONE, NULL, NULL, NULL, wxCMD_LINE_VAL_NONE, wxCMD_LINE_VAL_NONE } + { wxCMD_LINE_NONE, NULL, NULL, NULL, wxCMD_LINE_VAL_NONE, 0 } }; // 2.9 automatically translates desc, but 2.8 doesn't #if !wxCHECK_VERSION(2, 9, 0) diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index 23fc725e..cca29123 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -658,7 +658,7 @@ extern struct cmditem { extern const int ncmds; // Initializer for struct cmditem -cmditem new_cmditem(const wxString cmd = "", const wxString name = "", +cmditem new_cmditem(const wxString cmd = wxT(""), const wxString name = wxT(""), int cmd_id = 0, int mask_flags = 0, wxMenuItem* mi = NULL); // for binary search