This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/cxx in repository https://gitbox.apache.org/repos/asf/celix.git
commit eec8e08ca39f6211a0eeb156c35c8edc7b6df9e8 Author: Pepijn Noltes <pepijnnol...@gmail.com> AuthorDate: Sat Jan 5 11:56:05 2019 +0100 CELIX-438: Adds bundle register for __APPLE__ --- CMakeLists.txt | 12 ++--- bundles/CMakeLists.txt | 14 +++--- bundles/shell/CMakeLists.txt | 8 ++-- bundles/shell/cxx_shell/CMakeLists.txt | 6 ++- bundles/shell/cxx_shell/src/ShellActivator.cc | 67 ++++++++++++++++++++++++--- bundles/shell/cxx_shell_tui/CMakeLists.txt | 2 +- bundles/shell/cxx_shell_tui/src/shell_test.cc | 3 +- cmake/celix_project/AddGLog.cmake | 10 ++-- cmake/celix_project/AddGTest.cmake | 2 +- cmake/celix_project/AddLibzip.cmake | 10 ++-- libs/CMakeLists.txt | 9 ++-- libs/framework/src/bundle_archive.c | 5 +- libs/framework_cxx/CMakeLists.txt | 5 +- libs/framework_cxx/gtest/CMakeLists.txt | 2 +- libs/framework_cxx/src/Framework.cc | 4 +- 15 files changed, 114 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7025630..8d0b790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ set(CELIX_MAJOR "3") set(CELIX_MINOR "0") set(CELIX_MICRO "0") -option(ENABLE_TESTING "Enables unit testing" OFF) +option(ENABLE_TESTING "Enables unit testing" ON) if (ENABLE_TESTING) enable_testing() @@ -70,15 +70,15 @@ add_subdirectory(libs) add_subdirectory(bundles) #Example as last, because some example will check if underlining options are enabled -add_subdirectory(examples/celix-examples examples) +#TODO add_subdirectory(examples/celix-examples examples) #export targets -install(EXPORT celix NAMESPACE Celix:: DESTINATION share/celix/cmake FILE Targets.cmake COMPONENT cmake) -install_celix_targets(celix NAMESPACE Celix:: DESTINATION share/celix/cmake FILE CelixTargets.cmake COMPONENT cmake) +#install(EXPORT celix NAMESPACE Celix:: DESTINATION share/celix/cmake FILE Targets.cmake COMPONENT cmake) +#install_celix_targets(celix NAMESPACE Celix:: DESTINATION share/celix/cmake FILE CelixTargets.cmake COMPONENT cmake) #install celix cmake modules -install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/Modules/ DESTINATION share/celix/cmake/Modules) -install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmake_celix/ DESTINATION share/celix/cmake/cmake_celix) +#install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/Modules/ DESTINATION share/celix/cmake/Modules) +#install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmake_celix/ DESTINATION share/celix/cmake/cmake_celix) #configure and install CelixConfig and CelixConfigVersion files configure_file(cmake/CelixConfigVersion.cmake.in diff --git a/bundles/CMakeLists.txt b/bundles/CMakeLists.txt index 5ed4054..847b1f0 100644 --- a/bundles/CMakeLists.txt +++ b/bundles/CMakeLists.txt @@ -15,11 +15,11 @@ # specific language governing permissions and limitations # under the License. -add_subdirectory(config_admin) -add_subdirectory(device_access) -add_subdirectory(deployment_admin) -add_subdirectory(remote_services) +#add_subdirectory(config_admin) +#add_subdirectory(device_access) +#add_subdirectory(deployment_admin) +#add_subdirectory(remote_services) add_subdirectory(shell) -add_subdirectory(log_writer) -add_subdirectory(log_service) -add_subdirectory(pubsub) \ No newline at end of file +#add_subdirectory(log_writer) +#add_subdirectory(log_service) +#add_subdirectory(pubsub) \ No newline at end of file diff --git a/bundles/shell/CMakeLists.txt b/bundles/shell/CMakeLists.txt index 851d601..c3d0196 100644 --- a/bundles/shell/CMakeLists.txt +++ b/bundles/shell/CMakeLists.txt @@ -15,10 +15,10 @@ # specific language governing permissions and limitations # under the License. -add_subdirectory(shell) -add_subdirectory(remote_shell) -add_subdirectory(shell_bonjour) -add_subdirectory(shell_tui) +#add_subdirectory(shell) +#add_subdirectory(remote_shell) +#add_subdirectory(shell_bonjour) +#add_subdirectory(shell_tui) add_subdirectory(cxx_shell) add_subdirectory(cxx_shell_tui) diff --git a/bundles/shell/cxx_shell/CMakeLists.txt b/bundles/shell/cxx_shell/CMakeLists.txt index d2b2113..c82d2ef 100644 --- a/bundles/shell/cxx_shell/CMakeLists.txt +++ b/bundles/shell/cxx_shell/CMakeLists.txt @@ -23,7 +23,7 @@ target_include_directories(celix_cxx_shell_api INTERFACE $<INSTALL_INTERFACE:include/celix/shell> ) -#TODO should eventually be done by a CMake command (i.e. bundle_add_resources) +#TODO should eventually be done by a CMake command (i.e. celix_bundle_add_resources) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/celix_cxx_shell_resources.zip COMMAND zip -rq ${CMAKE_CURRENT_BINARY_DIR}/celix_cxx_shell_resources.zip * COMMENT "Packaging Resources" @@ -47,10 +47,12 @@ target_include_directories(celix_cxx_shell PRIVATE src) target_link_libraries(celix_cxx_shell PRIVATE celix_cxx_shell_api glog::glog) target_link_libraries(celix_cxx_shell PUBLIC celix_framework_cxx) add_dependencies(celix_cxx_shell create_resources) + +#TODO should eventually be done by a CMake command (i.e. the add_celix_bundle) if (UNIX AND NOT APPLE) target_link_libraries(celix_cxx_shell PRIVATE -Wl,--format=binary -Wl,celix_cxx_shell_resources.zip -Wl,--format=default) else () - #TODO apple + target_link_libraries(celix_cxx_shell PRIVATE -Wl,-sectcreate -Wl,resources -Wl,celix_cxx_shell -Wl,celix_cxx_shell_resources.zip) endif () diff --git a/bundles/shell/cxx_shell/src/ShellActivator.cc b/bundles/shell/cxx_shell/src/ShellActivator.cc index ea54219..807a9b3 100644 --- a/bundles/shell/cxx_shell/src/ShellActivator.cc +++ b/bundles/shell/cxx_shell/src/ShellActivator.cc @@ -25,8 +25,15 @@ #include "commands.h" +#ifdef __APPLE__ +#include <mach-o/getsect.h> +#include <dlfcn.h> +static uint8_t *resources = nullptr; +#else extern const uint8_t resources[] asm("_binary_celix_cxx_shell_resources_zip_start"); extern const uint8_t resources_end[] asm("_binary_celix_cxx_shell_resources_zip_end"); +#endif + namespace { @@ -54,15 +61,15 @@ namespace { bool commandCalled = false; if (!cmdName.empty()) { - std::string filter = - std::string{"("} + celix::IShellCommand::COMMAND_NAME + "=" + cmdName + ")"; + //first try to call IShellCommand services. + std::string filter = std::string{"("} + celix::IShellCommand::COMMAND_NAME + "=" + cmdName + ")"; commandCalled = ctx->useService<celix::IShellCommand>([&](celix::IShellCommand &cmd) { cmd.executeCommand(cmdName, cmdArgs, out, err); }, filter); } if (!cmdName.empty() && !commandCalled) { - std::string filter = - std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=" + cmdName + ")"; + //if no IShellCommand service is found for the command name, try calling a ShellCommandFunction service. + std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=" + cmdName + ")"; std::function<void(celix::ShellCommandFunction&)> use = [&](celix::ShellCommandFunction &cmd) -> void { cmd(cmdName, cmdArgs, out, err); }; @@ -100,13 +107,61 @@ namespace { }; //NOTE that eventually the (ctor) bundle register will be generated by a CMake command (i.e. add_bundle) - //This also applies for the resources, resources_end asm entries. + //This also applies for the resources, resources_end asm entries or the __APPLE__ variant __attribute__((constructor)) static void registerShellBundle() { + +#ifdef __APPLE__ + //get library info using a addr in the lib (the bundle register function) + Dl_info info; + const void *addr = reinterpret_cast<void*>(®isterShellBundle); + dladdr(addr, &info); + + //get mach header from Dl_info + struct mach_header_64 *header = static_cast<struct mach_header_64*>(info.dli_fbase); + + //get section from mach header based on the seg and sect name + const struct section_64 *sect = getsectbynamefromheader_64(header, "resources", "celix_cxx_shell"); + + //NOTE reading directly form the sect->addr is not possible (BAD_ACCESS), so copy sect part from dylib file. + + //alloc buffer to store resources zip + size_t resourcesLen = sect->size; + resources = (uint8_t*)malloc(resourcesLen); + + //read from dylib. note that the dylib location is in the Dl_info struct. + errno = 0; + FILE *dylib = fopen(info.dli_fname, "r"); + size_t read = 0; + if (dylib != nullptr) { + fseek(dylib, sect->offset, SEEK_SET); + read = fread(resources, 1, sect->size, dylib); + } + if (dylib == nullptr || read != sect->size) { + LOG(WARNING) << "Error reading resources from dylib " << info.dli_fname << ": " << strerror(errno) << std::endl; + free(resources); + resources = nullptr; + resourcesLen = 0; + } + if (dylib != nullptr) { + fclose(dylib); + } +#else + size_t resourcesLen = resources_end - resources; +#endif + + celix::Properties manifest{}; manifest[celix::MANIFEST_BUNDLE_NAME] = "Shell"; manifest[celix::MANIFEST_BUNDLE_GROUP] = "Celix"; manifest[celix::MANIFEST_BUNDLE_VERSION] = "1.0.0"; - celix::registerStaticBundle<ShellBundleActivator>("celix::Shell", manifest, resources, resources_end - resources); + celix::registerStaticBundle<ShellBundleActivator>("celix::Shell", manifest, resources, resourcesLen); + } + + __attribute__((destructor)) + static void cleanupShellBundle() { +#ifdef __APPLE__ + free(resources); +#endif } } diff --git a/bundles/shell/cxx_shell_tui/CMakeLists.txt b/bundles/shell/cxx_shell_tui/CMakeLists.txt index e9fa13b..d5b65f7 100644 --- a/bundles/shell/cxx_shell_tui/CMakeLists.txt +++ b/bundles/shell/cxx_shell_tui/CMakeLists.txt @@ -33,4 +33,4 @@ target_link_libraries(celix_cxx_shell_tui PUBLIC celix_framework_cxx) add_executable(shell_test src/shell_test.cc ) -target_link_libraries(shell_test PRIVATE celix_cxx_shell celix_cxx_shell_tui) \ No newline at end of file +target_link_libraries(shell_test PRIVATE celix_cxx_shell celix_cxx_shell_tui glog::glog) \ No newline at end of file diff --git a/bundles/shell/cxx_shell_tui/src/shell_test.cc b/bundles/shell/cxx_shell_tui/src/shell_test.cc index 8e92107..ab44a00 100644 --- a/bundles/shell/cxx_shell_tui/src/shell_test.cc +++ b/bundles/shell/cxx_shell_tui/src/shell_test.cc @@ -17,14 +17,13 @@ *under the License. */ -#include <iostream> - #include <glog/logging.h> #include "celix/api.h" int main(int /*argc*/, char **argv) { + //TODO move glog init to framework (a pthread_once?) google::InitGoogleLogging(argv[0]); google::LogToStderr(); diff --git a/cmake/celix_project/AddGLog.cmake b/cmake/celix_project/AddGLog.cmake index 4897f35..df0f3ab 100644 --- a/cmake/celix_project/AddGLog.cmake +++ b/cmake/celix_project/AddGLog.cmake @@ -22,14 +22,16 @@ ExternalProject_Add( GIT_REPOSITORY https://github.com/google/glog.git GIT_TAG v0.3.5 UPDATE_DISCONNECTED TRUE - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/glog - CMAKE_ARGS -DWITH_GFLAGS=OFF -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/glog -DCMAKE_CXX_FLAGS=-w + PREFIX ${CMAKE_BINARY_DIR}/glog + CMAKE_ARGS -DWITH_GFLAGS=OFF -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/glog -DCMAKE_CXX_FLAGS=-w ) +file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/glog/include/dummy.txt CONTENT "//Dummy file to ensure the include dir exists") + add_library(glog::glog IMPORTED STATIC GLOBAL) add_dependencies(glog::glog googlelog_project) set_target_properties(glog::glog PROPERTIES - IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/glog/lib/libglog.a" - INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/glog/include" + IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/glog/lib/libglog.a" + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR}/glog/include" ) diff --git a/cmake/celix_project/AddGTest.cmake b/cmake/celix_project/AddGTest.cmake index 2da1a47..1b48d8a 100644 --- a/cmake/celix_project/AddGTest.cmake +++ b/cmake/celix_project/AddGTest.cmake @@ -21,7 +21,7 @@ ExternalProject_Add( GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1 UPDATE_DISCONNECTED TRUE - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest + PREFIX ${CMAKE_BINARY_DIR}/gtest INSTALL_COMMAND "" ) diff --git a/cmake/celix_project/AddLibzip.cmake b/cmake/celix_project/AddLibzip.cmake index 7d14cb6..aec4be7 100644 --- a/cmake/celix_project/AddLibzip.cmake +++ b/cmake/celix_project/AddLibzip.cmake @@ -21,13 +21,15 @@ ExternalProject_Add( GIT_REPOSITORY https://github.com/nih-at/libzip.git GIT_TAG rel-1-5-1 UPDATE_DISCONNECTED TRUE - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libzip - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/libzip -DCMAKE_C_FLAGS=-fPIC -DBUILD_SHARED_LIBS=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_OPENSSL=OFF -Wno-dev + PREFIX ${CMAKE_BINARY_DIR}/libzip + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/libzip -DCMAKE_C_FLAGS=-fPIC -DBUILD_SHARED_LIBS=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_OPENSSL=OFF -Wno-dev ) +file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/libzip/include/dummy.txt CONTENT "//Dummy file to ensure the include dir exists") + add_library(libzip::libzip IMPORTED STATIC GLOBAL) add_dependencies(libzip::libzip libzip_project) set_target_properties(libzip::libzip PROPERTIES - IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/libzip/lib64/libzip.a" - INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/libzip/include" + IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/libzip/lib/libzip.a" + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR}/libzip/include" ) \ No newline at end of file diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 88d1928..928932a 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -21,14 +21,15 @@ add_subdirectory(utils) add_subdirectory(dfi) add_subdirectory(etcdlib) -add_subdirectory(framework) +#add_subdirectory(framework) +#C++ stuff add_subdirectory(registry) add_subdirectory(framework_cxx) #launcher -add_subdirectory(launcher) +#add_subdirectory(launcher) #add_subdirectory(event_admin)# event_admin is unstable -add_subdirectory(dependency_manager) -add_subdirectory(dependency_manager_cxx) \ No newline at end of file +#add_subdirectory(dependency_manager) +#add_subdirectory(dependency_manager_cxx) \ No newline at end of file diff --git a/libs/framework/src/bundle_archive.c b/libs/framework/src/bundle_archive.c index e2fc658..addea63 100644 --- a/libs/framework/src/bundle_archive.c +++ b/libs/framework/src/bundle_archive.c @@ -29,12 +29,15 @@ #include <stdio.h> #include <time.h> #include <sys/stat.h> +#include <sys/errno.h> #include <dirent.h> #include <unistd.h> #include "bundle_archive.h" #include "linked_list_iterator.h" +#include <string.h> + struct bundleArchive { long id; char * location; @@ -76,7 +79,7 @@ celix_status_t bundleArchive_createSystemBundleArchive(bundle_archive_pt *bundle status = linkedList_create(&archive->revisions); if (status == CELIX_SUCCESS) { archive->id = 0L; - archive->location = strdup("System Bundle"); + archive->location = strndup("System Bundle", 1024*1024); archive->archiveRoot = NULL; archive->archiveRootDir = NULL; archive->refreshCount = -1; diff --git a/libs/framework_cxx/CMakeLists.txt b/libs/framework_cxx/CMakeLists.txt index f3c116e..98c857d 100644 --- a/libs/framework_cxx/CMakeLists.txt +++ b/libs/framework_cxx/CMakeLists.txt @@ -16,6 +16,9 @@ # under the License. find_package(UUID REQUIRED) +if(NOT APPLE) + set(UUID ${UUID_LIBRARY}) +endif() #TODO rename to celix::framework add_library(celix_framework_cxx SHARED @@ -27,7 +30,7 @@ target_include_directories(celix_framework_cxx PRIVATE src) target_include_directories(celix_framework_cxx PUBLIC include) target_link_libraries(celix_framework_cxx PRIVATE glog::glog libzip::libzip) #NOTE because of libzil libbz2 and libz is also needed. maybe more to other form of resources (i.e. tar) -target_link_libraries(celix_framework_cxx PUBLIC celix::registry bz2 z ${UUID_LIBRARY}) +target_link_libraries(celix_framework_cxx PUBLIC celix::registry bz2 z ${UUID}) if (ENABLE_TESTING) add_subdirectory(gtest) diff --git a/libs/framework_cxx/gtest/CMakeLists.txt b/libs/framework_cxx/gtest/CMakeLists.txt index 23fdfb7..4e76ed2 100644 --- a/libs/framework_cxx/gtest/CMakeLists.txt +++ b/libs/framework_cxx/gtest/CMakeLists.txt @@ -20,7 +20,7 @@ set(SOURCES src/Framework_tests.cc ) add_executable(celix_framework_cxx_tests ${SOURCES}) -target_link_libraries(celix_framework_cxx_tests PRIVATE gtest celix_framework_cxx) +target_link_libraries(celix_framework_cxx_tests PRIVATE gtest celix_framework_cxx glog::glog) #NOTE last .. argument for the setup coverage is the scan dir (i.e. not gtest dir, but a dir higher) add_test(NAME celix_framework_cxx_tests COMMAND celix_framework_cxx_tests) diff --git a/libs/framework_cxx/src/Framework.cc b/libs/framework_cxx/src/Framework.cc index 0b1d856..0740e5b 100644 --- a/libs/framework_cxx/src/Framework.cc +++ b/libs/framework_cxx/src/Framework.cc @@ -31,7 +31,9 @@ #include <future> #include <algorithm> +#ifndef __APPLE__ #include <linux/limits.h> +#endif #include <glog/logging.h> #include <uuid/uuid.h> @@ -339,7 +341,7 @@ private: std::string uuidString() { char uuidStr[37]; uuid_t uuid; - uuid_generate_time_safe(uuid); + uuid_generate(uuid); uuid_unparse(uuid, uuidStr); return std::string{uuidStr}; }