From 39a90f7e7ad823e3d591abf3644cce3b7d683544 Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Wed, 24 Jan 2024 11:04:56 -0600 Subject: [PATCH] Replace MODULE_EXPORTS with MMDEVICE_CLIENT_BUILD The new macro has (roughly) the opposite meaning as the (intent of) MODULE_EXPORTS: it should be defined when building MMCore and undefined when building device adapters. The source is now _capable_ of excluding the module interface functions when building MMCore (and the MMCore Meson build does so). Symbol visibility is set for GCC/Clang so that -fvisibility=hidden can be used when building device adapters (but this is not done for now). No changes to device adapters is required. --- MMCore/MMCore.vcxproj | 4 +- MMCore/Makefile.am | 2 + MMCore/meson.build | 7 ++-- MMCoreJ_wrap/Makefile.am | 3 +- MMDevice/MMDevice-SharedRuntime.vcxproj | 4 +- MMDevice/MMDevice-StaticRuntime.vcxproj | 4 +- MMDevice/MMDevice.h | 7 ++-- MMDevice/ModuleInterface.cpp | 5 ++- MMDevice/ModuleInterface.h | 37 ++++++++++--------- MMDevice/meson.build | 9 ++++- MMDevice/meson_options.txt | 3 ++ .../VisualStudio/MMDeviceAdapter.props | 1 - 12 files changed, 50 insertions(+), 36 deletions(-) diff --git a/MMCore/MMCore.vcxproj b/MMCore/MMCore.vcxproj index 413f2b563..3fe6c5a21 100644 --- a/MMCore/MMCore.vcxproj +++ b/MMCore/MMCore.vcxproj @@ -50,7 +50,7 @@ Disabled - NOMINMAX;WIN32;_DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + MMDEVICE_CLIENT_BUILD;NOMINMAX;WIN32;_DEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) EnableFastChecks true @@ -65,7 +65,7 @@ X64 - NOMINMAX;WIN32;NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) + MMDEVICE_CLIENT_BUILD;NOMINMAX;WIN32;NDEBUG;_LIB;_WINDOWS;%(PreprocessorDefinitions) true diff --git a/MMCore/Makefile.am b/MMCore/Makefile.am index 013860a8a..e5d26a97d 100644 --- a/MMCore/Makefile.am +++ b/MMCore/Makefile.am @@ -1,5 +1,7 @@ AUTOMAKE_OPTIONS = foreign subdir-objects +AM_CPPFLAGS = -DMMDEVICE_CLIENT_BUILD + noinst_LTLIBRARIES = libMMCore.la libMMCore_la_LIBADD = ../MMDevice/libMMDevice.la diff --git a/MMCore/meson.build b/MMCore/meson.build index 3049fbb65..8b04fafb3 100644 --- a/MMCore/meson.build +++ b/MMCore/meson.build @@ -4,7 +4,7 @@ project( 'MMCore', 'cpp', - meson_version: '>=1.1.0', # May relax + meson_version: '>=1.2.0', default_options: [ 'cpp_std=c++14', 'warning_level=3', @@ -28,9 +28,10 @@ else endif mmdevice_proj = subproject( 'MMDevice', - # Propagate value of 'tests' option ('yield: true' in MMDeivce's 'tests' - # option did not seem to work; Meson 1.3.1). default_options: { + 'client_interface': true, + # Propagate value of 'tests' option ('yield: true' in MMDeivce's + # 'tests' option did not seem to work; Meson 1.3.1). 'tests': tests_option, }, ) diff --git a/MMCoreJ_wrap/Makefile.am b/MMCoreJ_wrap/Makefile.am index 83fc9e744..8fc832543 100644 --- a/MMCoreJ_wrap/Makefile.am +++ b/MMCoreJ_wrap/Makefile.am @@ -10,9 +10,8 @@ AUTOMAKE_OPTIONS = foreign subdir-objects # (We used to globally use -O by default, rather than -O2, on Linux, presumably # for the above reason (though the intent was never documented). But there is # nothing Linux-specific about this.) -# TODO The flag should come from configure. AM_CXXFLAGS = -fno-strict-aliasing -AM_CPPFLAGS = $(JNI_CPPFLAGS) +AM_CPPFLAGS = $(JNI_CPPFLAGS) -DMMDEVICE_CLIENT_BUILD # This ugly list of headers is necessary to trigger the rebuild of the diff --git a/MMDevice/MMDevice-SharedRuntime.vcxproj b/MMDevice/MMDevice-SharedRuntime.vcxproj index d1e1f8636..8fc7e8ad2 100644 --- a/MMDevice/MMDevice-SharedRuntime.vcxproj +++ b/MMDevice/MMDevice-SharedRuntime.vcxproj @@ -65,7 +65,7 @@ Disabled - WIN32;_DEBUG;_LIB;MODULE_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) Windows @@ -77,7 +77,7 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;MODULE_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) Windows diff --git a/MMDevice/MMDevice-StaticRuntime.vcxproj b/MMDevice/MMDevice-StaticRuntime.vcxproj index be67f1eed..bdb2fce9a 100644 --- a/MMDevice/MMDevice-StaticRuntime.vcxproj +++ b/MMDevice/MMDevice-StaticRuntime.vcxproj @@ -65,7 +65,7 @@ Disabled - WIN32;_DEBUG;_LIB;MODULE_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebug @@ -78,7 +78,7 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;MODULE_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreaded diff --git a/MMDevice/MMDevice.h b/MMDevice/MMDevice.h index ae95e6ec6..f0e60538c 100644 --- a/MMDevice/MMDevice.h +++ b/MMDevice/MMDevice.h @@ -53,7 +53,10 @@ #include -#ifdef MODULE_EXPORTS +#ifdef MMDEVICE_CLIENT_BUILD +// Hide deprecation warnings when building MMCore +# define MM_DEPRECATED(prototype) prototype +#else # ifdef _MSC_VER # define MM_DEPRECATED(prototype) __declspec(deprecated) prototype # elif defined(__GNUC__) @@ -61,8 +64,6 @@ # else # define MM_DEPRECATED(prototype) prototype # endif -#else -# define MM_DEPRECATED(prototype) prototype #endif #ifdef _WIN32 diff --git a/MMDevice/ModuleInterface.cpp b/MMDevice/ModuleInterface.cpp index cbfd83b60..0a3a8a520 100644 --- a/MMDevice/ModuleInterface.cpp +++ b/MMDevice/ModuleInterface.cpp @@ -23,11 +23,12 @@ #include "ModuleInterface.h" +#ifndef MMDEVICE_CLIENT_BUILD + #include #include #include - namespace { struct DeviceInfo @@ -135,3 +136,5 @@ void RegisterDevice(const char* deviceName, MM::DeviceType deviceType, const cha g_registeredDevices.push_back(DeviceInfo(deviceName, deviceType, deviceDescription)); } + +#endif // MMDEVICE_CLIENT_BUILD diff --git a/MMDevice/ModuleInterface.h b/MMDevice/ModuleInterface.h index 4aa5f2301..ecdd760ee 100644 --- a/MMDevice/ModuleInterface.h +++ b/MMDevice/ModuleInterface.h @@ -29,17 +29,6 @@ #include "MMDevice.h" -#ifdef _WIN32 - #ifdef MODULE_EXPORTS - #define MODULE_API __declspec(dllexport) - #else - #define MODULE_API __declspec(dllimport) - #endif -#else - #define MODULE_API -#endif - - /// Module interface version. /** * The Core ensures that any loaded device adapter modules have a matching @@ -50,11 +39,20 @@ // GetModuleVersion() must never change. #define MODULE_INTERFACE_VERSION 10 - -/* - * Exported module interface - */ extern "C" { +#ifndef MMDEVICE_CLIENT_BUILD + +// Make the module interface functions visible from outside the module. +#ifdef _MSC_VER +# define MODULE_API __declspec(dllexport) +#else +# define MODULE_API __attribute__((visibility("default"))) +#endif + + /* + * Exported module interface + */ + /// Initialize the device adapter module. /** * Device adapter modules must provide an implementation of this function. @@ -103,10 +101,10 @@ extern "C" { MODULE_API bool GetDeviceName(unsigned deviceIndex, char* name, unsigned bufferLength); MODULE_API bool GetDeviceType(const char* deviceName, int* type); MODULE_API bool GetDeviceDescription(const char* deviceName, char* name, unsigned bufferLength); +#endif // MMDEVICE_CLIENT_BUILD +#ifdef MMDEVICE_CLIENT_BUILD // Function pointer types for module interface functions - // (Not for use by device adapters) -#ifndef MODULE_EXPORTS typedef void (*fnInitializeModuleData)(); typedef MM::Device* (*fnCreateDevice)(const char*); typedef void (*fnDeleteDevice)(MM::Device*); @@ -116,9 +114,10 @@ extern "C" { typedef bool (*fnGetDeviceName)(unsigned, char*, unsigned); typedef bool (*fnGetDeviceType)(const char*, int*); typedef bool (*fnGetDeviceDescription)(const char*, char*, unsigned); -#endif +#endif // MMDEVICE_CLIENT_BUILD } +#ifndef MMDEVICE_CLIENT_BUILD /* * Functions for use by the device adapter module @@ -135,3 +134,5 @@ extern "C" { * \see InitializeModuleData() */ void RegisterDevice(const char* deviceName, MM::DeviceType deviceType, const char* description); + +#endif // MMDEVICE_CLIENT_BUILD diff --git a/MMDevice/meson.build b/MMDevice/meson.build index dcddc8cb0..094d22430 100644 --- a/MMDevice/meson.build +++ b/MMDevice/meson.build @@ -11,6 +11,11 @@ project( ], ) +build_mode_args = [] +if get_option('client_interface') + build_mode_args += '-DMMDEVICE_CLIENT_BUILD' +endif + # We intentionally do NOT define NOMINMAX on Windows. MMDevice should compile # correctly with or without Windows.h's min()/max() macros. @@ -43,8 +48,7 @@ mmdevice_lib = static_library( 'MMDevice', sources: mmdevice_sources, include_directories: mmdevice_include_dir, - cpp_args: [ - '-DMODULE_EXPORTS', + cpp_args: build_mode_args + [ '-D_CRT_SECURE_NO_WARNINGS', # TODO Eliminate the need ], # MMDevice does not depend on any external library. This is a big advantage @@ -58,6 +62,7 @@ mmdevice_lib = static_library( subdir('unittest') mmdevice = declare_dependency( + compile_args: build_mode_args, include_directories: mmdevice_include_dir, link_with: mmdevice_lib, ) diff --git a/MMDevice/meson_options.txt b/MMDevice/meson_options.txt index 4f5d777ee..d10a16fb8 100644 --- a/MMDevice/meson_options.txt +++ b/MMDevice/meson_options.txt @@ -1,3 +1,6 @@ +option('client_interface', type: 'boolean', value: false, + description: 'Build for use by MMCore, as opposed to by a device adapter', +) option('tests', type: 'feature', value: 'enabled', yield: true, description: 'Build unit tests', ) diff --git a/buildscripts/VisualStudio/MMDeviceAdapter.props b/buildscripts/VisualStudio/MMDeviceAdapter.props index 7e4e52053..04ab5bc99 100644 --- a/buildscripts/VisualStudio/MMDeviceAdapter.props +++ b/buildscripts/VisualStudio/MMDeviceAdapter.props @@ -7,7 +7,6 @@ - MODULE_EXPORTS;%(PreprocessorDefinitions) $(MM_MMDEVICE_INCLUDEDIR);$(MM_BOOST_INCLUDEDIR);%(AdditionalIncludeDirectories)