| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you 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. |
| |
| ##### setup docker target |
| if (APPLE) #create filesystem script is not working on mac os, exclude target from ALL |
| add_custom_target(celix-build-docker-dirs |
| DEPENDS $<TARGET_PROPERTY:celix-build-docker-dirs,DOCKER_DEPS> |
| ) |
| else () |
| add_custom_target(celix-build-docker-dirs ALL |
| DEPENDS $<TARGET_PROPERTY:celix-build-docker-dirs,DOCKER_DEPS> |
| ) |
| endif () |
| set_target_properties(celix-build-docker-dirs PROPERTIES "DOCKER_DEPS" "") #initial empty deps list |
| |
| add_custom_target(celix-build-docker-images) |
| set(DOCKER_USE_SUDO ON CACHE BOOL "Wether the use of sudo is needed to run docker") |
| set(DOCKER_CMD "docker" CACHE STRING "Docker command to use.") |
| |
| get_directory_property(CLEANFILES ADDITIONAL_MAKE_CLEAN_FILES) |
| list(APPEND CLEANFILES "${CMAKE_BINARY_DIR}/docker") |
| set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}") |
| ##### |
| |
| function(add_celix_docker) |
| list(GET ARGN 0 DOCKER_TARGET) |
| list(REMOVE_AT ARGN 0) |
| |
| set(OPTIONS CXX) |
| set(ONE_VAL_ARGS GROUP NAME FROM BUNDLES_DIR WORKDIR IMAGE_NAME) |
| set(MULTI_VAL_ARGS BUNDLES PROPERTIES INSTRUCTIONS) |
| cmake_parse_arguments(DOCKER "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN}) |
| |
| #set defaults |
| if (NOT DOCKER_FROM) |
| set(DOCKER_FROM "scratch") |
| set(DOCKER_CREATE_FS true) |
| else() |
| set(DOCKER_CREATE_FS false) |
| endif() |
| if (NOT DOCKER_NAME) |
| set(DOCKER_NAME "${DOCKER_TARGET}") |
| endif() |
| if (NOT DOCKER_IMAGE_NAME) |
| set(DOCKER_IMAGE_NAME "${DOCKER_NAME}") |
| endif() |
| if (NOT DOCKER_WORKDIR) |
| set(DOCKER_WORKDIR "/root") |
| endif() |
| if (NOT DOCKER_GROUP) |
| set(DOCKER_LOC "${CMAKE_BINARY_DIR}/docker/${DOCKER_NAME}") |
| else() |
| set(DOCKER_LOC "${CMAKE_BINARY_DIR}/docker/${DOCKER_GROUP}/${DOCKER_NAME}") |
| endif() |
| if (NOT DOCKER_BUNDLES_DIR) |
| set(DOCKER_BUNDLES_DIR "/bundles") |
| endif() |
| |
| #ensure the docker dir will be deleted during clean |
| get_directory_property(CLEANFILES ADDITIONAL_MAKE_CLEAN_FILES) |
| list(APPEND CLEANFILES "$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>") |
| set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEANFILES}") |
| |
| if (DOCKER_LAUNCHER_SRC) |
| get_filename_component(SRC_FILENAME ${DOCKER_LAUNCHER_SRC} NAME) |
| set(LAUNCHER_SRC "${PROJECT_BINARY_DIR}/celix/gen/${DOCKER_TARGET}-${SRC_FILENAME}") |
| set(LAUNCHER_ORG "${DOCKER_LAUNCHER_SRC}") |
| elseif (DOCKER_CXX) |
| set(LAUNCHER_SRC "${PROJECT_BINARY_DIR}/celix/gen/${DOCKER_TARGET}-main.cc") |
| set(LAUNCHER_ORG "${CELIX_CMAKE_DIRECTORY}/cmake_celix/main.c.in") |
| else() |
| set(LAUNCHER_SRC "${PROJECT_BINARY_DIR}/celix/gen/${DOCKER_TARGET}-main.c") |
| set(LAUNCHER_ORG "${CELIX_CMAKE_DIRECTORY}/cmake_celix/main.c.in") |
| endif() |
| |
| if (DOCKER_LAUNCHER) |
| add_custom_target(${DOCKER_TARGET}) |
| if (IS_ABSOLUTE "${DOCKER_LAUNCHER}") |
| set(LAUNCHER "${DOCKER_LAUNCHER}") |
| get_filename_component(EXE_FILENAME ${DOCKER_LAUNCHER} NAME) |
| set(DOCKER_ENTRYPOINT "ENTRYPOINT [\"/bin/${EXE_FILENAME}\"]") |
| else() |
| #assuming target |
| set(LAUNCHER "$<TARGET_FILE:${DOCKER_LAUNCHER}>") |
| set(DOCKER_ENTRYPOINT "ENTRYPOINT [\"/bin/$<TARGET_FILE_NAME:${DOCKER_TARGET}>\"]") |
| endif() |
| else () |
| add_custom_command(OUTPUT ${LAUNCHER_SRC} |
| COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/celix/gen |
| ) |
| |
| if (DOCKER_CXX) |
| set(LAUNCHER_STAGE1 "${CMAKE_CURRENT_BINARY_DIR}/${DOCKER_TARGET}-docker-main-stage1.cc") |
| else() |
| set(LAUNCHER_STAGE1 "${CMAKE_CURRENT_BINARY_DIR}/${DOCKER_TARGET}-docker-main-stage1.c") |
| endif() |
| |
| file(GENERATE |
| OUTPUT "${LAUNCHER_STAGE1}" |
| CONTENT "#include <celix_launcher.h> |
| |
| int main(int argc, char *argv[]) { |
| const char * config = \"cosgi.auto.start.1=$<JOIN:$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_BUNDLES>, >\\n\\ |
| $<JOIN:$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_PROPERTIES>,\\n\\ |
| >\"; |
| |
| properties_pt packedConfig = properties_loadFromString(config); |
| |
| return celixLauncher_launchWithArgsAndProps(argc, argv, packedConfig); |
| } |
| " |
| ) |
| |
| file(GENERATE |
| OUTPUT "${LAUNCHER_SRC}" |
| INPUT "${LAUNCHER_STAGE1}" |
| ) |
| |
| add_executable(${DOCKER_TARGET} EXCLUDE_FROM_ALL ${LAUNCHER_SRC}) |
| # set_target_properties(${DOCKER_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${DOCKER_LOC}) |
| target_include_directories(${DOCKER_TARGET} PRIVATE ${CELIX_INCLUDE_DIRS}) |
| target_link_libraries(${DOCKER_TARGET} PRIVATE ${CELIX_FRAMEWORK_LIBRARY} ${CELIX_UTILS_LIBRARY}) |
| set(LAUNCHER "$<TARGET_FILE:${DOCKER_TARGET}>") |
| set(DOCKER_ENTRYPOINT "ENTRYPOINT [\"/bin/$<TARGET_FILE_NAME:${DOCKER_TARGET}>\"]") |
| endif () |
| |
| |
| ###### Setup docker custom target timestamp |
| add_custom_target(${DOCKER_TARGET}-deps |
| DEPENDS ${FS_TIMESTAMP_FILE} $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_DEPS> |
| ) |
| add_dependencies(${DOCKER_TARGET} ${DOCKER_TARGET}-deps) |
| |
| #setup dependencies based on timestamp |
| if (DOCKER_CREATE_FS) |
| add_custom_command(TARGET ${DOCKER_TARGET} POST_BUILD |
| COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> |
| COMMAND cd $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> && /bin/bash ${CELIX_CMAKE_DIRECTORY}/cmake_celix/create_target_filesystem.sh -e ${LAUNCHER} > /dev/null |
| WORKING_DIRECTORY "${DOCKER_LOC}" |
| COMMENT "Creating docker dir for ${DOCKER_TARGET}" VERBATIM |
| ) |
| else () |
| add_custom_command(TARGET ${DOCKER_TARGET} POST_BUILD |
| COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>/bin |
| COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LAUNCHER} $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>/bin/ |
| WORKING_DIRECTORY "${DOCKER_LOC}" |
| COMMENT "Creating docker dir for ${DOCKER_TARGET}" VERBATIM |
| ) |
| endif () |
| |
| ##### Deploy Target Properties for Dockerfile ##### |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_LOC" "${DOCKER_LOC}") |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_FROM" "${DOCKER_FROM}") #name of docker base, default celix-base |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_IMAGE_NAME" "${DOCKER_IMAGE_NAME}") #name of docker images, default deploy target name |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_BUNDLES_DIR" "${DOCKER_BUNDLES_DIR}") #bundles directory in docker image |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_BUNDLES" "") #bundles |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_WORKDIR" "${DOCKER_WORKDIR}") #workdir in docker image, should also contain the config.properties |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_ENTRYPOINT" "${DOCKER_ENTRYPOINT}") |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_CREATE_FS" "${DOCKER_CREATE_FS}") #wether to create a fs with the minimal needed libraries / etc files |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_INSTRUCTIONS" "") #list of additional instructions |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_PROPERTIES" "") |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_DEPS" "") |
| |
| set(DOCKERFILE_STAGE1 ${CMAKE_BINARY_DIR}/celix/gen/${DOCKER_TARGET}-Dockerfile.in) |
| set(DOCKERFILE "$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC>/Dockerfile") |
| |
| file(GENERATE |
| OUTPUT "${DOCKERFILE_STAGE1}" |
| CONTENT "# Dockerfile for celix based image |
| FROM $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_FROM> |
| ENV IMAGE_NAME $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_IMAGE_NAME> |
| COPY . / |
| WORKDIR $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_WORKDIR> |
| $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_ENTRYPOINT> |
| $<JOIN:$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_INSTRUCTIONS>, |
| > |
| ") |
| file(GENERATE |
| OUTPUT ${DOCKERFILE} |
| INPUT ${DOCKERFILE_STAGE1} |
| ) |
| |
| #generate config.properties |
| set(DOCKER_PROPERTIES_FILE "${DOCKER_LOC}/${DOCKER_WORKDIR}/config.properties") |
| set(STAGE1_PROPERTIES_FILE "${CMAKE_BINARY_DIR}/celix/gen/${DOCKER_TARGET}-docker-config-stage1.properties") |
| file(GENERATE |
| OUTPUT "${STAGE1_PROPERTIES_FILE}" |
| CONTENT "cosgi.auto.start.1=$<JOIN:$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_BUNDLES>, > |
| $<JOIN:$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_PROPERTIES>, |
| > |
| " |
| ) |
| file(GENERATE |
| OUTPUT "${DOCKER_PROPERTIES_FILE}" |
| INPUT "${STAGE1_PROPERTIES_FILE}" |
| ) |
| |
| if (DOCKER_BUNDLES) |
| celix_docker_bundles(${DOCKER_TARGET} ${DOCKER_BUNDLES}) |
| endif() |
| if (DOCKER_PROPERTIES) |
| celix_docker_properties(${DOCKER_TARGET} ${DOCKER_PROPERTIES}) |
| endif () |
| if (DOCKER_INSTRUCTIONS) |
| celix_docker_instructions(${DOCKER_TARGET} ${DOCKER_INSTRUCTIONS}) |
| endif () |
| |
| get_target_property(DEPS celix-build-docker-dirs "DOCKER_DEPS") |
| list(APPEND DEPS ${DOCKER_TARGET}) |
| set_target_properties(celix-build-docker-dirs PROPERTIES "DOCKER_DEPS" "${DEPS}") |
| |
| add_custom_target(celix-build-${DOCKER_TARGET}-docker-image |
| COMMAND cd $<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_LOC> && ${DOCKER_CMD} build -t "$<TARGET_PROPERTY:${DOCKER_TARGET},DOCKER_IMAGE_NAME>" . |
| DEPENDS ${DOCKERFILE} ${DOCKER_TARGET} |
| COMMENT "Creating docker image for target '${DOCKER_TARGET}'" VERBATIM |
| ) |
| add_dependencies(celix-build-docker-images celix-build-${DOCKER_TARGET}-docker-image) |
| |
| endfunction() |
| |
| function(celix_docker_bundles) |
| #0 is docker TARGET |
| #1..n is bundles |
| list(GET ARGN 0 DOCKER_TARGET) |
| list(REMOVE_AT ARGN 0) |
| |
| get_target_property(BUNDLES ${DOCKER_TARGET} "DOCKER_BUNDLES") |
| get_target_property(BUNDLES_DIR ${DOCKER_TARGET} "DOCKER_BUNDLES_DIR") |
| get_target_property(LOC ${DOCKER_TARGET} "DOCKER_LOC") |
| get_target_property(DEPS ${DOCKER_TARGET} "DOCKER_DEPS") |
| |
| foreach(BUNDLE IN ITEMS ${ARGN}) |
| if(IS_ABSOLUTE ${BUNDLE} AND EXISTS ${BUNDLE}) |
| get_filename_component(BUNDLE_FILENAME ${BUNDLE} NAME) |
| list(APPEND BUNDLES "${BUNDLES_DIR}/${BUNDLE_FILENAME}") |
| set(OUT "${LOC}/${BUNDLES_DIR}/${BUNDLE_FILENAME}") |
| add_custom_command(OUTPUT ${OUT} |
| COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BUNDLE} ${OUT} |
| COMMENT "Copying bundle '${BUNDLE}' to '${OUT}'" |
| DEPENDS ${BUNDLE} |
| ) |
| else() #assuming target |
| get_target_property(BFN ${BUNDLE} BUNDLE_FILE_NAME) |
| list(APPEND BUNDLES "${BUNDLES_DIR}/${BFN}") |
| set(OUT ${LOC}/${BUNDLES_DIR}/${BFN}) |
| add_custom_command(OUTPUT ${OUT} |
| COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILE>" "${OUT}" |
| COMMENT "Copying bundle '${BUNDLE}' to '${OUT}'" |
| DEPENDS ${BUNDLE} ${BUNDLE}_bundle |
| ) |
| endif() |
| list(APPEND DEPS "${OUT}") |
| endforeach() |
| |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_BUNDLES" "${BUNDLES}") |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_DEPS" "${DEPS}") |
| endfunction() |
| |
| function(celix_docker_properties) |
| #0 is docker TARGET |
| #1..n is properties |
| list(GET ARGN 0 DOCKER_TARGET) |
| list(REMOVE_AT ARGN 0) |
| |
| get_target_property(PROPS ${DOCKER_TARGET} "DOCKER_PROPERTIES") |
| |
| foreach(PROP IN ITEMS ${ARGN}) |
| list(APPEND PROPS ${PROP}) |
| endforeach() |
| |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_PROPERTIES" "${PROPS}") |
| endfunction() |
| |
| function(celix_docker_instructions) |
| #0 is docker TARGET |
| #1..n is instructions |
| list(GET ARGN 0 DOCKER_TARGET) |
| list(REMOVE_AT ARGN 0) |
| |
| get_target_property(INSTRUCTIONS ${DOCKER_TARGET} "DOCKER_INSTRUCTIONS") |
| |
| foreach(INSTR IN ITEMS ${ARGN}) |
| list(APPEND INSTRUCTIONS ${INSTR}) |
| endforeach() |
| |
| set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_INSTRUCTIONS" "${INSTRUCTIONS}") |
| endfunction() |