Skip to content

Commit

Permalink
Merge pull request #76 from Flow-IPC/polish
Browse files Browse the repository at this point in the history
Polish:  Protocol_version + Native_socket_stream::release() improvement; link_test + CI/CD artifact improvement; VERSION file support in CMake/Conan+CI/CD pipeline; misc formatting.
  • Loading branch information
ygoldfeld authored Feb 26, 2024
2 parents 4dd1e9f + 7167de9 commit ff937af
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 59 deletions.
92 changes: 78 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ name: Flow-IPC pipeline

on:
# Want to merge to development tip? Should probably pass these builds/tests and doc generation first (the latter
# in case the source change adds a Doxygen error or bad-looking docs). Note this rans on PR creation *and* update.
# in case the source change adds a Doxygen error or bad-looking docs). Note this runs on PR creation *and* update.
pull_request:
branches:
- main
Expand Down Expand Up @@ -104,6 +104,65 @@ jobs:
needs: set-vars
runs-on: ubuntu-latest
steps:
- name: Checkout VERSION file and tag history
uses: actions/checkout@v4
with:
sparse-checkout: VERSION
fetch-depth: 0 # Get all history regarding tags. We'll need that for VERSION checking below.
- name: Grab repository version from `VERSION` file
id: repo_version
run: |
# Grab repository version from `VERSION` file.
if [ ! -e VERSION ]; then
echo '::error ::No VERSION file in repository root. One must exist.'
exit 1
fi
VERSION=`cat VERSION`
echo "Determined version: [$VERSION]."
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: (On release creation only) Check repository version against release tag name
if: success() && (!cancelled()) && startsWith(github.ref, 'refs/tags/v')
run: |
# Check repository version against release tag name.
VERSION=${{ steps.repo_version.outputs.version }}
TAG_VERSION=${GITHUB_REF#refs/tags/v}
if [ "$VERSION" = "$TAG_VERSION" ]; then
echo ":notice ::Tag name and repo version are an exact match. Looks good."
elif [[ "$TAG_VERSION" == "$VERSION-"* ]]; then
echo "::notice ::Tag name [v$TAG_VERSION] starts with repo version (pre-release). Allowed."
else
echo "::error ::VERSION file version v[$VERSION] must = release tag name [v$TAG_VERSION]."
echo "::error ::Suggest deleting release and tag, fixing VERSION if needed, and re-creating release/tag."
exit 1
fi
# TODO: Would be nice to also grab release name and ensure it equals tag name v<...>.
# Could be a separate step or just execute here if the above succeeded so far. Requires API fetch, so it's
# a few lines.
- name: (Except on release creation) Check repository version against already-existing release tag names
if: success() && (!cancelled()) && (!startsWith(github.ref, 'refs/tags/v'))
run: |
# Check repo version against release tag name.
# Do not fail on account of VERSION in this path however... just warn or gently inform.
VERSION=${{ steps.repo_version.outputs.version }}
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "::warning ::Tag [v$VERSION] already exists. The repo/VERSION file will require "\
"a bump, before the next release. However this should be done *just* ahead of release creation and must "\
"follow semantic versioning conventions, especially regarding when to bump major/minor/patch components. "\
"When ready to do this consult [https://semver.org/] as needed."
elif git tag | grep -q "^v$VERSION-"; then
echo "::notice ::Since pre-release tag(s) [v$VERSION-*] already exist(s), but no tag "\
"[v$VERSION] exists, this repo state is likely intended for a later pre-release or official release. "\
"Cool! However, reminder: "\
"The repo/VERSION version should be decided/finalized *just* ahead of release creation and must "\
"follow semantic versioning conventions, especially regarding when to bump major/minor/patch components. "\
"When ready to do this consult [https://semver.org/] as needed."
else
echo "::notice ::Since no tag [v$VERSION] or [v$VERSION-*] exists, this repo state "\
"is likely intended for a future release. Cool! However, reminder: "\
"The repo/VERSION version should be decided/finalized *just* ahead of release creation and must "\
"follow semantic versioning conventions, especially regarding when to bump major/minor/patch components. "\
"When ready to do this consult [https://semver.org/] as needed."
fi
- id: compute_proceed_else_not
name: Compute whether for main jobs to proceed or not
# For checking whether github.event.head_commit.message starts with needs.set-vars.outputs.doc-commit-message
Expand Down Expand Up @@ -682,67 +741,72 @@ jobs:
run: |
# Run link test [`ipc_core` - Flow-IPC Core].
cd ${{ env.install-dir }}/bin
mkdir -p logs/ipc_core_link_test
OUT_DIR=logs/ipc_core_link_test
mkdir -p $OUT_DIR
SUPP_DIR_A=${{ github.workspace }}/flow/src
{ cat $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file2 }} \
> ${{ env.san-suppress-cfg-file }} 2> /dev/null; } || true
${{ env.setup-tests-env }}
./ipc_core_link_test.exec > logs/ipc_core_link_test/console.log 2>&1
./ipc_core_link_test.exec $OUT_DIR/log.log > $OUT_DIR/console.log 2>&1
- name: Run link test [`ipc_transport_structured` - Flow-IPC Structured Transport]
if: |
!cancelled()
run: |
# Run link test [`ipc_transport_structured` - Flow-IPC Structured Transport].
cd ${{ env.install-dir }}/bin
mkdir -p logs/ipc_transport_structured_link_test
OUT_DIR=logs/ipc_transport_structured_link_test
mkdir -p $OUT_DIR
SUPP_DIR_A=${{ github.workspace }}/flow/src
{ cat $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file2 }} \
> ${{ env.san-suppress-cfg-file }} 2> /dev/null; } || true
${{ env.setup-tests-env }}
./ipc_transport_structured_link_test.exec > logs/ipc_transport_structured_link_test/console.log 2>&1
./ipc_transport_structured_link_test.exec $OUT_DIR/log.log > $OUT_DIR/console.log 2>&1
- name: Run link test [`ipc_session` - Flow-IPC Sessions]
if: |
!cancelled()
run: |
# Run link test [`ipc_session` - Flow-IPC Sessions].
cd ${{ env.install-dir }}/bin
mkdir -p logs/ipc_session_link_test
OUT_DIR=logs/ipc_session_link_test
mkdir -p $OUT_DIR
SUPP_DIR_A=${{ github.workspace }}/flow/src
SUPP_DIR_B=${{ github.workspace }}/ipc_session/src
{ cat $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file2 }} \
$SUPP_DIR_B/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_B/${{ env.san-suppress-cfg-in-file2 }} \
> ${{ env.san-suppress-cfg-file }} 2> /dev/null; } || true
${{ env.setup-tests-env }}
./ipc_session_link_test_srv.exec > logs/ipc_session_link_test/srv.console.log 2>&1 &
./ipc_session_link_test_srv.exec $OUT_DIR/srv.log > $OUT_DIR/srv.console.log 2>&1 &
sleep 1
./ipc_session_link_test_cli.exec > logs/ipc_session_link_test/cli.console.log 2>&1
./ipc_session_link_test_cli.exec $OUT_DIR/cli.log > $OUT_DIR/cli.console.log 2>&1
- name: Run link test [`ipc_shm` - Flow-IPC Shared Memory]
if: |
!cancelled()
run: |
# Run link test [`ipc_shm` - Flow-IPC Shared Memory].
cd ${{ env.install-dir }}/bin
mkdir -p logs/ipc_shm_link_test
OUT_DIR=logs/ipc_shm_link_test
mkdir -p $OUT_DIR
SUPP_DIR_A=${{ github.workspace }}/flow/src
SUPP_DIR_B=${{ github.workspace }}/ipc_session/src
{ cat $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_A/${{ env.san-suppress-cfg-in-file2 }} \
$SUPP_DIR_B/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_B/${{ env.san-suppress-cfg-in-file2 }} \
> ${{ env.san-suppress-cfg-file }} 2> /dev/null; } || true
${{ env.setup-tests-env }}
./ipc_shm_link_test_srv.exec > logs/ipc_shm_link_test/srv.console.log 2>&1 &
./ipc_shm_link_test_srv.exec $OUT_DIR/srv.log > $OUT_DIR/srv.console.log 2>&1 &
sleep 1
./ipc_shm_link_test_cli.exec > logs/ipc_shm_link_test/cli.console.log 2>&1
./ipc_shm_link_test_cli.exec $OUT_DIR/cli.log > $OUT_DIR/cli.console.log 2>&1
- name: Run link test [`ipc_shm_arena_lend` - Flow-IPC SHM-jemalloc]
if: |
!cancelled()
run: |
# Run link test [`ipc_shm_arena_lend` - Flow-IPC SHM-jemalloc].
cd ${{ env.install-dir }}/bin
mkdir -p logs/ipc_shm_arena_lend_link_test
OUT_DIR=logs/ipc_shm_arena_lend_link_test
mkdir -p $OUT_DIR
SUPP_DIR_A=${{ github.workspace }}/flow/src
SUPP_DIR_B=${{ github.workspace }}/ipc_session/src
SUPP_DIR_C=${{ github.workspace }}/ipc_shm_arena_lend/src
Expand All @@ -751,9 +815,9 @@ jobs:
$SUPP_DIR_C/${{ env.san-suppress-cfg-in-file1 }} $SUPP_DIR_C/${{ env.san-suppress-cfg-in-file2 }} \
> ${{ env.san-suppress-cfg-file }} 2> /dev/null; } || true
${{ env.setup-tests-env }}
./ipc_shm_arena_lend_link_test_srv.exec > logs/ipc_shm_arena_lend_link_test/srv.console.log 2>&1 &
./ipc_shm_arena_lend_link_test_srv.exec $OUT_DIR/srv.log > $OUT_DIR/srv.console.log 2>&1 &
sleep 1
./ipc_shm_arena_lend_link_test_cli.exec > logs/ipc_shm_arena_lend_link_test/cli.console.log 2>&1
./ipc_shm_arena_lend_link_test_cli.exec $OUT_DIR/cli.log > $OUT_DIR/cli.console.log 2>&1
- name: Run unit tests
if: |
Expand Down
37 changes: 19 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ set(PROJ_CAMEL "Ipc")
set(PROJ_VERSION "1.0.0")
set(PROJ_HUMAN "Flow-IPC")

