diff --git a/README.md b/README.md index 775d19e0dc555d101feed27bbff15a2152573209..11603003e32abb0c006937a7407b6095f6b9762a 100644 --- a/README.md +++ b/README.md @@ -114,11 +114,11 @@ Windows 64 bit binaries are built from a linux system. On arch, install the pack Make sure that you have the windows toolchain for 64 bit installed. Run the followinf commands: (cd utils/arch-pkgs/mingw-w64-shaderc && makepkg -si) - yay -Sy mingw-w64-gcc mingw-w64-cmake mingw-w64-make + yay -Sy mingw-w64-gcc mingw-w64-cmake mingw-w64-make mingw-w64-dlfcn yay -Sy mingw-w64-mpv # Be sure to install it after building shaderc from source yay -Sy mingw-w64-qt6-* # You may specify the packages rustup target add x86_64-pc-windows-gnu - CMAKE=x86_64-w64-mingw32-cmake CXX=x86_64-w64-mingw32-g++ cargo build --target x86_64-pc-windows-gnu + MAKE=x86_64-w64-mingw32-make CMAKE=x86_64-w64-mingw32-cmake CXX=x86_64-w64-mingw32-g++ cargo build --target x86_64-pc-windows-gnu > Be sure to have the multilib repos and install the bootstrap `minwg-w64-*-bootstrap` packages > first, to avoid the circular dependencies... And be sure to have a lot of time to waste. diff --git a/lektord/build.rs b/lektord/build.rs index c652ce88b9a0840ccc99bedc230b0f10bdff8530..223372a00831834a12f8abf923234f2663c58b00 100644 --- a/lektord/build.rs +++ b/lektord/build.rs @@ -66,6 +66,7 @@ fn main() -> anyhow::Result<()> { let cmake_options: Vec<_> = [ [OsStr::new("-B").to_owned(), build.as_os_str().to_owned()], [OsStr::new("-S").to_owned(), source.as_os_str().to_owned()], + [OsStr::new("-G").to_owned(), "Unix Makefiles".into()], [OsStr::new("-D").to_owned(), version], ] .into_iter() @@ -74,29 +75,34 @@ fn main() -> anyhow::Result<()> { .collect(); let cmake_bin = std::env::var_os("CMAKE").unwrap_or("cmake".into()); + let make_bin = std::env::var_os("MAKE").unwrap_or("make".into()); cmd!(cmake_bin => cmake_options); - cmd!(cmake_bin => [ OsStr::new("--build"), build.as_os_str() ]); + cmd!(make_bin => [ OsStr::new("-C"), build.as_os_str() ]); - let path = std::fs::read_dir(&build) + let (path, ext) = std::fs::read_dir(&build) .expect("failed to read build folder") .find_map(|entry| { let entry = entry.ok()?.path(); match (entry.is_file(), entry.extension()) { - (true, Some(ext)) if is_dylib(ext) => Some(entry), + (true, Some(ext)) if is_dylib(ext) => { + let ext = ext.to_owned(); + Some((entry, ext)) + } _ => None, } }) .expect("failed to find the lektor so/dll lib"); let lib = path.as_os_str().to_string_lossy(); - let from = lib.rfind("/lib").unwrap(); - let libfile = &lib[(from + 4)..]; + let (from, count, prefix) = match lib.rfind("/lib") { + Some(from) => (from, 4, "lib"), + None => (lib.rfind("/").unwrap(), 1, ""), + }; + let libfile = &lib[(from + count)..]; let to = libfile.find('.').unwrap(); - std::fs::copy( - &path, - build_folder().join(format!("lib{}.so", &libfile[..to])), - ) - .expect("failed to copy the liblektor_c dynamic library"); + let mut target_file = build_folder().join(format!("{prefix}{}", &libfile[..to])); + target_file.set_extension(ext); + std::fs::copy(&path, target_file).expect("failed to copy the lektor_c dynamic library"); println!("cargo:rustc-link-search={}", &lib[..from]); println!("cargo:rustc-link-lib=dylib={}", &libfile[..to]); diff --git a/lektord/c/CMakeLists.txt b/lektord/c/CMakeLists.txt index 3b3b574f6b31ac092deb280cbb1bf2b4f9105276..c296409449e278ef904232e7403e8a5bfc57f7e4 100644 --- a/lektord/c/CMakeLists.txt +++ b/lektord/c/CMakeLists.txt @@ -83,7 +83,7 @@ set(GNU_C_FLAGS # FIND DEPENDENCIES # ### ### -find_library(MPV_LIBRARY mpv REQUIRED) # tested with 0.32.0 +find_library(MPV_LIBRARY mpv REQUIRED) # tested with 0.36.0 find_package(Qt6 COMPONENTS Widgets OpenGL OpenGLWidgets REQUIRED) # tested with 6.4.0-1 set(CMAKE_AUTOUIC ON) @@ -93,24 +93,20 @@ set(CMAKE_AUTORCC ON) message(STATUS "The installation prefix is ${CMAKE_INSTALL_PREFIX}") if(WIN32) - message(STATUS "You are building on windows, pay attenion to the dependencies") set(LKT_OS_WIN 1) find_package(dlfcn-win32 REQUIRED) add_compile_definitions(LKT_OS_WIN=1 TERMIWIN_DONOTREDEFINE) endif() if(MSVC OR MSYS OR MINGW) - message(STATUS "You are building with a windows compiler") set(LKT_OS_MINGW 1) find_package(dlfcn-win32 REQUIRED) add_compile_definitions(LKT_OS_MINGW=1 TERMIWIN_DONOTREDEFINE) endif() if(APPLE) - message(STATUS "You are building on MacOS X") set(LKT_OS_APPLE 1) add_compile_definitions(LKT_OS_APPLE=1) endif() if(UNIX AND NOT APPLE) - message(STATUS "You are building on Linux, FreeBSD or any other toaster OS") set(LKT_OS_TOASTER 1) add_compile_definitions(LKT_OS_TOASTER=1) endif() @@ -123,12 +119,16 @@ endif() # THE COMPILATION DIRECTIVES # ### ### -qt_add_library(lektor_c SHARED common.cc mainwindow.cc module_qt_window.cc mpvwidget.cc) -qt_add_library(lektor_c_static STATIC common.cc mainwindow.cc module_qt_window.cc mpvwidget.cc) +if(WIN32) + set(LEKTOR_C_SRC common.cc mainwindow.cc module_qt_window.cc mpvwidget.cc dll.cc) +else() + set(LEKTOR_C_SRC common.cc mainwindow.cc module_qt_window.cc mpvwidget.cc) +endif() +qt_add_library(lektor_c SHARED ${LEKTOR_C_SRC}) +qt_set_finalizer_mode(lektor_c ENABLE MODES static_plugins) -foreach(target lektor_c lektor_c_static) +foreach(target lektor_c) set_property(TARGET ${target} PROPERTY CXX_STANDARD 20) - target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_definitions(${target} PRIVATE LKT_ARCH="${CMAKE_SYSTEM_PROCESSOR}" @@ -147,18 +147,15 @@ foreach(target lektor_c lektor_c_static) ${${CMAKE_BUILD_TYPE}_${CMAKE_C_COMPILER_ID}_C_FLAGS} ${${CMAKE_BUILD_TYPE}_${CMAKE_CXX_COMPILER_ID}_C_FLAGS} ) + target_link_libraries(${target} PRIVATE ${MPV_LIBRARY} ${CMAKE_DL_LIBS}) + target_link_libraries(${target} PRIVATE Qt::Widgets Qt::OpenGL Qt::OpenGLWidgets) - target_link_options(${target} PRIVATE -Wl,-rpath,. -rdynamic) - target_link_libraries(${target} - PRIVATE - ${MPV_LIBRARY} - ${CMAKE_DL_LIBS} - Qt::Widgets - Qt::OpenGL - Qt::OpenGLWidgets - ) + if(UNIX) + target_link_options(${target} PRIVATE -Wl,-rpath,. -rdynamic) + endif() if(WIN32) - target_link_libraries(${TARGET} PRIVATE regex dlfcn-win32::dl ws2_32) + # target_link_options(${target} PRIVATE -Wl,--export-all-symbols) + target_link_libraries(${target} PRIVATE regex dlfcn-win32::dl ws2_32) endif() endforeach() diff --git a/lektord/c/common.cc b/lektord/c/common.cc index d1de4bb684bd8e02117e36eb39a044058dda8948..4521462e2508b8a1c0fe0d9c8d2109d51df1aa64 100644 --- a/lektord/c/common.cc +++ b/lektord/c/common.cc @@ -89,8 +89,8 @@ safe_strncpy(char *dest, const char *src, size_t n) } extern "C" { -void ___lkt_log_rs(int, const char *const, const char *const, const char *const, uint64_t, - const char *const); +DLL_IMPORT void ___lkt_log_rs(int, const char *const, const char *const, const char *const, + uint64_t, const char *const); } void @@ -107,8 +107,7 @@ ___lkt_log(LOG_LEVEL level, const char *section, const char *func, const char *f va_list ap; va_start(ap, format); - const ssize_t count = - safe_vsnprintf(line, BUFFER_MAX, format, ap); + const ssize_t count = safe_vsnprintf(line, BUFFER_MAX, format, ap); va_end(ap); /* Check for overflow */ diff --git a/lektord/c/common.h b/lektord/c/common.h index 717202111aae9dd0c4c62974f178aa7cd971705f..7ca898911619c9599574e8885768f4019fc26088 100644 --- a/lektord/c/common.h +++ b/lektord/c/common.h @@ -2,7 +2,6 @@ #include <inttypes.h> #include <locale.h> -#include <langinfo.h> #include <memory.h> #include <regex.h> #include <stddef.h> @@ -22,6 +21,7 @@ #include <ctype.h> #if defined(LKT_OS_TOASTER) && (LKT_OS_TOASTER == 1) +#include <langinfo.h> #include <linux/limits.h> #include <dirent.h> #include <fcntl.h> @@ -29,6 +29,11 @@ #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> +#define DLL_IMPORT extern + +#elif defined(LKT_OS_MINGW) && (LKT_OS_MINGW == 1) +#define DLL_IMPORT __declspec(dllimport) + #endif typedef void (*function_ptr)(void); @@ -138,7 +143,7 @@ void(___lkt_assert)(const char *file, int line, const char *func, const char *ms /* Custom defined abort. */ extern "C" { -extern EXIT_FUNCTION ___lkt_abort(void); +DLL_IMPORT EXIT_FUNCTION ___lkt_abort(void); #ifdef abort #undef abort #endif diff --git a/lektord/c/dll.cc b/lektord/c/dll.cc new file mode 100644 index 0000000000000000000000000000000000000000..f4928a128731dcbc952c4ab6cc83d935abf02462 --- /dev/null +++ b/lektord/c/dll.cc @@ -0,0 +1,47 @@ +#include <windows.h> + +void *__imp____lkt_abort; +void *__imp____lkt_log_rs; +void *__imp_lkt_toggle_play_state; +void *__imp_lkt_play_next; +void *__imp_lkt_play_prev; + +#define IMPORT_FUNCTION(name) \ + *(void **)&__imp_##name = (void *)GetProcAddress(GetModuleHandle(0), "__imp_" #name) + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, // handle to DLL module + DWORD fdwReason, // reason for calling function + LPVOID lpvReserved) // reserved +{ + // Perform actions based on the reason for calling. + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + IMPORT_FUNCTION(___lkt_abort); + IMPORT_FUNCTION(___lkt_log_rs); + IMPORT_FUNCTION(lkt_toggle_play_state); + IMPORT_FUNCTION(lkt_play_next); + IMPORT_FUNCTION(lkt_play_prev); + + // Initialize once for each new process. + // Return FALSE to fail DLL load. + break; + + case DLL_THREAD_ATTACH: + // Do thread-specific initialization. + break; + + case DLL_THREAD_DETACH: + // Do thread-specific cleanup. + break; + + case DLL_PROCESS_DETACH: + if (lpvReserved != nullptr) { + break; // do not do cleanup if process termination scenario + } + + // Perform any necessary cleanup. + break; + } + return TRUE; // Successful DLL_PROCESS_ATTACH. +} diff --git a/lektord/c/module_qt_window.hh b/lektord/c/module_qt_window.hh index b0a4aee3cf1a072179cbbe3bc9a2ffa3455c4da6..16c5bcbfc6a75008bee7ae7891d6d041cc7b69ec 100644 --- a/lektord/c/module_qt_window.hh +++ b/lektord/c/module_qt_window.hh @@ -31,9 +31,9 @@ static inline uint64_t module_font_size = 0; static inline uint64_t module_msg_len_sec = 0; static inline bool module_force_x11 = false; -extern void lkt_toggle_play_state(int); -extern void lkt_play_next(void); -extern void lkt_play_prev(void); +DLL_IMPORT void lkt_toggle_play_state(int); +DLL_IMPORT void lkt_play_next(void); +DLL_IMPORT void lkt_play_prev(void); enum LKT_PLAY_STATE { LKT_PLAY_STOP = 0,