diff --git a/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets b/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets index 2454f2555..810c31260 100644 --- a/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets +++ b/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets @@ -7,4 +7,116 @@ + + + + + + + + $(OutDir) + $(ProgramW6432)\WSL\wslc.exe + wslc + + + + + + latest + $(WslcImageOutputDir) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_WslcSourceDirs Include="$(_WslcSourceDir.Split(';'))" /> + <_WslcSourceFiles Include="$(_WslcDockerfile)" /> + <_WslcSourceFiles Include="%(_WslcSourceDirs.Identity)\**\*" Condition="'%(_WslcSourceDirs.Identity)' != ''" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets b/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets index 09823c7b0..a9cf3c22e 100644 --- a/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets +++ b/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets @@ -23,4 +23,52 @@ + + + + + + + + + + + + + <_WslcTlogSourceDirs Include="$(_WslcSourceDir.Split(';'))" /> + <_WslcTlogInputs Include="$(_WslcDockerfile)" /> + <_WslcTlogInputs Condition="'%(_WslcTlogSourceDirs.Identity)' != ''" Include="%(_WslcTlogSourceDirs.Identity)\**\*" /> + + + + <_WslcDockerfileFullPath>$([System.IO.Path]::GetFullPath('$(_WslcDockerfile)')) + <_WslcMarkerFullPath>$([System.IO.Path]::GetFullPath('$(IntDir)wslc_$(_WslcName).marker')) + <_WslcTarFullPath>$([System.IO.Path]::GetFullPath('$(WslcImageOutputDir)$(_WslcName).tar')) + + + + + + + + + + + + + \ No newline at end of file diff --git a/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets b/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets index 245e57a2c..cb1500527 100644 --- a/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets +++ b/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets @@ -11,4 +11,23 @@ + + + + + + + + + + + + + <_WslcUpToDateDirs Include="%(WslcImage.Sources)" Separator=";" /> + + + + \ No newline at end of file diff --git a/nuget/Microsoft.WSL.Containers/buildTransitive/Microsoft.WSL.Containers.targets b/nuget/Microsoft.WSL.Containers/buildTransitive/Microsoft.WSL.Containers.targets new file mode 100644 index 000000000..b5ada5ff6 --- /dev/null +++ b/nuget/Microsoft.WSL.Containers/buildTransitive/Microsoft.WSL.Containers.targets @@ -0,0 +1,4 @@ + + + + diff --git a/nuget/Microsoft.WSL.Containers/buildTransitive/native/Microsoft.WSL.Containers.targets b/nuget/Microsoft.WSL.Containers/buildTransitive/native/Microsoft.WSL.Containers.targets new file mode 100644 index 000000000..0f50deabc --- /dev/null +++ b/nuget/Microsoft.WSL.Containers/buildTransitive/native/Microsoft.WSL.Containers.targets @@ -0,0 +1,4 @@ + + + + diff --git a/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake b/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake index 0ea5f0642..07a38e4ae 100644 --- a/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake +++ b/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake @@ -55,3 +55,92 @@ unset(_wslcsdk_arch) unset(_wslcsdk_root) unset(_wslcsdk_include_dir) unset(_wslcsdk_lib_dir) + +# ============================================================================ +# Container Image Build Targets +# ============================================================================ +# +# Provides the wslc_add_image() function for declaring container image +# build targets with incremental rebuild support. +# +# Usage: +# find_package(Microsoft.WSL.Containers REQUIRED) +# +# wslc_add_image( +# NAME my-server +# DOCKERFILE container/Dockerfile +# CONTEXT container/ +# SOURCES container/src/*.cpp container/src/*.h +# TAG latest +# OUTPUT ${CMAKE_BINARY_DIR}/images +# ) +# +# # With explicit image registry/name (IMAGE defaults to NAME if omitted): +# wslc_add_image( +# NAME my-server +# IMAGE ghcr.io/myorg/my-server +# TAG v1.2.3 +# DOCKERFILE container/Dockerfile +# CONTEXT container/ +# ) + +function(wslc_add_image) + cmake_parse_arguments( + PARSE_ARGV 0 ARG + "" # options (none) + "NAME;IMAGE;TAG;DOCKERFILE;CONTEXT;OUTPUT" # one-value keywords + "SOURCES" # multi-value keywords + ) + + # Validate required arguments + if(NOT ARG_NAME) + message(FATAL_ERROR "wslc_add_image: NAME is required") + endif() + if(NOT ARG_DOCKERFILE) + message(FATAL_ERROR "wslc_add_image: DOCKERFILE is required") + endif() + if(NOT ARG_CONTEXT) + message(FATAL_ERROR "wslc_add_image: CONTEXT is required") + endif() + + # Defaults + if(NOT ARG_IMAGE) + set(ARG_IMAGE "${ARG_NAME}") + endif() + if(NOT ARG_TAG) + set(ARG_TAG "latest") + endif() + if(NOT ARG_OUTPUT) + set(ARG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + # Find wslc CLI + if(NOT WSLC_CLI_PATH) + find_program(WSLC_CLI_PATH wslc PATHS "$ENV{ProgramW6432}/WSL" "$ENV{ProgramFiles}/WSL") + if(NOT WSLC_CLI_PATH) + message(FATAL_ERROR "wslc CLI not found. Install WSL by running: wsl --install --no-distribution") + endif() + endif() + + set(_image_ref "${ARG_IMAGE}:${ARG_TAG}") + set(_marker "${CMAKE_CURRENT_BINARY_DIR}/wslc_${ARG_NAME}.marker") + set(_tar_output "${ARG_OUTPUT}/${ARG_NAME}.tar") + + # Resolve source globs to file lists + file(GLOB_RECURSE _resolved_sources CONFIGURE_DEPENDS ${ARG_SOURCES}) + + add_custom_command( + OUTPUT "${_marker}" + COMMAND "${WSLC_CLI_PATH}" image build -t "${_image_ref}" -f "${ARG_DOCKERFILE}" "${ARG_CONTEXT}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${ARG_OUTPUT}" + COMMAND "${WSLC_CLI_PATH}" image save -o "${_tar_output}" "${_image_ref}" + COMMAND ${CMAKE_COMMAND} -E touch "${_marker}" + DEPENDS ${_resolved_sources} "${ARG_DOCKERFILE}" + COMMENT "WSLC: Building and saving image '${_image_ref}' to '${_tar_output}'..." + VERBATIM + ) + + add_custom_target(wslc_image_${ARG_NAME} ALL + DEPENDS "${_marker}" + ) +endfunction()