diff --git a/.gitignore b/.gitignore index 47ca150..6e8c37c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ examples/CMakeUserPresets.json CMakeUserPresets.json .vscode Testing +conan_imports_manifest.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 876d098..96bcc75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,18 +14,25 @@ set(SPDLOG_FMT_EXTERNAL 1) find_package(spdlog REQUIRED) find_package(nlohmann_json REQUIRED) find_package(PahoMqttCpp REQUIRED) -find_package(GTest REQUIRED) -find_package(cppcheck REQUIRED) find_package(magic_enum REQUIRED) -if (CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT BUILD_SHARED_LIBS) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-allow-multiple-definition") +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + find_package(GTest REQUIRED) + find_package(cppcheck REQUIRED) endif() + if (CMAKE_SYSTEM_NAME MATCHES "Windows") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") - set(CMAKE_CROSSCOMPILING_EMULATOR "wine") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition") +elseif (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT BUILD_SHARED_LIBS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition") +endif() + +if (CMAKE_SYSTEM_NAME MATCHES "Windows" AND NOT BUILD_SHARED_LIBS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") endif() +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) add_library(${LIBRARY_NAME}) @@ -44,13 +51,21 @@ target_include_directories(${LIBRARY_NAME} PUBLIC ) target_link_libraries(${LIBRARY_NAME} - $<$>,$>:PahoMqttCpp::paho-mqttpp3-static> - $<$,$>>:PahoMqttCpp::paho-mqttpp3> + $<$:PahoMqttCpp::paho-mqttpp3> + $<$>:PahoMqttCpp::paho-mqttpp3-static> spdlog::spdlog nlohmann_json::nlohmann_json magic_enum::magic_enum ) +if (CMAKE_SYSTEM_NAME MATCHES "Windows" AND BUILD_SHARED_LIBS) + add_custom_command(TARGET ${LIBRARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/bin/*.dll + $ + ) +endif() + set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} diff --git a/cmake/cppcheck.cmake b/cmake/cppcheck.cmake index 3a7f938..56ffbb1 100644 --- a/cmake/cppcheck.cmake +++ b/cmake/cppcheck.cmake @@ -1,14 +1,14 @@ -# Add a target for cppcheck -find_program(CPPCHECK_EXECUTABLE cppcheck) -if(CPPCHECK_EXECUTABLE) - # cppcheck igner never used functions - add_custom_target(check - ${CPPCHECK_EXECUTABLE} --enable=all --suppress=missingIncludeSystem --suppress=unusedFunction - --template "{file}:{line}:{severity}:{id}:{message}" - -I ${CMAKE_SOURCE_DIR}/source - ${CMAKE_SOURCE_DIR}/source - COMMENT "Running Cppcheck static analysis tool" - ) -else() - message(WARNING "Cppcheck not found, can't run static analysis") +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + find_program(CPPCHECK_EXECUTABLE cppcheck) + if(CPPCHECK_EXECUTABLE) + add_custom_target(check + ${CPPCHECK_EXECUTABLE} --enable=all --suppress=missingIncludeSystem --suppress=unusedFunction + --template "{file}:{line}:{severity}:{id}:{message}" + -I ${CMAKE_SOURCE_DIR}/source + ${CMAKE_SOURCE_DIR}/source + COMMENT "Running Cppcheck static analysis tool" + ) + else() + message(WARNING "Cppcheck not found, can't run static analysis") + endif() endif() diff --git a/conan_profiles/x86_64_Cross_Windows b/conan_profiles/x86_64_Cross_Windows index 0f953d4..d7b63fe 100644 --- a/conan_profiles/x86_64_Cross_Windows +++ b/conan_profiles/x86_64_Cross_Windows @@ -1,19 +1,18 @@ -$toolchain=/usr/x86_64-w64-mingw32 # Adjust this path target_host=x86_64-w64-mingw32 -cc_compiler=gcc -cxx_compiler=g++ [env] -CONAN_CMAKE_FIND_ROOT_PATH=$toolchain CHOST=$target_host AR=$target_host-ar AS=$target_host-as RANLIB=$target_host-ranlib -CC=$target_host-$cc_compiler -CXX=$target_host-$cxx_compiler +CC=$target_host-gcc +CXX=$target_host-g++ STRIP=$target_host-strip RC=$target_host-windres +[conf] +tools.build:compiler_executables={"cpp": "$target_host-g++", "c": "$target_host-gcc"} + # We are cross building to Windows [settings] os=Windows diff --git a/conan_profiles/x86_64_Linux b/conan_profiles/x86_64_Linux index d17b05f..4721d8f 100644 --- a/conan_profiles/x86_64_Linux +++ b/conan_profiles/x86_64_Linux @@ -1,13 +1,6 @@ [settings] os=Linux -os_build=Linux arch=x86_64 -arch_build=x86_64 compiler=gcc compiler.version=13 compiler.libcxx=libstdc++11 -build_type=Release -[options] -[build_requires] -[env] - diff --git a/conanfile.py b/conanfile.py index e82a7d3..4e0507d 100644 --- a/conanfile.py +++ b/conanfile.py @@ -21,18 +21,16 @@ def requirements(self): self.requires("paho-mqtt-cpp/[>=1.2.0]") self.requires("spdlog/[>=1.11.0]") self.requires("nlohmann_json/[>=3.11.2]") - self.requires("gtest/cci.20210126") - self.requires("cppcheck/[>=2.10]") self.requires("magic_enum/[>=0.9.2]") + if self.settings.os == "Linux": + self.requires("gtest/cci.20210126") + self.requires("cppcheck/[>=2.10]") def layout(self): cmake_layout(self, build_folder=os.getcwd()) def configure(self): - if self.settings.os == "Windows": - self.options["*"].shared = False - else: - self.options["*"].shared = self.options.shared + self.options["*"].shared = self.options.shared def generate(self): tc = CMakeToolchain(self) @@ -49,4 +47,14 @@ def build(self): def package(self): cmake = CMake(self) - cmake.install() \ No newline at end of file + cmake.install() + + def imports(self): + if self.settings.os == "Windows" and self.options.shared: + folder = f"{self.build_folder}/bin" + self.copy("*.dll", dst=folder, src="bin") + mingw_dlls = ["libgcc_s_seh-1.dll", "libwinpthread-1.dll", "libstdc++-6.dll"] + mingw_dll_path = "/usr/x86_64-w64-mingw32/bin" + for dll in mingw_dlls: + self.copy(dll, dst=folder, src=mingw_dll_path) + diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index fca323a..f4150bf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,7 +5,14 @@ set(examples foreach(example ${examples}) add_executable(${example} ${example}.cxx) set_target_properties(${example} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/examples" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/examples/bin" ) target_link_libraries(${example} ${LIBRARY_NAME}) -endforeach() \ No newline at end of file + if (CMAKE_SYSTEM_NAME MATCHES "Windows" AND BUILD_SHARED_LIBS) + add_custom_command(TARGET ${example} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/bin/*.dll + $ + ) + endif() +endforeach() diff --git a/examples/bps.cxx b/examples/bps.cxx index ff1b6b2..d4145c2 100644 --- a/examples/bps.cxx +++ b/examples/bps.cxx @@ -36,10 +36,12 @@ int main(void) //bps_channel->voltmeter.set_measure_polling_cycle(2); //bps_channel->ampermeter.set_measure_polling_cycle(2); - bps_channel->ctrl.set_enable_polling_cycle(2); + //bps_channel->ctrl.set_enable_polling_cycle(2); } spdlog::info("\n\nOK\n\n"); + cli->disconnect(); + return 0; } diff --git a/scripts/build.sh b/scripts/build.sh index 64d2cf1..f0f04d4 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -21,6 +21,8 @@ function install_deps { echo "Installing dependencies for $TARGET..." if [ "$TARGET" = "Windows" ]; then EXTRA_CONAN_ARGS="-pr:h ../conan_profiles/x86_64_Cross_Windows" + else + EXTRA_CONAN_ARGS="-pr:h ../conan_profiles/x86_64_Linux" fi mkdir -p $BUILD_DIR cd $BUILD_DIR diff --git a/source/pza/core/attribute.hxx b/source/pza/core/attribute.hxx index 142852c..dbec3e4 100644 --- a/source/pza/core/attribute.hxx +++ b/source/pza/core/attribute.hxx @@ -14,7 +14,7 @@ namespace pza class attribute { public: - friend class interface; + friend class itface; explicit attribute(const std::string &name); diff --git a/source/pza/core/client.hxx b/source/pza/core/client.hxx index 2b3842f..6c51f47 100644 --- a/source/pza/core/client.hxx +++ b/source/pza/core/client.hxx @@ -25,7 +25,7 @@ namespace pza using ptr = std::shared_ptr; friend class device; - friend class interface; + friend class itface; explicit client(const std::string &addr, int port, const std::string &id = ""); diff --git a/source/pza/core/device.cxx b/source/pza/core/device.cxx index 0ec8b7c..0de2bf2 100644 --- a/source/pza/core/device.cxx +++ b/source/pza/core/device.cxx @@ -49,7 +49,7 @@ int device::_set_identity(const std::string &payload) return 0; } -void device::register_interface(interface &interface) +void device::register_interface(itface &itface) { - _interfaces[interface._name] = &interface; + _interfaces[itface._name] = &itface; } \ No newline at end of file diff --git a/source/pza/core/device.hxx b/source/pza/core/device.hxx index 54b969d..5e5c4c4 100644 --- a/source/pza/core/device.hxx +++ b/source/pza/core/device.hxx @@ -19,7 +19,7 @@ namespace pza using ptr = std::shared_ptr; friend class client; - friend class interface; + friend class itface; enum class state : unsigned int { @@ -37,7 +37,7 @@ namespace pza void reset(); enum state get_state() { return _state; } - void register_interface(interface &interface); + void register_interface(itface &itface); protected: device(const std::string &group, const std::string &name); @@ -58,7 +58,7 @@ namespace pza std::string _base_topic; std::string _device_topic; - std::map _interfaces; + std::map _interfaces; enum state _state = state::orphan; }; diff --git a/source/pza/core/interface.cxx b/source/pza/core/interface.cxx index 394b484..d09850d 100644 --- a/source/pza/core/interface.cxx +++ b/source/pza/core/interface.cxx @@ -4,7 +4,7 @@ using namespace pza; -interface::interface(device *device, const std::string &name) +itface::itface(device *device, const std::string &name) : _device(device), _name(name) { @@ -12,7 +12,7 @@ interface::interface(device *device, const std::string &name) _topic_cmd = _topic_base + "/cmds/set"; } -void interface::register_attribute(attribute &attribute) +void itface::register_attribute(attribute &attribute) { std::condition_variable cv; std::unique_lock lock(_mtx); @@ -38,7 +38,7 @@ void interface::register_attribute(attribute &attribute) } } -void interface::register_attributes(const std::vector &list) +void itface::register_attributes(const std::vector &list) { for (auto const &it : list) { register_attribute(*it); diff --git a/source/pza/core/interface.hxx b/source/pza/core/interface.hxx index b0f63ea..655bce6 100644 --- a/source/pza/core/interface.hxx +++ b/source/pza/core/interface.hxx @@ -9,12 +9,12 @@ namespace pza { class device; - class interface + class itface { public: friend class device; - interface(device *device, const std::string &name); + itface(device *device, const std::string &name); void register_attribute(attribute &attribute); void register_attributes(const std::vector &list); diff --git a/source/pza/interfaces/bps_chan_ctrl.cxx b/source/pza/interfaces/bps_chan_ctrl.cxx index d28737a..7732439 100644 --- a/source/pza/interfaces/bps_chan_ctrl.cxx +++ b/source/pza/interfaces/bps_chan_ctrl.cxx @@ -5,7 +5,7 @@ using namespace pza; bps_chan_ctrl::bps_chan_ctrl(device *device, const std::string &name) - : interface(device, name), + : itface(device, name), _volts("volts"), _amps("amps"), _enable("enable") diff --git a/source/pza/interfaces/bps_chan_ctrl.hxx b/source/pza/interfaces/bps_chan_ctrl.hxx index 3ae6f7c..d5346f3 100644 --- a/source/pza/interfaces/bps_chan_ctrl.hxx +++ b/source/pza/interfaces/bps_chan_ctrl.hxx @@ -11,7 +11,7 @@ namespace pza { class device; - class bps_chan_ctrl : public interface + class bps_chan_ctrl : public itface { public: using ptr = std::shared_ptr; diff --git a/source/pza/interfaces/meter.cxx b/source/pza/interfaces/meter.cxx index cb25e3c..1921899 100644 --- a/source/pza/interfaces/meter.cxx +++ b/source/pza/interfaces/meter.cxx @@ -3,7 +3,7 @@ using namespace pza; meter::meter(device *device, const std::string &name) - : interface(device, name), + : itface(device, name), _measure("measure") { _measure.add_ro_field("value"); diff --git a/source/pza/interfaces/meter.hxx b/source/pza/interfaces/meter.hxx index 07894b4..6f79e15 100644 --- a/source/pza/interfaces/meter.hxx +++ b/source/pza/interfaces/meter.hxx @@ -3,7 +3,7 @@ #include namespace pza { - class meter : public interface + class meter : public itface { public: meter(device *device, const std::string &name);