Skip to content

Commit

Permalink
Remove support for embedded bundles
Browse files Browse the repository at this point in the history
  • Loading branch information
pnoltes committed Dec 30, 2023
1 parent 9ea03bc commit acedb91
Show file tree
Hide file tree
Showing 21 changed files with 48 additions and 922 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ limitations under the License.
- C Properties are no longer a direct typedef of `hashmap`.
- celix_string/long_hashmap put functions now return a celix_status_t instead of bool (value replaced).
THe celix_status_t is used to indicate an ENOMEM error.
- Embedded bundles are no longer supported.

## New Features

Expand Down
129 changes: 2 additions & 127 deletions cmake/cmake_celix/ContainerPackaging.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ Optional Arguments:
- C: With this option the generated Celix launcher (if used) will be a C source. Only one of the C or CXX options can
be provided.
Default is CXX
- FAT: With this option only embedded bundles are allowed to be added to the container. Ensuring a container executable
this is not dependent on external bundle zip files.
Note that this option does not change anything to the container, it just ensure that all added bundles are embedded
bundles.
- USE_CONFIG: With this option the config properties are generated in a 'config.properties' instead of embedded in
the Celix launcher.
- GROUP: If configured the build location will be prefixed the GROUP. Default is empty.
Expand All @@ -79,14 +75,8 @@ Optional Arguments:
- BUNDLES: A list of bundles for the Celix container to install and start.
These bundle will be configured for run level 3. See 'celix_container_bundles' for more info.
- INSTALL_BUNDLES: A list of bundles for the Celix container to install (but not start).
- EMBEDDED_BUNDLES: A list of bundles to embed in the Celix container (inject as binary in the executable) and
to install and start for the Celix container.
See `celix_target_embedded_bundle` for more info about embedded bundles.
- INSTALL_EMBEDDED_BUNDLES: A list of bundles to embed in the Celix container (inject as binary in the executable) and
to install (but not start) for the Celix container.
See `celix_target_embedded_bundle` for more info about embedded bundles.
- PROPERTIES: A list of configuration properties, these can be used to configure the Celix framework and/or bundles.
Normally this will be EMBEDED_PROPERTIES, but if the USE_CONFIG option is used this will be RUNTIME_PROPERTIES.
Normally this will be EMBEDDED_PROPERTIES, but if the USE_CONFIG option is used this will be RUNTIME_PROPERTIES.
See the framework library or bundles documentation about the available configuration options.
- EMBEDDED_PROPERTIES: A list of configuration properties which will be used in the generated Celix launcher.
- RUNTIME_PROPERTIES: A list of configuration properties which will be used in the generated config.properties file.
Expand All @@ -97,15 +87,12 @@ add_celix_container(<celix_container_name>
[NO_COPY]
[CXX]
[C]
[FAT]
[USE_CONFIG]
[GROUP group_name]
[NAME celix_container_name]
[DIR dir]
[BUNDLES <bundle1> <bundle2> ...]
[INSTALL_BUNDLES <bundle1> <bundle2> ...]
[EMBEDDED_BUNDLES <bundle1> <bundle2> ...]
[INSTALL_EMBEDDED_BUNDLES <bundle1> <bundle2> ...]
[PROPERTIES "prop1=val1" "prop2=val2" ...]
[EMBEDDED_PROPERTIES "prop1=val1" "prop2=val2" ...]
[RUNTIME_PROPERTIES "prop1=val1" "prop2=val2" ...]
Expand All @@ -119,15 +106,12 @@ add_celix_container(<celix_container_name>
[NO_COPY]
[CXX]
[C]
[FAT]
[USE_CONFIG]
[GROUP group_name]
[NAME celix_container_name]
[DIR dir]
[BUNDLES <bundle1> <bundle2> ...]
[INSTALL_BUNDLES <bundle1> <bundle2> ...]
[EMBEDDED_BUNDLES <bundle1> <bundle2> ...]
[INSTALL_EMBEDDED_BUNDLES <bundle1> <bundle2> ...]
[PROPERTIES "prop1=val1" "prop2=val2" ...]
[EMBEDDED_PROPERTIES "prop1=val1" "prop2=val2" ...]
[RUNTIME_PROPERTIES "prop1=val1" "prop2=val2" ...]
Expand All @@ -141,15 +125,12 @@ add_celix_container(<celix_container_name>
[NO_COPY]
[CXX]
[C]
[FAT]
[USE_CONFIG]
[GROUP group_name]
[NAME celix_container_name]
[DIR dir]
[BUNDLES <bundle1> <bundle2> ...]
[INSTALL_BUNDLES <bundle1> <bundle2> ...]
[EMBEDDED_BUNDLES <bundle1> <bundle2> ...]
[INSTALL_EMBEDDED_BUNDLES <bundle1> <bundle2> ...]
[PROPERTIES "prop1=val1" "prop2=val2" ...]
[EMBEDDED_PROPERTIES "prop1=val1" "prop2=val2" ...]
[RUNTIME_PROPERTIES "prop1=val1" "prop2=val2" ...]
Expand All @@ -169,28 +150,14 @@ add_celix_container(simple_container
CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug
)
```
```CMake
#Creates a "fat" Celix container in ${CMAKE_BINARY_DIR}/deploy/simple_fat_container which starts 3 bundles embedded
#in the container executable.
add_celix_container(simple_fat_container
FAT
EMBEDDED_BUNDLES
Celix::shell
Celix::shell_tui
Celix::log_admin
PROPERTIES
CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug
)
```
]]
function(add_celix_container)
list(GET ARGN 0 CONTAINER_TARGET)
list(REMOVE_AT ARGN 0)

set(OPTIONS COPY NO_COPY C CXX FAT USE_CONFIG)
set(ONE_VAL_ARGS GROUP NAME LAUNCHER LAUNCHER_SRC DIR)
set(MULTI_VAL_ARGS BUNDLES INSTALL_BUNDLES EMBEDDED_BUNDLES INSTALL_EMBEDDED_BUNDLES PROPERTIES EMBEDDED_PROPERTIES RUNTIME_PROPERTIES)
set(MULTI_VAL_ARGS BUNDLES INSTALL_BUNDLES PROPERTIES EMBEDDED_PROPERTIES RUNTIME_PROPERTIES)
cmake_parse_arguments(CONTAINER "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})

##### Check arguments #####
Expand Down Expand Up @@ -370,7 +337,6 @@ $<JOIN:$<TARGET_PROPERTY:${CONTAINER_TARGET},CONTAINER_RUNTIME_PROPERTIES>,
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_6" "") #bundles to deploy for the container for startup level 6
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_INSTALL" "") #bundles to install for the container
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_COPY_BUNDLES" ${CONTAINER_COPY}) #copy bundles in bundle dir or link using abs paths. NOTE this cannot be changed after a add_deploy command
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_IS_FAT" ${CONTAINER_FAT}) #Whether this is a fat container, so a container with only embedded bundles.

#deploy specific
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_NAME" "${CONTAINER_NAME}")
Expand All @@ -382,9 +348,7 @@ $<JOIN:$<TARGET_PROPERTY:${CONTAINER_TARGET},CONTAINER_RUNTIME_PROPERTIES>,
#####

celix_container_bundles(${CONTAINER_TARGET} LEVEL 3 ${CONTAINER_BUNDLES})
celix_container_embedded_bundles(${CONTAINER_TARGET} LEVEL 3 ${CONTAINER_EMBEDDED_BUNDLES})
celix_container_bundles(${CONTAINER_TARGET} INSTALL ${CONTAINER_INSTALL_BUNDLES})
celix_container_embedded_bundles(${CONTAINER_TARGET} INSTALL ${CONTAINER_INSTALL_EMBEDDED_BUNDLES})
if (CONTAINER_USE_CONFIG)
celix_container_runtime_properties(${CONTAINER_TARGET} ${CONTAINER_PROPERTIES})
else ()
Expand Down Expand Up @@ -560,7 +524,6 @@ function(celix_container_bundles)
get_target_property(BUNDLES ${CONTAINER_TARGET} "CONTAINER_BUNDLES_LEVEL_${BUNDLES_LEVEL}")
endif ()
get_target_property(COPY ${CONTAINER_TARGET} "CONTAINER_COPY_BUNDLES")
get_target_property(IS_FAT ${CONTAINER_TARGET} "CONTAINER_IS_FAT")

if (BUNDLES_COPY)
set(COPY TRUE)
Expand All @@ -569,10 +532,6 @@ function(celix_container_bundles)
endif ()

foreach(BUNDLE IN ITEMS ${BUNDLES_LIST})
if (IS_FAT)
message(FATAL_ERROR "Cannot add bundle ${BUNDLE} to Celix container ${CONTAINER_TARGET}. ${CONTAINER_TARGET} is configured as a fat container, so only embedded bundles are allowed. Use EMBEDDED_BUNDLES instead of BUNDLES in the add_celix_container CMake command.")
endif ()

if (TARGET ${BUNDLE})
get_target_property(TARGET_TYPE ${BUNDLE} TYPE)
if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
Expand Down Expand Up @@ -643,90 +602,6 @@ function(_celix_container_check_duplicate_bundles)
endforeach()
endfunction()

#[[
Embed a selection of bundles to the Celix container.
```CMake
celix_container_embedded_bundles(<celix_container_target_name>
[LEVEL (0..6)]
[INSTALL]
bundle1
bundle2
...
)
```
Example:
```CMake
celix_container_embedded_bundles(my_container Celix::shell Celix::shell_tui)
```
The selection of bundles are embedded in the container executable using the
`celix_target_embedded_bundle` Celix CMake command and are added to the configuration properties so that they are
installed and started when the Celix container is executed.
See `celix_target_embedded_bundle` for how bundle is embedded in a executable.
The Celix framework supports 7 (0 - 6) run levels. Run levels can be used to control the start and stop order of bundles.
Bundles in run level 0 are started first and bundles in run level 6 are started last.
When stopping bundles in run level 6 are stopped first and bundles in run level 0 are stopped last.
Within a run level the order of configured decides the start order; bundles added earlier are started first.
Optional Arguments:
- LEVEL: The run level for the added bundles. Default is 3.
- INSTALL: If this option is present, the bundles will only be installed instead of the default install and start.
The bundles will be installed after all bundle in LEVEL 0..6 are installed and started.
]]
function(celix_container_embedded_bundles)
#0 is container TARGET
list(GET ARGN 0 CONTAINER_TARGET)
list(REMOVE_AT ARGN 0)

set(OPTIONS INSTALL)
set(ONE_VAL_ARGS LEVEL)
set(MULTI_VAL_ARGS )
cmake_parse_arguments(BUNDLES "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})
set(BUNDLES_LIST ${BUNDLES_UNPARSED_ARGUMENTS})

if (NOT DEFINED BUNDLES_LEVEL)
set(BUNDLES_LEVEL 3)
endif ()

if (BUNDLES_INSTALL)
get_target_property(BUNDLES ${CONTAINER_TARGET} "CONTAINER_BUNDLES_INSTALL")
else () #bundle level 0,1,2,3,4,5 or 6
get_target_property(BUNDLES ${CONTAINER_TARGET} "CONTAINER_BUNDLES_LEVEL_${BUNDLES_LEVEL}")
endif ()

foreach(BUNDLE IN ITEMS ${BUNDLES_LIST})
if (TARGET ${BUNDLE})
celix_get_bundle_symbolic_name(${BUNDLE} NAME)
add_celix_bundle_dependencies(${CONTAINER_TARGET} ${BUNDLE})
elseif (IS_ABSOLUTE ${BUNDLE} AND EXISTS ${BUNDLE})
get_filename_component(RAW_NAME ${BUNDLE} NAME_WE)
string(MAKE_C_IDENTIFIER ${RAW_NAME} NAME)
else()
message(FATAL_ERROR "Cannot add bundle `${BUNDLE}` to container target ${CONTAINER_TARGET}. Argument is not a path or cmake target")
endif ()
celix_target_embedded_bundle(${CONTAINER_TARGET} BUNDLE ${BUNDLE} NAME ${NAME})
set(BUNDLE_TO_ADD "embedded://${NAME}")

list(FIND BUNDLES ${BUNDLE_TO_ADD} INDEX)
if (INDEX EQUAL -1) #Note this ignores the same bundle for the same level
_celix_container_check_duplicate_bundles(${CONTAINER_TARGET} ${BUNDLE_TO_ADD} ${BUNDLES_LEVEL})
list(APPEND BUNDLES ${BUNDLE_TO_ADD})
endif ()
endforeach()



if (BUNDLES_INSTALL)
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_INSTALL" "${BUNDLES}")
else () #bundle level 0,1,2,3,4,5 or 6
set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_${BUNDLES_LEVEL}" "${BUNDLES}")
endif ()
endfunction()

function(deploy_properties)
celix_container_runtime_properties(${ARGN})
endfunction()
Expand Down
143 changes: 0 additions & 143 deletions cmake/cmake_celix/Generic.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -48,149 +48,6 @@ function(install_celix_targets)
install_celix_bundle_targets(${ARGN})
endfunction ()

#[[
Embeds a Celix bundle into a CMake target.
```CMake
celix_target_embedded_bundle(<cmake_target>
BUNDLE <bundle>
[NAME <name>]
)
```
Example:
```CMake
celix_target_embedded_bundle(my_executable
BUNDLE Celix::shell
NAME celix_shell
)
# result in the symbols:
# - celix_embedded_bundle_celix_shell_start
# - celix_embedded_bundle_celix_shell_end
# - celix_embedded_bundles = "embedded://celix_shell"
# to be added to `my_executable`
```
The Celix bundle will be embedded into the CMake target between the symbols: `celix_embedded_bundle_${NAME}_start` and
`celix_embedded_bundle_${NAME}_end`.
Also a `const char * const` symbol with the name `celix_embedded_bundles` will be added or updated containing a `,`
seperated list of embedded Celix bundle urls. The url will be: `embedded://${NAME}`.
For Linux the linking flag `--export-dynamic` is added to ensure that the previous mentioned symbols can be retrieved
using `dlsym`.
Mandatory Arguments:
- BUNDLE: The bundle target or bundle file (absolute path) to embed in the CMake target.
Optional Arguments:
- NAME: The name to use when embedding the Celix bundle. This name is used in the _start and _end symbol, but also
for the embedded bundle url.
For a bundle CMake target the default is the bundle symbolic name and for a bundle file the default is the
bundle filename without extension. The NAME must be a valid C identifier.
Bundles embedded in an executable can be installed/started using the bundle url: "embedded://${NAME}" in
combination with `celix_bundleContext_installBundle` (C) or `celix::BundleContext::installBundle` (C++).
All embedded bundle can be installed using the framework utils function
`celix_framework_utils_installEmbeddedBundles` (C) or `celix::installEmbeddedBundles` (C++).
]]
function(celix_target_embedded_bundle)
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
if (NOT "ASM" IN_LIST LANGUAGES)
message(FATAL_ERROR "celix_target_embedded_bundle is only supported it the language ASM is enabled."
" Please add ASM as cmake project language.")
endif ()

list(GET ARGN 0 TARGET_NAME)
list(REMOVE_AT ARGN 0)

set(OPTIONS)
set(ONE_VAL_ARGS BUNDLE NAME)
set(MULTI_VAL_ARGS)
cmake_parse_arguments(EMBED_BUNDLE "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})

if (NOT EMBED_BUNDLE_BUNDLE)
message(FATAL_ERROR "Missing required BUNDLE argument")
endif ()

if (TARGET ${EMBED_BUNDLE_BUNDLE})
celix_get_bundle_symbolic_name(${EMBED_BUNDLE_BUNDLE} DEFAULT_NAME)
celix_get_bundle_file(${EMBED_BUNDLE_BUNDLE} EMBED_BUNDLE_FILE)
add_celix_bundle_dependencies(${TARGET_NAME} ${EMBED_BUNDLE_BUNDLE})
elseif (IS_ABSOLUTE ${EMBED_BUNDLE_BUNDLE} AND EXISTS ${EMBED_BUNDLE_BUNDLE})
get_filename_component(RAW_NAME ${EMBED_BUNDLE_BUNDLE} NAME_WE)
string(MAKE_C_IDENTIFIER ${RAW_NAME} DEFAULT_NAME)
set(EMBED_BUNDLE_FILE ${EMBED_BUNDLE_BUNDLE})
else ()
message(FATAL_ERROR "Cannot embed bundle `${EMBED_BUNDLE_BUNDLE}` to target ${TARGET_NAME}. Argument is not a path or cmake target")
endif ()

if (NOT EMBED_BUNDLE_NAME)
set(EMBED_BUNDLE_NAME ${DEFAULT_NAME})
endif()

string(MAKE_C_IDENTIFIER ${EMBED_BUNDLE_NAME} EMBED_BUNDLE_NAME_CHECK)
if (NOT EMBED_BUNDLE_NAME STREQUAL EMBED_BUNDLE_NAME_CHECK)
message(FATAL_ERROR "Cannot embed bundle ${EMBED_BUNDLE_BUNDLE}, because the bundle symbolic name (${EMBED_BUNDLE_NAME}) is not a valid c identifier. Please specify an valid c identifier as embedded bundle name instead.")
endif ()

if (APPLE)
set(ASSEMBLY_FILE_IN ${CELIX_CMAKE_DIRECTORY}/templates/embed_bundle_apple.s)
else ()
set(ASSEMBLY_FILE_IN ${CELIX_CMAKE_DIRECTORY}/templates/embed_bundle_linux.s)
endif ()
set(ASSEMBLY_FILE "${CMAKE_BINARY_DIR}/celix/gen/target/${TARGET_NAME}/embed_bundle_${EMBED_BUNDLE_NAME}.s")
configure_file(${ASSEMBLY_FILE_IN} ${ASSEMBLY_FILE} @ONLY)
target_sources(${TARGET_NAME} PRIVATE ${ASSEMBLY_FILE})

get_target_property(CELIX_EMBEDDED_BUNDLES ${TARGET_NAME} "CELIX_EMBEDDED_BUNDLES")
if (NOT CELIX_EMBEDDED_BUNDLES)
set(CELIX_EMBEDDED_BUNDLES "embedded://${EMBED_BUNDLE_NAME}")

#If executable also add symbol with a ; seperated list of embedded bundles urls
get_target_property(TYPE ${TARGET_NAME} TYPE)
if (TYPE STREQUAL "EXECUTABLE")
set(C_FILE "${CMAKE_BINARY_DIR}/celix/gen/target/${TARGET_NAME}/celix_embedded_bundles.c")
file(GENERATE OUTPUT ${C_FILE}.stage1 CONTENT "const char * const celix_embedded_bundles = \"$<JOIN:$<TARGET_PROPERTY:${TARGET_NAME},CELIX_EMBEDDED_BUNDLES>,$<COMMA>>\";")
file(GENERATE OUTPUT ${C_FILE} INPUT ${C_FILE}.stage1)
target_sources(${TARGET_NAME} PRIVATE ${C_FILE})
endif ()

if (NOT APPLE)
#For linux ensure the --export-dynamic linking flag is added to that symbols in the main program can be found with dlsym.
target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--export-dynamic)
endif ()
else()
list(APPEND CELIX_EMBEDDED_BUNDLES "embedded://${EMBED_BUNDLE_NAME}")
endif()
list(REMOVE_DUPLICATES CELIX_EMBEDDED_BUNDLES)
set_target_properties(${TARGET_NAME} PROPERTIES "CELIX_EMBEDDED_BUNDLES" "${CELIX_EMBEDDED_BUNDLES}")
endfunction()

#[[
Embed multiple Celix bundles into a CMake target.
```CMake
celix_target_embedded_bundles(<cmake_target> [<bundle1> <bundle2> ...])
```
Example:
```CMake
celix_target_embedded_bundles(my_executable Celix::shell Celix::shell_tui)
```
The bundles will be embedded using their symbolic name if the bundle is a CMake target or their filename (without
extension) if the bundle is a file (absolute path).
]]
function(celix_target_embedded_bundles)
list(GET ARGN 0 TARGET_NAME)
list(REMOVE_AT ARGN 0)

foreach (BUNDLE IN LISTS ARGN)
celix_target_embedded_bundle(${TARGET_NAME} BUNDLE ${BUNDLE})
endforeach ()
endfunction()

#[[
Add a compile-definition with a set of comma seperated bundles paths to a target and also adds the bundles as
dependency to the target.
Expand Down
Loading

0 comments on commit acedb91

Please sign in to comment.