diff --git a/build-config/quill/meson.build b/build-config/quill/meson.build index c6105b1..15c1fc6 100644 --- a/build-config/quill/meson.build +++ b/build-config/quill/meson.build @@ -1,15 +1,23 @@ +cmake = import('cmake') + quill_cmake_options = cmake.subproject_options() quill_cmake_options.add_cmake_defines({ - 'BUILD_SHARED_LIBS': 'ON', - 'CMAKE_SKIP_INSTALL_RULES': 'ON' + 'BUILD_STATIC_LIBS': 'ON', + 'BUILD_SHARED_LIBS': 'OFF', + 'CMAKE_SKIP_INSTALL_RULES': 'ON', + 'CMAKE_POSITION_INDEPENDENT_CODE': 'ON' }) + quill_sp = cmake.subproject( 'quill', options: quill_cmake_options, ) + quill_dep = quill_sp.dependency('quill') -message('Registering quill headers (' + meson.global_source_root() + '/subprojects/quill/include/quill) for installation...') -quill_headers = meson.global_source_root() + '/subprojects/quill/include/quill' -install_subdir(quill_headers, install_dir: get_option('includedir')) -message('Done registering quill headers for installation!') +if get_option('default_library') != 'static' + message('Registering quill headers for installation...') + # Note: verify this path matches your source structure + quill_headers = meson.global_source_root() + '/subprojects/quill/include/quill' + install_subdir(quill_headers, install_dir: get_option('includedir')) +endif diff --git a/cross/macos_arm64.ini b/cross/macos_arm64.ini new file mode 100644 index 0000000..74dd72a --- /dev/null +++ b/cross/macos_arm64.ini @@ -0,0 +1,19 @@ +[binaries] +c = 'arm64-apple-darwin25-clang' +cpp = 'arm64-apple-darwin25-clang++' +ar = 'arm64-apple-darwin25-ar' +strip = 'arm64-apple-darwin25-strip' +pkg-config = 'pkg-config' +ranlib = '/usr/bin/true' + +[host_machine] +system = 'darwin' +cpu_family = 'aarch64' +cpu = 'arm64' +endian = 'little' + +[built-in options] +c_args = ['-mmacosx-version-min=15.0'] +cpp_args = ['-mmacos-version-min=15.0'] +c_link_args = ['-mmacosx-version-min=15.0'] +cpp_link_args = ['-mmacos-version-min=15.0'] diff --git a/cross/wasm.ini b/cross/wasm.ini new file mode 100644 index 0000000..5a7f6f7 --- /dev/null +++ b/cross/wasm.ini @@ -0,0 +1,23 @@ +[binaries] +c = 'emcc' +cpp = 'em++' +ar = 'emar' +strip = 'emstrip' + +exec_wrapper = 'node' + +[built-in options] +c_args = ['-Dpkg_config=false', '-Dbuild_tests=false', '-Dbuild_examples=true', '-s', 'MEMORY64=1', '-pthread', '-DQUILL_NO_THREAD_NAME_SUPPORT', '-DQUILL_IMMEDIATE_FLUSH'] +cpp_args = ['-Dpkg_config=false', '-Dbuild_tests=false', '-Dbuild_examples=true', '-fwasm-exceptions', '-s', 'MEMORY64=1', '-pthread', '-DQUILL_NO_THREAD_NAME_SUPPORT', '-DQUILL_IMMEDIATE_FLUSH'] +c_link_args = ['-s', 'WASM=1', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'MEMORY64=1', '-fwasm-exceptions', '-pthread', '-s', 'EXPORTED_RUNTIME_METHODS=["FS", "callMain"]'] +cpp_link_args = ['-s', 'WASM=1', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'MEMORY64=1', '-fwasm-exceptions', '-pthread', '-s', 'EXPORTED_RUNTIME_METHODS=["FS", "callMain"]'] + +[host_machine] +system = 'emscripten' +cpu_family = 'wasm64' +cpu = 'wasm64' +endian = 'little' + +[properties] +cmake_toolchain_file = '/home/tboudreaux/Programming/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake' + diff --git a/examples/meson.build b/examples/meson.build new file mode 100644 index 0000000..626f153 --- /dev/null +++ b/examples/meson.build @@ -0,0 +1 @@ +executable('simple_logging_test', 'simple.cpp', dependencies: [logging_dep]) diff --git a/examples/simple.cpp b/examples/simple.cpp new file mode 100644 index 0000000..09243de --- /dev/null +++ b/examples/simple.cpp @@ -0,0 +1,16 @@ +#include +#include + +#include "quill/LogMacros.h" + +#include "fourdst/logging/logging.h" + + +int main() { + auto& logManager = fourdst::logging::LogManager::getInstance(); + quill::Logger* logger = logManager.newFileLogger("test.log", "logger"); + + std::cout << "Logging...\n"; + LOG_INFO(logger, "This is an info message: {}", 42); + std::cout << "Done Logging\n"; +} diff --git a/meson.build b/meson.build index a281864..a93a808 100644 --- a/meson.build +++ b/meson.build @@ -18,15 +18,24 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # *********************************************************************** # -project('liblogging', 'cpp', version: 'v1.1.0', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0') +project('liblogging', 'cpp', version: 'v1.1.1', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0') # Add default visibility for all C++ targets add_project_arguments('-fvisibility=default', language: 'cpp') + + subdir('build-config') subdir('src') -subdir('tests') -if get_option('pkg-config') +if get_option('build_tests') + subdir('tests') +endif + +if get_option('build_examples') + subdir('examples') +endif + +if get_option('pkg_config') message('Generating pkg-config file for liblogging...') pkg = import('pkgconfig') pkg.generate( diff --git a/meson_options.txt b/meson_options.txt index 1c45a6e..bebd86f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,3 @@ -option('pkg-config', type: 'boolean', value: true, description: 'generate pkg-config file for liblogging (fourdst_liblogging.pc)') +option('pkg_config', type: 'boolean', value: true, description: 'generate pkg-config file for liblogging (fourdst_liblogging.pc)') +option('build_tests', type: 'boolean', value: true, description: 'generate unit tests (uses gtest)') +option('build_examples', type: 'boolean', value: true, description: 'generate example programs') diff --git a/src/logging/include/fourdst/logging/logging.h b/src/logging/include/fourdst/logging/logging.h index b9addc7..9a536eb 100644 --- a/src/logging/include/fourdst/logging/logging.h +++ b/src/logging/include/fourdst/logging/logging.h @@ -24,7 +24,6 @@ #include #include #include -#include #include "quill/Logger.h" diff --git a/src/logging/lib/logging.cpp b/src/logging/lib/logging.cpp index be1c234..41fb7fd 100644 --- a/src/logging/lib/logging.cpp +++ b/src/logging/lib/logging.cpp @@ -22,17 +22,17 @@ #include "quill/Frontend.h" #include "quill/Logger.h" #include "quill/sinks/ConsoleSink.h" -#include "quill/sinks/FileSink.h" -#include "quill/LogMacros.h" +#include "quill/sinks/FileSink.h" -#include +#include #include -#include -#include -#include #include #include -#include + +#if defined(__EMSCRIPTEN__) + #include +#endif + #include "fourdst/logging/logging.h" @@ -41,28 +41,43 @@ namespace fourdst::logging { LogManager::LogManager() { quill::Backend::start(); + auto CLILogger = quill::Frontend::create_or_get_logger( "root", quill::Frontend::create_or_get_sink("sink_id_1")); newFileLogger("fourdst.log", "log"); + loggerMap.emplace("stdout", CLILogger); } +#if defined(__EMSCRIPTEN__) + +LogManager::~LogManager() { + for (const auto& logger : loggerMap | std::views::values) { + logger->flush_log(); + } + quill::Backend::stop(); +} + +#else + LogManager::~LogManager() = default; +#endif + quill::Logger* LogManager::getLogger(const std::string& loggerName) { - auto it = loggerMap.find(loggerName); // Find *once* + auto it = loggerMap.find(loggerName); if (it == loggerMap.end()) { throw std::runtime_error("Cannot find logger " + loggerName); } - return it->second; // Return the raw pointer from the shared_ptr + return it->second; } std::vector LogManager::getLoggerNames() { std::vector loggerNames; loggerNames.reserve(loggerMap.size()); - for (const auto& pair : loggerMap) { // Use range-based for loop and const auto& + for (const auto& pair : loggerMap) { loggerNames.push_back(pair.first); } return loggerNames; @@ -72,13 +87,21 @@ std::vector LogManager::getLoggers() { std::vector loggers; loggers.reserve(loggerMap.size()); for (const auto& pair : loggerMap) { - loggers.push_back(pair.second); // Get the raw pointer + loggers.push_back(pair.second); } return loggers; } quill::Logger* LogManager::newFileLogger(const std::string& filename, - const std::string& loggerName) { + const std::string& loggerName) { + +#if defined(__EMSCRIPTEN__) + auto proxy_sink = quill::Frontend::create_or_get_sink("sink_id_1"); + quill::Logger* rawLogger = quill::Frontend::create_or_get_logger(loggerName, std::move(proxy_sink)); + + loggerMap.emplace(loggerName, rawLogger); + return rawLogger; +#else auto file_sink = quill::Frontend::create_or_get_sink( filename, []() { @@ -87,12 +110,13 @@ quill::Logger* LogManager::newFileLogger(const std::string& filename, return cfg; }(), quill::FileEventNotifier{}); - // Get the raw pointer. + quill::Logger* rawLogger = quill::Frontend::create_or_get_logger(loggerName, std::move(file_sink)); - // Create a shared_ptr from the raw pointer. loggerMap.emplace(loggerName, rawLogger); return rawLogger; +#endif } -} // namespace Probe +} + diff --git a/subprojects/packagefiles/quill/add_wasm_rdtsc_fallback_support.patch b/subprojects/packagefiles/quill/add_wasm_rdtsc_fallback_support.patch new file mode 100644 index 0000000..42f6c03 --- /dev/null +++ b/subprojects/packagefiles/quill/add_wasm_rdtsc_fallback_support.patch @@ -0,0 +1,20 @@ +--- quill/include/quill/core/Rdtsc.h.orig 2025-12-03 09:43:26.530875697 -0500 ++++ quill/include/quill/core/Rdtsc.h 2025-12-03 09:42:49.852913743 -0500 +@@ -16,7 +16,7 @@ + #elif defined(__ARM_ARCH) + #include + #include +-#elif (defined(_M_ARM) || defined(_M_ARM64)) ++#elif (defined(_M_ARM) || defined(_M_ARM64) || defined(__wasm__)) + #include + #include + #elif (defined(__PPC64__)) +@@ -72,7 +72,7 @@ + // soft failover + return static_cast(std::chrono::system_clock::now().time_since_epoch().count()); + } +-#elif (defined(_M_ARM) || defined(_M_ARM64) || defined(__PPC64__)) ++#elif (defined(_M_ARM) || defined(_M_ARM64) || defined(__PPC64__) || defined(__wasm__)) + QUILL_NODISCARD QUILL_ATTRIBUTE_HOT inline uint64_t rdtsc() noexcept + { + // soft failover diff --git a/subprojects/packagefiles/quill/enable_pthread_header_emscripted.patch b/subprojects/packagefiles/quill/enable_pthread_header_emscripted.patch new file mode 100644 index 0000000..f9c243d --- /dev/null +++ b/subprojects/packagefiles/quill/enable_pthread_header_emscripted.patch @@ -0,0 +1,36 @@ +--- quill/inlcude/quill/backend/BackendUtilities.h.orig 2025-12-03 10:02:26.861779737 -0500 ++++ quill/include/quill/backend/BackendUtilities.h 2025-12-03 10:09:04.509482559 -0500 +@@ -35,7 +35,7 @@ + #elif defined(__CYGWIN__) + #include + #include +-#elif defined(__linux__) ++#elif (defined(__linux__) || defined(__EMSCRIPTEN__)) + #include + #include + #include +@@ -84,6 +84,8 @@ + thread_port_t mach_thread = pthread_mach_thread_np(pthread_self()); + + thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1); ++#elif defined(__EMSCRIPTEN__) ++ (void)cpu_id; + #else + cpu_set_t cpuset; + CPU_ZERO(&cpuset); +@@ -102,7 +104,7 @@ + /***/ + QUILL_ATTRIBUTE_COLD inline void set_thread_name(char const* name) + { +-#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(QUILL_NO_THREAD_NAME_SUPPORT) ++#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(QUILL_NO_THREAD_NAME_SUPPORT) || defined(__EMSCRIPTEN__) + // Disabled on MINGW / Cygwin. + (void)name; + #elif defined(_WIN32) +@@ -154,4 +156,4 @@ + } + } // namespace detail + +-QUILL_END_NAMESPACE +\ No newline at end of file ++QUILL_END_NAMESPACE diff --git a/subprojects/quill.wrap b/subprojects/quill.wrap index d857641..bfa6910 100644 --- a/subprojects/quill.wrap +++ b/subprojects/quill.wrap @@ -1,5 +1,6 @@ [wrap-git] url = https://github.com/odygrd/quill revision = v8.1.1 +diff_files = quill/add_wasm_rdtsc_fallback_support.patch, quill/enable_pthread_header_emscripted.patch -[cmake] \ No newline at end of file +[cmake]