From: pjh9216 Date: Wed, 6 Nov 2024 04:52:00 +0000 (+0900) Subject: Add libopener X-Git-Tag: accepted/tizen/unified/20250114.104251~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=92061cc35974b5e69b59ccf65b72bcc2f8ad986a;p=platform%2Fcore%2Fbase%2Fbundle.git Add libopener - C++ wrapper API for dlopen and dlsym - example tizen_base::LibOpener opener(LIBDIR"/libglib-2.0.so.0"); using GMainContext = void; using GMainLoop = void; auto* g_main_loop_get_context = opener.Bind("g_main_loop_get_context"); Change-Id: Iaea4e2beb05856e4870824f149c5515335a334cc Signed-off-by: pjh9216 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index aaea2db..fb8dc72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(bundle) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(VERSION ${FULLVER}) +SET(LIBDIR ${LIB_INSTALL_DIR}) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") @@ -31,6 +32,7 @@ SET(TARGET_BUNDLE_UNITTESTS "bundle_unittests") SET(TARGET_PARCEL_UNITTESTS "parcel_unittests") SET(TARGET_TIZEN_DATABASE_UNITTESTS "tizen-database_unittests") SET(TARGET_TIZEN_SHARED_QUEUE_UNITTESTS "tizen-shared-queue_unittests") +SET(TARGET_TIZEN_LIBOPENER_UNITTESTS "tizen-libopener_unittests") INCLUDE(FindPkgConfig) INCLUDE(ApplyPkgConfig) @@ -61,3 +63,7 @@ ADD_TEST(NAME ${TARGET_TIZEN_DATABASE_UNITTESTS} ADD_TEST(NAME ${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS} COMMAND ${TARGET_TIZEN_SHARED_QUEUE_UNITTESTS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/tizen-shared-queue_unittests) + +ADD_TEST(NAME ${TARGET_TIZEN_LIBOPENER_UNITTESTS} + COMMAND ${TARGET_TIZEN_LIBOPENER_UNITTESTS} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/tizen-libopener_unittests) diff --git a/packaging/bundle.spec b/packaging/bundle.spec index 75a6e02..8ad10b4 100644 --- a/packaging/bundle.spec +++ b/packaging/bundle.spec @@ -87,6 +87,26 @@ Group: Development/Libraries %description -n parcel-unittests GTest for parcel +################################################# +## tizen-libopener-devel +################################################# +%package -n tizen-libopener-devel +Summary: Tizen-libopener (devel) +Group: Development/Libraries + +%description -n tizen-libopener-devel +C++ wrapper API for dlopen and dlsym + +################################################# +# tizen-libopener-unittests +################################################# +%package -n tizen-libopener-unittests +Summary: GTest for tizen-libopener +Group: Development/Libraries + +%description -n tizen-libopener-unittests +GTest for tizen-libopener + ################################################# ## tizen-database-devel ################################################# @@ -280,6 +300,10 @@ mkdir -p %{buildroot}%{_bindir}/tizen-unittests/tizen-database install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/tizen-database/ sed -i -e 's//tizen-database/g' %{buildroot}%{_bindir}/tizen-unittests/tizen-database/run-unittest.sh +mkdir -p %{buildroot}%{_bindir}/tizen-unittests/tizen-libopener +install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/tizen-libopener/ +sed -i -e 's//tizen-libopener/g' %{buildroot}%{_bindir}/tizen-unittests/tizen-libopener/run-unittest.sh + mkdir -p %{buildroot}%{_bindir}/tizen-unittests/tizen-shared-queue install -m 0755 run-unittest.sh %{buildroot}%{_bindir}/tizen-unittests/tizen-shared-queue/ sed -i -e 's//tizen-shared-queue/g' %{buildroot}%{_bindir}/tizen-unittests/tizen-shared-queue/run-unittest.sh @@ -367,6 +391,17 @@ ln -sf %{_rust_dylibdir}/libtizen_parcel.so %{buildroot}%{_libdir}/libtizen_parc %{_bindir}/parcel_unittests %{_bindir}/tizen-unittests/parcel/run-unittest.sh +################################################# +# tizen-libopener-devel +################################################# +%files -n tizen-libopener-devel +%{_includedir}/tizen-libopener/* +%{_libdir}/pkgconfig/tizen-libopener.pc + +%files -n tizen-libopener-unittests +%{_bindir}/tizen-libopener_unittests +%{_bindir}/tizen-unittests/tizen-libopener/run-unittest.sh + ################################################# # tizen-database-devel ################################################# diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9373d86..713e9b5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,3 +2,4 @@ ADD_SUBDIRECTORY(bundle) ADD_SUBDIRECTORY(parcel) ADD_SUBDIRECTORY(tizen-database) ADD_SUBDIRECTORY(tizen-shared-queue) +ADD_SUBDIRECTORY(tizen-libopener) diff --git a/src/tizen-libopener/CMakeLists.txt b/src/tizen-libopener/CMakeLists.txt new file mode 100644 index 0000000..2d9bae9 --- /dev/null +++ b/src/tizen-libopener/CMakeLists.txt @@ -0,0 +1,7 @@ +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/tizen-libopener.pc.in + ${CMAKE_BINARY_DIR}/tizen-libopener.pc @ONLY) + +INSTALL(FILES ${CMAKE_BINARY_DIR}/tizen-libopener.pc + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/libopener.hpp + DESTINATION include/tizen-libopener) diff --git a/src/tizen-libopener/libopener.hpp b/src/tizen-libopener/libopener.hpp new file mode 100644 index 0000000..bf75704 --- /dev/null +++ b/src/tizen-libopener/libopener.hpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIZEN_LIBOPENER_HPP_ +#define TIZEN_LIBOPENER_HPP_ + +#include + +#include +#include + +namespace tizen_base { + +class LibOpener { + public: + LibOpener(std::string_view lib_path, int flag = RTLD_LAZY | RTLD_GLOBAL) { + handle_ = dlopen(lib_path.data(), flag); + if (handle_ == nullptr) { + throw std::filesystem::filesystem_error("dlopen() failed", std::error_code()); + } + } + + LibOpener() { handle_ = RTLD_DEFAULT; } + + template + T TryBind(std::string_view symbol, T t = nullptr) { + T func_type = reinterpret_cast(dlsym(handle_, symbol.data())); + if (func_type == nullptr) { + return nullptr; + } + + return func_type; + } + + template + T Bind(std::string_view symbol, T t = nullptr) { + T func_type = reinterpret_cast(dlsym(handle_, symbol.data())); + if (func_type == nullptr) { + throw std::filesystem::filesystem_error(dlerror(), std::error_code()); + return nullptr; + } + + return func_type; + } + + ~LibOpener() { + if (handle_ == RTLD_DEFAULT) return; + if (handle_) dlclose(handle_); + } + + private: + void* handle_ = nullptr; +}; + +} // namespace tizen_base + +#endif // TIZEN_LIBOPENER_HPP_ diff --git a/src/tizen-libopener/tizen-libopener.pc.in b/src/tizen-libopener/tizen-libopener.pc.in new file mode 100644 index 0000000..5f4aa3b --- /dev/null +++ b/src/tizen-libopener/tizen-libopener.pc.in @@ -0,0 +1,9 @@ +prefix=@PREFIX@ +includedir=${prefix}/include + +Name: tizen-libopener +Description: C++ wrapper API for dlopen and dlsym +Version: @VERSION@ +Requires: +Cflags: -I${includedir} -I${includedir}/tizen-libopener +cppflags: -I${includedir} -I${includedir}/tizen-libopener diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 30e9d3e..b554db1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,6 +2,7 @@ ADD_SUBDIRECTORY(bundle_unittests) ADD_SUBDIRECTORY(parcel_unittests) ADD_SUBDIRECTORY(tizen-database_unittests) ADD_SUBDIRECTORY(tizen-shared-queue_unittests) +ADD_SUBDIRECTORY(tizen-libopener_unittests) ADD_DEPENDENCIES(${TARGET_BUNDLE_UNITTESTS} ${TARGET_BUNDLE}) ADD_DEPENDENCIES(${TARGET_PARCEL_UNITTESTS} ${TARGET_PARCEL}) diff --git a/tests/tizen-libopener_unittests/CMakeLists.txt b/tests/tizen-libopener_unittests/CMakeLists.txt new file mode 100644 index 0000000..1e9b350 --- /dev/null +++ b/tests/tizen-libopener_unittests/CMakeLists.txt @@ -0,0 +1,22 @@ +ADD_DEFINITIONS("-DLIBDIR=\"${LIBDIR}\"") +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src TIZEN_LIBOPENER_UNITTESTS_SRCS) + +ADD_EXECUTABLE(${TARGET_TIZEN_LIBOPENER_UNITTESTS} + ${TIZEN_LIBOPENER_UNITTESTS_SRCS}) + +TARGET_INCLUDE_DIRECTORIES(${TARGET_TIZEN_LIBOPENER_UNITTESTS} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../ + ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CMAKE_CURRENT_SOURCE_DIR}/../../src + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/tizen-libopener +) + +APPLY_PKG_CONFIG(${TARGET_TIZEN_LIBOPENER_UNITTESTS} PUBLIC + GMOCK_DEPS +) + +TARGET_LINK_LIBRARIES(${TARGET_TIZEN_LIBOPENER_UNITTESTS} PRIVATE + "-ldl") + +INSTALL(TARGETS ${TARGET_TIZEN_LIBOPENER_UNITTESTS} DESTINATION bin) diff --git a/tests/tizen-libopener_unittests/src/test_libopener.cc b/tests/tizen-libopener_unittests/src/test_libopener.cc new file mode 100644 index 0000000..b043439 --- /dev/null +++ b/tests/tizen-libopener_unittests/src/test_libopener.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +#include "tizen-libopener/libopener.hpp" + +namespace {} // namespace + +TEST(LibOpenerTest, Create_N) { + ASSERT_THROW(tizen_base::LibOpener opener("wrong_path/libglib-2.0.so.0"), + std::filesystem::filesystem_error); +} + +TEST(LibOpenerTest, Bind) { + tizen_base::LibOpener opener(LIBDIR"/libglib-2.0.so.0"); + + using GMainContext = void; + using GMainLoop = void; + auto* g_main_loop_get_context = + opener.Bind("g_main_loop_get_context"); + ASSERT_NE(g_main_loop_get_context, nullptr); +} + +TEST(LibOpenerTest, Bind_N) { + tizen_base::LibOpener opener(LIBDIR"/libglib-2.0.so.0"); + + using GMainContext = void; + using GMainLoop = void; + ASSERT_THROW(opener.Bind("wrong_symbol"), + std::filesystem::filesystem_error); +} + +TEST(LibOpenerTest, TryBind) { + tizen_base::LibOpener opener(LIBDIR"/libglib-2.0.so.0"); + + using GMainContext = void; + using GMainLoop = void; + auto* g_main_loop_get_context = + opener.TryBind("g_main_loop_get_context"); + ASSERT_NE(g_main_loop_get_context, nullptr); +} diff --git a/tests/tizen-libopener_unittests/src/test_main.cc b/tests/tizen-libopener_unittests/src/test_main.cc new file mode 100644 index 0000000..da13aab --- /dev/null +++ b/tests/tizen-libopener_unittests/src/test_main.cc @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include + +#include + +int main(int argc, char** argv) { + try { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); + } catch (std::exception const &e) { + std::cout << "test_main caught exception: " << e.what() << std::endl; + return -1; + } +}