You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2019/01/07 20:11:56 UTC

[celix] 08/22: CELIX-438: Adds bundle register for __APPLE__

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 <pe...@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*>(&registerShellBundle);
+        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};
     }