project(${PROJ_CAMEL} VERSION ${PROJ_VERSION} LANGUAGES CXX)

# The children below rely on this being set and its value to detect they're part of the meta-project,
# as opposed to being loaded separately, and then to load needed things off this place.
# So in *nix setting this indicates to each kid below that they're a part of one big `make`.
# (Whereas otherwise each kid is on its own and assumes the all its dependencies have had `make` and `make install`
# done, and the exported stuff is somewhere the `make` will know to search.)
set(IPC_META_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
set(FLOW_LIKE_META_ROOT ${CMAKE_CURRENT_SOURCE_DIR})

# The following might be a little tough to realize if looking through multiple layers of CMake scripts, so
# for your convenience let's summarize how we do the whole thing.
Expand Down Expand Up @@ -99,27 +97,30 @@ foreach(ipc_meta_project ${IPC_META_PROJECTS})
set(ipc_meta_project_dir "<unknown>")
endif()

set(IPC_META_ROOT_${ipc_meta_project} ${ipc_meta_project_dir} CACHE STRING
set(FLOW_LIKE_META_ROOT_${ipc_meta_project} ${ipc_meta_project_dir} CACHE STRING
"Location of sub-project [${ipc_meta_project}]; defaults to resolved [./${ipc_meta_project}] if exists.")

if(NOT (EXISTS ${IPC_META_ROOT_${ipc_meta_project}}))
message(FATAL_ERROR "[${IPC_META_ROOT_${ipc_meta_project}}] does not exist. Therefore: "
"Unable to determine IPC_META_ROOT_${ipc_meta_project}; either symlink "
if(NOT (EXISTS ${FLOW_LIKE_META_ROOT_${ipc_meta_project}}))
message(FATAL_ERROR "[${FLOW_LIKE_META_ROOT_${ipc_meta_project}}] does not exist. Therefore: "
"Unable to determine FLOW_LIKE_META_ROOT_${ipc_meta_project}; either symlink "
"[./${ipc_meta_project}], place sub-project there directly, or set "
"cache setting explicitly. You may need to now clear cache (or blow away build) "
"for the symlink or direct-placement methods to work.")
endif()

list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "(Path = [${IPC_META_ROOT_${ipc_meta_project}}]; it exists.)")
message(CHECK_PASS "(Path = [${FLOW_LIKE_META_ROOT_${ipc_meta_project}}]; it exists.)")
endblock()
endforeach()

# Got through that; now actually do the add_subdirectory()s. Output/error handling is crisper this way than doing
# add_subdirectory() within the above loop.
include("${FLOW_LIKE_META_ROOT_flow}/tools/cmake/FlowLikeProject.cmake") # Determine $PROJ_VERSION, at least.
project(${PROJ_CAMEL} VERSION ${PROJ_VERSION} DESCRIPTION ${PROJ_HUMAN} LANGUAGES CXX)

# Got through that; now actually do the add_subdirectory()s. This needs to below the project() call just above.
# (Also, output/error handling is crisper this way than doing add_subdirectory() within the above loop.)
foreach(ipc_meta_project ${IPC_META_PROJECTS})
# Finally! Note in the build output the name is normalized to simply ${ipc_meta_project} (e.g., "flow").
add_subdirectory(${IPC_META_ROOT_${ipc_meta_project}} ${ipc_meta_project})
add_subdirectory(${FLOW_LIKE_META_ROOT_${ipc_meta_project}} ${ipc_meta_project})
endforeach()

# Going back to the summary comment, we're now done with the sub-projects' code generation and, where applicable,
Expand All @@ -129,14 +130,14 @@ endforeach()
# that would also get built just as for each of the IPC_META_PROJECTs. We'd still just need the following line;
# no changes.)

include("${IPC_META_ROOT_flow}/tools/cmake/FlowLikeCodeGenerate.cmake")
include("${FLOW_LIKE_META_ROOT_flow}/tools/cmake/FlowLikeCodeGenerate.cmake")

# As noted in the summary FlowLikeCodeGenerate.cmake does not do doc generation.
# FlowLikeDocGenerate.cmake does that; and it's up to each project root CMake script to include() it.
# So let's do it, much like flow/CMakeLists.txt (which handles its own docs) does.

# See this guy; it'll explain inside. It mandates the following procedure and documents details.
set(DOC_GEN_CMAKE_SCRIPT "${IPC_META_ROOT_flow}/tools/cmake/FlowLikeDocGenerate.cmake")
set(DOC_GEN_CMAKE_SCRIPT "${FLOW_LIKE_META_ROOT_flow}/tools/cmake/FlowLikeDocGenerate.cmake")

# It may also be instructive to contrast with `flow`'s CMakeLists.txt.
# - Flow has its own self-contained doc generation, though it uses the same FlowLikeDocGenerate utility.
Expand All @@ -146,11 +147,11 @@ set(DOC_GEN_CMAKE_SCRIPT "${IPC_META_ROOT_flow}/tools/cmake/FlowLikeDocGenerate.
# - Therefore you see src/doc/manual, which lives directly inside this meta-project as opposed to any kid.

set(DOC_INPUT
${IPC_META_ROOT_ipc_core}/src/ipc
${IPC_META_ROOT_ipc_transport_structured}/src/ipc
${IPC_META_ROOT_ipc_session}/src/ipc
${IPC_META_ROOT_ipc_shm}/src/ipc
${IPC_META_ROOT_ipc_shm_arena_lend}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_core}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_transport_structured}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_session}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_shm}/src/ipc
${FLOW_LIKE_META_ROOT_ipc_shm_arena_lend}/src/ipc
src/doc/manual)

# For now I (ygoldfel) am excluding echan's SHM-jemalloc stuff which *has* been integrated into Flow-IPC
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,14 @@ pretty easy to have this Flow-IPC meta-project work with such a source tree. Th
a Flow-IPC `*_full.tar.gz` or `*_full.zip` archive,
you can rename or delete the existing `./flow` before setting the symlink.
- You can specify a different Flow project root entirely; use the CMake knob (cache setting) named
`IPC_META_ROOT_flow` to specify the path to this directory. So `cmake -DIPC_META_ROOT_flow=...`
`FLOW_LIKE_META_ROOT_flow` to specify the path to this directory. So `cmake -DFLOW_LIKE_META_ROOT_flow=...`
(or `ccmake ...same...`).
- In this case `./flow` will be ignored (whether or not it exists).

Actually, one can use either of those 2 technique for some or all of the
`ipc_{core|transport_structured|session|shm|shm_arena_lend}` sub-projects as well.
The symlink or cache-setting name would be not `flow` or `IPC_META_ROOT_flow` but instead
`ipc_{...|...|...|...|...}` or `IPC_META_ROOT_ipc_{...|...|...|...|...}`, respectively,
The symlink or cache-setting name would be not `flow` or `FLOW_LIKE_META_ROOT_flow` but instead
`ipc_{...|...|...|...|...}` or `FLOW_LIKE_META_ROOT_ipc_{...|...|...|...|...}`, respectively,
depending on the sub-project in question.

That said it will only work if it is indeed a bona-fide open-source tree with a root `CMakeLists.txt`
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
16 changes: 12 additions & 4 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout, CMakeDeps, CMakeToolchain

def load_version_from_file(): # TODO: Code-reuse from flow/conanfile.py?
version_path = './VERSION'
with open(version_path, 'r') as version_file:
# Read the entire file content and strip whitespace (matches what FlowLikeProject.cmake does).
version = version_file.read().strip()
return version

class IpcRecipe(ConanFile):
name = "ipc"
version = "1.0"
version = load_version_from_file()
settings = "os", "compiler", "build_type", "arch"

DOXYGEN_VERSION = "1.9.4"

options = {
"build": [True, False],
"build_no_lto": [True, False],
Expand Down Expand Up @@ -39,8 +48,7 @@ def configure(self):
def generate(self):
deps = CMakeDeps(self)
if self.options.doc:
# TODO: This magic version number is repeated several times. Code reuse.
deps.build_context_activated = ["doxygen/1.9.4"]
deps.build_context_activated = [f"doxygen/{self.DOXYGEN_VERSION}"]
deps.generate()

toolchain = CMakeToolchain(self)
Expand Down Expand Up @@ -98,7 +106,7 @@ def requirements(self):
def build_requirements(self):
self.tool_requires("cmake/3.26.3")
if self.options.doc:
self.tool_requires("doxygen/1.9.4")
self.tool_requires(f"doxygen/{self.DOXYGEN_VERSION}")

def package(self):
cmake = CMake(self)
Expand Down
2 changes: 1 addition & 1 deletion flow
Submodule flow updated 1020 files
2 changes: 1 addition & 1 deletion ipc_transport_structured
4 changes: 2 additions & 2 deletions test/suite/transport_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ set(NAME_ROOT transport_test)
set(NAME "${NAME_ROOT}.exec")

# Please see explanation in ipc_session's src/CMakeLists.txt for why we do the following.
set(CAPNPC_IMPORT_DIRS ${IPC_META_ROOT_ipc_transport_structured}/src
${IPC_META_ROOT_ipc_shm}/src)
set(CAPNPC_IMPORT_DIRS ${FLOW_LIKE_META_ROOT_ipc_transport_structured}/src
${FLOW_LIKE_META_ROOT_ipc_shm}/src)

capnp_generate_cpp(capnp_generated_srcs capnp_generated_hdrs_ignored "ex.capnp")

Expand Down
Loading

0 comments on commit ff937af

Please sign in to comment.