This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new f2ceac78d examples/sotest: support packaged shared library fixtures.
f2ceac78d is described below

commit f2ceac78db76d54b4a2cf8fdc3275edd690d2e50
Author: aviralgarg05 <[email protected]>
AuthorDate: Sat Jul 11 21:57:50 2026 +0530

    examples/sotest: support packaged shared library fixtures.
    
    Extend the examples/sotest packaging path so the shared-library test
    fixtures can also be prepared through nxpkg-style package artifacts.
    
    Generate shared-index.json and pkgsotest.nsh from the built modprint
    and sotest shared objects, recording the correct target arch/compat
    metadata and SHA-256 digests for the packaged shared-library fixtures.
    Allow sotest to run in either its existing builtin-ROMFS flow or from
    explicit shared-library paths, with a --mount helper mode for
    preparing the builtin test mount separately. Keep the paired fixture
    outputs in one grouped make step so parallel builds do not re-enter
    the generator independently.
    
    This makes the sotest shared-library example usable as a
    package-style fixture producer for the Dynamic ELF/nxpkg series,
    useful for validating the shared-library side of the packaging flow
    where the loader should consume installed artifacts rather than only
    the default builtin test paths. The existing builtin-ROMFS path is
    preserved with no regression to the normal sotest example flow.
    
    Assisted-by: Claude:claude-sonnet-5
    Assisted-by: OpenAI Codex:gpt-5.6-sol
    Signed-off-by: aviralgarg05 <[email protected]>
---
 examples/sotest/Make.defs                         |   9 +-
 examples/sotest/main/CMakeLists.txt               | 114 +++++-
 examples/sotest/main/Makefile                     |  30 +-
 examples/sotest/main/{ => host}/CMakeLists.txt    |  29 +-
 examples/sotest/main/mk_pkg_fixture_shared.c      | 433 ++++++++++++++++++++++
 examples/sotest/main/sotest_main.c                |  98 ++++-
 examples/sotest/{main => modprint}/CMakeLists.txt |  26 +-
 examples/sotest/{main => sotest}/CMakeLists.txt   |  26 +-
 8 files changed, 661 insertions(+), 104 deletions(-)

diff --git a/examples/sotest/Make.defs b/examples/sotest/Make.defs
index c674e34e6..17afaca43 100644
--- a/examples/sotest/Make.defs
+++ b/examples/sotest/Make.defs
@@ -20,4 +20,11 @@
 #
 ############################################################################
 
-include $(wildcard $(APPDIR)/examples/sotest/*/Make.defs)
+ifeq ($(CONFIG_EXAMPLES_SOTEST),y)
+include $(APPDIR)/examples/sotest/main/Make.defs
+endif
+
+ifneq ($(CONFIG_EXAMPLES_SOTEST),n)
+include $(APPDIR)/examples/sotest/modprint/Make.defs
+include $(APPDIR)/examples/sotest/sotest/Make.defs
+endif
diff --git a/examples/sotest/main/CMakeLists.txt 
b/examples/sotest/main/CMakeLists.txt
index caca43d22..5c5cef5a6 100644
--- a/examples/sotest/main/CMakeLists.txt
+++ b/examples/sotest/main/CMakeLists.txt
@@ -21,27 +21,107 @@
 # 
##############################################################################
 
 if(CONFIG_EXAMPLES_SOTEST)
+  set(SOTEST_SYMTAB ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c)
+  set(SOTEST_ROMFS_IMG ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.img)
+  set(SOTEST_ROMFS_SRC ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c)
+  set(SOTEST_MODPRINT_ELF ${CMAKE_BINARY_DIR}/bin/modprint)
+  set(SOTEST_SHARED_ELF ${CMAKE_BINARY_DIR}/bin/sotest)
+
+  # Dynamic applications are wrapped in ELF_* helper targets when the build 
uses
+  # the non-ELF-capable compiler path.
+  if(CMAKE_C_ELF_COMPILER)
+    set(SOTEST_MODPRINT_TARGET modprint)
+    set(SOTEST_SHARED_TARGET sotest)
+  else()
+    set(SOTEST_MODPRINT_TARGET ELF_modprint)
+    set(SOTEST_SHARED_TARGET ELF_sotest)
+  endif()
 
-  # FIXME: fix all empty a after the kernel build is implemented
   add_custom_command(
-    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    COMMAND
-      ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${CMAKE_CURRENT_BINARY_DIR}/empty
-      g_sot > ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c)
+    OUTPUT ${SOTEST_SYMTAB}
+    COMMAND ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${SOTEST_MODPRINT_ELF}
+            ${SOTEST_SHARED_ELF} g_sot > ${SOTEST_SYMTAB}
+    DEPENDS ${SOTEST_MODPRINT_TARGET} ${SOTEST_SHARED_TARGET})
 
-  add_custom_target(
-    sotest_romfs
-    COMMAND genromfs -f sotest_romfs.img -d empty
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+  set_source_files_properties(${SOTEST_SYMTAB} PROPERTIES GENERATED TRUE)
 
-  add_custom_command(
-    OUTPUT sotest_romfs.c
-    COMMAND xxd -i sotest_romfs.img > sotest_romfs.c
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    DEPENDS sotest_romfs)
+  set(SOTEST_GENERATED_OUTPUTS ${SOTEST_SYMTAB})
+  set(SOTEST_SRCS sotest_main.c ${SOTEST_SYMTAB})
+
+  if(CONFIG_EXAMPLES_SOTEST_BUILTINFS)
+    set(SOTEST_ROMFS_DEPS ${SOTEST_MODPRINT_TARGET} ${SOTEST_SHARED_TARGET})
+
+    if(CONFIG_SYSTEM_NXPKG)
+      set(SOTEST_SHARED_INDEX ${CMAKE_BINARY_DIR}/bin/shared-index.json)
+      set(SOTEST_SHARED_SCRIPT ${CMAKE_BINARY_DIR}/bin/pkgsotest.nsh)
+      set(SOTEST_FIXTURE_HOST_DIR ${CMAKE_CURRENT_BINARY_DIR}/host)
+      set(SOTEST_FIXTURE_HOST_SRC
+          ${CMAKE_CURRENT_SOURCE_DIR}/host/CMakeLists.txt)
+      set(SOTEST_FIXTURE_TOOL
+          
${SOTEST_FIXTURE_HOST_DIR}/mk_pkg_fixture_shared${CMAKE_EXECUTABLE_SUFFIX}
+      )
+
+      if(CONFIG_ARCH_BOARD)
+        set(SOTEST_FIXTURE_COMPAT ${CONFIG_ARCH_BOARD})
+      else()
+        set(SOTEST_FIXTURE_COMPAT ${CONFIG_ARCH_BOARD_CUSTOM_NAME})
+      endif()
+
+      add_custom_command(
+        OUTPUT ${SOTEST_FIXTURE_TOOL}
+        COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/host -B
+                ${SOTEST_FIXTURE_HOST_DIR}
+        COMMAND ${CMAKE_COMMAND} --build ${SOTEST_FIXTURE_HOST_DIR} --target
+                mk_pkg_fixture_shared
+        DEPENDS ${SOTEST_FIXTURE_HOST_SRC}
+                ${CMAKE_CURRENT_SOURCE_DIR}/mk_pkg_fixture_shared.c
+        VERBATIM)
+
+      add_custom_command(
+        OUTPUT ${SOTEST_SHARED_INDEX} ${SOTEST_SHARED_SCRIPT}
+        COMMAND
+          ${SOTEST_FIXTURE_TOOL} ${SOTEST_MODPRINT_ELF} ${SOTEST_SHARED_ELF}
+          ${SOTEST_SHARED_INDEX} ${SOTEST_SHARED_SCRIPT} ${CONFIG_ARCH}
+          ${SOTEST_FIXTURE_COMPAT}
+        DEPENDS ${SOTEST_MODPRINT_TARGET} ${SOTEST_SHARED_TARGET}
+                ${SOTEST_FIXTURE_TOOL}
+        VERBATIM)
+
+      list(APPEND SOTEST_ROMFS_DEPS ${SOTEST_SHARED_INDEX}
+           ${SOTEST_SHARED_SCRIPT})
+    endif()
+
+    add_custom_command(
+      OUTPUT ${SOTEST_ROMFS_IMG}
+      COMMAND genromfs -f ${SOTEST_ROMFS_IMG} -d ${CMAKE_BINARY_DIR}/bin
+      DEPENDS ${SOTEST_ROMFS_DEPS}
+      VERBATIM)
+
+    get_filename_component(SOTEST_ROMFS_IMG_NAME ${SOTEST_ROMFS_IMG} NAME)
+
+    # xxd -i derives the generated array/length symbol names from the exact 
path
+    # it is given - sotest_main.c declares them as plain
+    # "sotest_romfs_img"/"sotest_romfs_img_len", so xxd must be run against 
just
+    # the bare filename (via WORKING_DIRECTORY) rather than the absolute
+    # ${SOTEST_ROMFS_IMG} path, or every non- alphanumeric character in that
+    # path (e.g. every "/" in the build directory) gets folded into the symbol
+    # name instead, leaving the names sotest_main.c expects undefined at link
+    # time.
+
+    add_custom_command(
+      OUTPUT ${SOTEST_ROMFS_SRC}
+      COMMAND xxd -i ${SOTEST_ROMFS_IMG_NAME} > ${SOTEST_ROMFS_SRC}
+      DEPENDS ${SOTEST_ROMFS_IMG}
+      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+    set_source_files_properties(${SOTEST_ROMFS_SRC} PROPERTIES GENERATED TRUE)
+
+    list(APPEND SOTEST_GENERATED_OUTPUTS ${SOTEST_ROMFS_SRC})
+    list(APPEND SOTEST_SRCS ${SOTEST_ROMFS_SRC})
+  endif()
 
-  nuttx_add_application(
-    NAME sotest SRCS sotest_main.c ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c)
+  add_custom_target(sotest_artifacts DEPENDS ${SOTEST_GENERATED_OUTPUTS})
 
+  nuttx_add_application(NAME sotest SRCS ${SOTEST_SRCS} DEPENDS
+                        sotest_artifacts)
 endif()
diff --git a/examples/sotest/main/Makefile b/examples/sotest/main/Makefile
index 064b0b434..327b60c9e 100644
--- a/examples/sotest/main/Makefile
+++ b/examples/sotest/main/Makefile
@@ -50,8 +50,34 @@ ifeq ($(CONFIG_EXAMPLES_SOTEST_BUILTINFS),y)
 ROMFSIMG = sotest_romfs.img
 ROMFSSRC = sotest_romfs.c
 ROMFSOBJ = $(ROMFSSRC:.c=$(OBJEXT))
+ifdef CONFIG_SYSTEM_NXPKG
+HOSTOBJSEXT ?= hobj
+PKGSHAREDINDEX = $(BINDIR)/shared-index.json
+PKGSHAREDTEST = $(BINDIR)/pkgsotest.nsh
+PKG_FIXTURE_GEN = mk_pkg_fixture_shared$(HOSTEXEEXT)
+PKG_FIXTURE_SRCS = mk_pkg_fixture_shared.c
+PKG_FIXTURE_OBJS = $(PKG_FIXTURE_SRCS:.c=.$(HOSTOBJSEXT))
+PKG_FIXTURE_OUTPUTS = $(PKGSHAREDINDEX) $(PKGSHAREDTEST)
+PKG_FIXTURE_STAMP = $(BINDIR)/.pkgsotest.stamp
+PKG_FIXTURE_COMPAT = $(if 
$(CONFIG_ARCH_BOARD),$(CONFIG_ARCH_BOARD),$(CONFIG_ARCH_BOARD_CUSTOM_NAME))
+
+$(PKG_FIXTURE_OBJS): %.$(HOSTOBJSEXT): %.c
+       @echo "CC:  $<"
+       $(Q) $(HOSTCC) -c $(HOSTCFLAGS) $< -o $@
+
+$(PKG_FIXTURE_GEN): $(PKG_FIXTURE_OBJS)
+       $(Q) $(HOSTCC) $(HOSTLDFLAGS) $(PKG_FIXTURE_OBJS) -o $@
+
+$(PKG_FIXTURE_OUTPUTS): $(PKG_FIXTURE_STAMP)
+
+$(PKG_FIXTURE_STAMP): $(BINDIR)/modprint $(BINDIR)/sotest $(PKG_FIXTURE_GEN)
+       $(Q) ./$(PKG_FIXTURE_GEN) $(BINDIR)/modprint $(BINDIR)/sotest \
+               $(PKGSHAREDINDEX) $(PKGSHAREDTEST) $(CONFIG_ARCH) \
+               $(PKG_FIXTURE_COMPAT)
+       $(Q) touch $@
+endif
 
-$(ROMFSIMG):
+$(ROMFSIMG): $(PKG_FIXTURE_OUTPUTS)
        $(Q) genromfs -d $(BINDIR) -f $@
 
 $(ROMFSSRC): $(ROMFSIMG)
@@ -67,6 +93,6 @@ postinstall:: $(ROMFSOBJ) $(SYMTABOBJ) $(FSIMG_OBJ)
        $(call ARLOCK, $(call CONVERT_PATH,$(BIN)), $^)
 
 distclean::
-       $(Q) $(call DELFILE, $(SYMTABSRC) $(SYMTABOBJ) $(ROMFSSRC) $(ROMFSIMG) 
$(ROMFSOBJ))
+       $(Q) $(call DELFILE, $(SYMTABSRC) $(SYMTABOBJ) $(ROMFSSRC) $(ROMFSIMG) 
$(ROMFSOBJ) $(PKG_FIXTURE_GEN) $(PKG_FIXTURE_OBJS) $(PKG_FIXTURE_STAMP))
 
 include $(APPDIR)/Application.mk
diff --git a/examples/sotest/main/CMakeLists.txt 
b/examples/sotest/main/host/CMakeLists.txt
similarity index 54%
copy from examples/sotest/main/CMakeLists.txt
copy to examples/sotest/main/host/CMakeLists.txt
index caca43d22..e83524d29 100644
--- a/examples/sotest/main/CMakeLists.txt
+++ b/examples/sotest/main/host/CMakeLists.txt
@@ -1,5 +1,5 @@
 # 
##############################################################################
-# apps/examples/sotest/main/CMakeLists.txt
+# apps/examples/sotest/main/host/CMakeLists.txt
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -20,28 +20,7 @@
 #
 # 
##############################################################################
 
-if(CONFIG_EXAMPLES_SOTEST)
+cmake_minimum_required(VERSION 3.16)
+project(sotest_fixture_host LANGUAGES C)
 
-  # FIXME: fix all empty a after the kernel build is implemented
-  add_custom_command(
-    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    COMMAND
-      ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${CMAKE_CURRENT_BINARY_DIR}/empty
-      g_sot > ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c)
-
-  add_custom_target(
-    sotest_romfs
-    COMMAND genromfs -f sotest_romfs.img -d empty
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
-  add_custom_command(
-    OUTPUT sotest_romfs.c
-    COMMAND xxd -i sotest_romfs.img > sotest_romfs.c
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    DEPENDS sotest_romfs)
-
-  nuttx_add_application(
-    NAME sotest SRCS sotest_main.c ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c)
-
-endif()
+add_executable(mk_pkg_fixture_shared ../mk_pkg_fixture_shared.c)
diff --git a/examples/sotest/main/mk_pkg_fixture_shared.c 
b/examples/sotest/main/mk_pkg_fixture_shared.c
new file mode 100644
index 000000000..713cd7115
--- /dev/null
+++ b/examples/sotest/main/mk_pkg_fixture_shared.c
@@ -0,0 +1,433 @@
+/****************************************************************************
+ * apps/examples/sotest/main/mk_pkg_fixture_shared.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SHA256_BLOCK_SIZE 64
+#define SHA256_DIGEST_SIZE 32
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct sha256_state_s
+{
+  uint32_t state[8];
+  uint64_t bitcount;
+  uint8_t buffer[SHA256_BLOCK_SIZE];
+  size_t buffer_len;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const uint32_t g_sha256_init[8] =
+{
+  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+
+static const uint32_t g_sha256_k[64] =
+{
+  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint32_t sha256_rotr(uint32_t value, unsigned int bits)
+{
+  return (value >> bits) | (value << (32 - bits));
+}
+
+static uint32_t sha256_ch(uint32_t x, uint32_t y, uint32_t z)
+{
+  return (x & y) ^ (~x & z);
+}
+
+static uint32_t sha256_maj(uint32_t x, uint32_t y, uint32_t z)
+{
+  return (x & y) ^ (x & z) ^ (y & z);
+}
+
+static uint32_t sha256_bs0(uint32_t x)
+{
+  return sha256_rotr(x, 2) ^ sha256_rotr(x, 13) ^ sha256_rotr(x, 22);
+}
+
+static uint32_t sha256_bs1(uint32_t x)
+{
+  return sha256_rotr(x, 6) ^ sha256_rotr(x, 11) ^ sha256_rotr(x, 25);
+}
+
+static uint32_t sha256_ss0(uint32_t x)
+{
+  return sha256_rotr(x, 7) ^ sha256_rotr(x, 18) ^ (x >> 3);
+}
+
+static uint32_t sha256_ss1(uint32_t x)
+{
+  return sha256_rotr(x, 17) ^ sha256_rotr(x, 19) ^ (x >> 10);
+}
+
+static uint32_t sha256_load32(const uint8_t *src)
+{
+  return ((uint32_t)src[0] << 24) | ((uint32_t)src[1] << 16) |
+         ((uint32_t)src[2] << 8) | (uint32_t)src[3];
+}
+
+static void sha256_store32(uint8_t *dst, uint32_t value)
+{
+  dst[0] = (uint8_t)(value >> 24);
+  dst[1] = (uint8_t)(value >> 16);
+  dst[2] = (uint8_t)(value >> 8);
+  dst[3] = (uint8_t)value;
+}
+
+static void sha256_transform(struct sha256_state_s *ctx,
+                             const uint8_t block[SHA256_BLOCK_SIZE])
+{
+  uint32_t schedule[64];
+  uint32_t a;
+  uint32_t b;
+  uint32_t c;
+  uint32_t d;
+  uint32_t e;
+  uint32_t f;
+  uint32_t g;
+  uint32_t h;
+  int i;
+
+  for (i = 0; i < 16; i++)
+    {
+      schedule[i] = sha256_load32(block + i * 4);
+    }
+
+  for (; i < 64; i++)
+    {
+      schedule[i] = sha256_ss1(schedule[i - 2]) + schedule[i - 7] +
+                    sha256_ss0(schedule[i - 15]) + schedule[i - 16];
+    }
+
+  a = ctx->state[0];
+  b = ctx->state[1];
+  c = ctx->state[2];
+  d = ctx->state[3];
+  e = ctx->state[4];
+  f = ctx->state[5];
+  g = ctx->state[6];
+  h = ctx->state[7];
+
+  for (i = 0; i < 64; i++)
+    {
+      uint32_t t1 = h + sha256_bs1(e) + sha256_ch(e, f, g) + g_sha256_k[i] +
+                    schedule[i];
+      uint32_t t2 = sha256_bs0(a) + sha256_maj(a, b, c);
+
+      h = g;
+      g = f;
+      f = e;
+      e = d + t1;
+      d = c;
+      c = b;
+      b = a;
+      a = t1 + t2;
+    }
+
+  ctx->state[0] += a;
+  ctx->state[1] += b;
+  ctx->state[2] += c;
+  ctx->state[3] += d;
+  ctx->state[4] += e;
+  ctx->state[5] += f;
+  ctx->state[6] += g;
+  ctx->state[7] += h;
+}
+
+static void sha256_init(struct sha256_state_s *ctx)
+{
+  memcpy(ctx->state, g_sha256_init, sizeof(g_sha256_init));
+  ctx->bitcount = 0;
+  ctx->buffer_len = 0;
+}
+
+static void sha256_update(struct sha256_state_s *ctx, const uint8_t *data,
+                          size_t len)
+{
+  ctx->bitcount += (uint64_t)len * 8;
+
+  while (len > 0)
+    {
+      size_t space = SHA256_BLOCK_SIZE - ctx->buffer_len;
+      size_t chunk = len < space ? len : space;
+
+      memcpy(ctx->buffer + ctx->buffer_len, data, chunk);
+      ctx->buffer_len += chunk;
+      data += chunk;
+      len -= chunk;
+
+      if (ctx->buffer_len == SHA256_BLOCK_SIZE)
+        {
+          sha256_transform(ctx, ctx->buffer);
+          ctx->buffer_len = 0;
+        }
+    }
+}
+
+static void sha256_final(struct sha256_state_s *ctx,
+                         uint8_t digest[SHA256_DIGEST_SIZE])
+{
+  uint8_t length_bytes[8];
+  uint8_t padding[SHA256_BLOCK_SIZE] =
+  {
+    0x80
+  };
+
+  int i;
+
+  for (i = 0; i < 8; i++)
+    {
+      length_bytes[7 - i] = (uint8_t)(ctx->bitcount >> (i * 8));
+    }
+
+  if (ctx->buffer_len < 56)
+    {
+      sha256_update(ctx, padding, 56 - ctx->buffer_len);
+    }
+  else
+    {
+      sha256_update(ctx, padding, SHA256_BLOCK_SIZE - ctx->buffer_len);
+      sha256_update(ctx, padding + 1, 56);
+    }
+
+  sha256_update(ctx, length_bytes, sizeof(length_bytes));
+
+  for (i = 0; i < 8; i++)
+    {
+      sha256_store32(digest + i * 4, ctx->state[i]);
+    }
+}
+
+static int sha256_file(const char *path, char *digest_hex, size_t digest_len)
+{
+  struct sha256_state_s ctx;
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  uint8_t buffer[4096];
+  static const char g_hex[] = "0123456789abcdef";
+  FILE *stream;
+  size_t nread;
+  int i;
+
+  if (digest_len < SHA256_DIGEST_SIZE * 2 + 1)
+    {
+      fprintf(stderr, "digest buffer is too small\n");
+      return -1;
+    }
+
+  stream = fopen(path, "rb");
+  if (stream == NULL)
+    {
+      fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
+      return -1;
+    }
+
+  sha256_init(&ctx);
+
+  while ((nread = fread(buffer, 1, sizeof(buffer), stream)) > 0)
+    {
+      sha256_update(&ctx, buffer, nread);
+    }
+
+  if (ferror(stream) != 0)
+    {
+      fprintf(stderr, "failed to read %s: %s\n", path, strerror(errno));
+      fclose(stream);
+      return -1;
+    }
+
+  fclose(stream);
+  sha256_final(&ctx, digest);
+
+  for (i = 0; i < SHA256_DIGEST_SIZE; i++)
+    {
+      digest_hex[i * 2] = g_hex[digest[i] >> 4];
+      digest_hex[i * 2 + 1] = g_hex[digest[i] & 0x0f];
+    }
+
+  digest_hex[SHA256_DIGEST_SIZE * 2] = '\0';
+  return 0;
+}
+
+static int write_text_file(const char *path, const char *content)
+{
+  FILE *stream = fopen(path, "w");
+
+  if (stream == NULL)
+    {
+      fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
+      return -1;
+    }
+
+  if (fputs(content, stream) == EOF)
+    {
+      fprintf(stderr, "failed to write %s: %s\n", path, strerror(errno));
+      fclose(stream);
+      return -1;
+    }
+
+  if (fclose(stream) != 0)
+    {
+      fprintf(stderr, "failed to close %s: %s\n", path, strerror(errno));
+      return -1;
+    }
+
+  return 0;
+}
+
+static int write_index_file(const char *path, const char *arch,
+                            const char *compat, const char *modprint_digest,
+                            const char *sotest_digest)
+{
+  FILE *stream = fopen(path, "w");
+
+  if (stream == NULL)
+    {
+      fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
+      return -1;
+    }
+
+  if (fprintf(stream,
+              "{\"_nxpkg_source\":\"/etc/nxpkg/index.json\","
+              "\"packages\":["
+              "{\"name\":\"modprint\",\"version\":\"1.0.0\",\"arch\":\"%s\","
+              "\"compat\":\"%s\","
+              "\"artifact\":\"modprint\","
+              "\"sha256\":\"%s\",\"type\":\"shared-lib\"},"
+              "{\"name\":\"modprint\",\"version\":\"9.9.9\","
+              "\"arch\":\"arm\","
+              "\"compat\":\"stm32f4discovery\","
+              "\"artifact\":\"modprint\","
+              "\"sha256\":\"%s\",\"type\":\"shared-lib\"},"
+              "{\"name\":\"sotest\",\"version\":\"1.0.0\",\"arch\":\"%s\","
+              "\"compat\":\"%s\",\"artifact\":\"sotest\","
+              "\"sha256\":\"%s\",\"type\":\"shared-lib\"},"
+              "{\"name\":\"sotest\",\"version\":\"9.9.9\",\"arch\":\"arm\","
+              "\"compat\":\"stm32f4discovery\","
+              "\"artifact\":\"sotest\","
+              "\"sha256\":\"%s\",\"type\":\"shared-lib\"}"
+              "]}\n",
+              arch, compat, modprint_digest, modprint_digest, arch, compat,
+              sotest_digest, sotest_digest) < 0)
+    {
+      fprintf(stderr, "failed to write %s: %s\n", path, strerror(errno));
+      fclose(stream);
+      return -1;
+    }
+
+  if (fclose(stream) != 0)
+    {
+      fprintf(stderr, "failed to close %s: %s\n", path, strerror(errno));
+      return -1;
+    }
+
+  return 0;
+}
+
+static void usage(const char *progname)
+{
+  fprintf(stderr,
+          "usage: %s <modprint-bin> <sotest-bin> <shared-index-json> "
+          "<pkgsotest-nsh> <arch> <compat>\n",
+          progname);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char *argv[])
+{
+  char modprint_digest[SHA256_DIGEST_SIZE * 2 + 1];
+  char sotest_digest[SHA256_DIGEST_SIZE * 2 + 1];
+  static const char g_pkgsotest[] =
+    "mount -t tmpfs /etc\n"
+    "mount -t tmpfs /var\n"
+    "mkdir /etc/nxpkg\n"
+    "cp /mnt/sotest/romfs/shared-index.json /etc/nxpkg/index.json\n"
+    "cp /mnt/sotest/romfs/modprint /etc/nxpkg/modprint\n"
+    "cp /mnt/sotest/romfs/sotest /etc/nxpkg/sotest\n"
+    "mkdir /var/lib\n"
+    "mkdir /var/lib/nxpkg\n"
+    "cp /mnt/sotest/romfs/shared-index.json /var/lib/nxpkg/index.jsn\n"
+    "nxpkg install modprint\n"
+    "nxpkg install sotest\n"
+    "cp /var/lib/nxpkg/pkgs/modprint/1.0.0/modprint /etc/m\n"
+    "cp /var/lib/nxpkg/pkgs/sotest/1.0.0/sotest /etc/s\n"
+    "sotest /etc/m /etc/s\n"
+    "nxpkg list\n";
+
+  if (argc != 7)
+    {
+      usage(argv[0]);
+      return EXIT_FAILURE;
+    }
+
+  if (sha256_file(argv[1], modprint_digest, sizeof(modprint_digest)) < 0 ||
+      sha256_file(argv[2], sotest_digest, sizeof(sotest_digest)) < 0 ||
+      write_index_file(argv[3], argv[5], argv[6], modprint_digest,
+                       sotest_digest) < 0 ||
+      write_text_file(argv[4], g_pkgsotest) < 0)
+    {
+      return EXIT_FAILURE;
+    }
+
+  return EXIT_SUCCESS;
+}
diff --git a/examples/sotest/main/sotest_main.c 
b/examples/sotest/main/sotest_main.c
index 0d399568f..6b2417ddb 100644
--- a/examples/sotest/main/sotest_main.c
+++ b/examples/sotest/main/sotest_main.c
@@ -82,6 +82,21 @@
 
 #define SOTEST_DEVPATH_FMT "/dev/ram%d"
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void sotest_show_usage(FAR const char *progname)
+{
+#if CONFIG_LIBC_ELF_MAXDEPEND > 0
+  fprintf(stderr,
+          "Usage: %s [--mount] [<modprint-path> <sotest-path>]\n",
+          progname);
+#else
+  fprintf(stderr, "Usage: %s [--mount] [<sotest-path>]\n", progname);
+#endif
+}
+
 /****************************************************************************
  * Symbols from Auto-Generated Code
  ****************************************************************************/
@@ -104,7 +119,11 @@ extern const int g_sot_nexports;
 
 int main(int argc, FAR char *argv[])
 {
+  FAR const char *modprint_path = NULL;
+  FAR const char *sotest_path = NULL;
+  bool mount_only = false;
 #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS
+  bool mounted_builtinfs = false;
   char devname[32];
 #endif
 #if CONFIG_LIBC_ELF_MAXDEPEND > 0
@@ -117,6 +136,38 @@ int main(int argc, FAR char *argv[])
 #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS
   struct boardioc_romdisk_s desc;
 #endif
+
+#if CONFIG_LIBC_ELF_MAXDEPEND > 0
+  if (argc == 2 && strcmp(argv[1], "--mount") == 0)
+    {
+      mount_only = true;
+    }
+  else if (argc == 3)
+    {
+      modprint_path = argv[1];
+      sotest_path = argv[2];
+    }
+  else if (argc != 1)
+    {
+      sotest_show_usage(argv[0]);
+      return EXIT_FAILURE;
+    }
+#else
+  if (argc == 2 && strcmp(argv[1], "--mount") == 0)
+    {
+      mount_only = true;
+    }
+  else if (argc == 2)
+    {
+      sotest_path = argv[1];
+    }
+  else if (argc != 1)
+    {
+      sotest_show_usage(argv[0]);
+      return EXIT_FAILURE;
+    }
+#endif
+
   /* Set the shared library symbol table */
 
   ret = dlsymtab((FAR struct symtab_s *)g_sot_exports, g_sot_nexports);
@@ -127,6 +178,8 @@ int main(int argc, FAR char *argv[])
     }
 
 #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS
+  if (sotest_path == NULL || mount_only)
+    {
   /* Create a ROM disk for the ROMFS filesystem */
 
   desc.minor    = 0;                                   /* Minor device number 
of the ROM disk. */
@@ -168,28 +221,48 @@ int main(int argc, FAR char *argv[])
               devname, BINDIR, strerror(errno));
       exit(EXIT_FAILURE);
     }
+
+      mounted_builtinfs = true;
+    }
 #endif /* CONFIG_EXAMPLES_SOTEST_BUILTINFS */
 
+  if (mount_only)
+    {
+      return EXIT_SUCCESS;
+    }
+
+#if CONFIG_LIBC_ELF_MAXDEPEND > 0
+  if (modprint_path == NULL)
+    {
+      modprint_path = BINDIR "/modprint";
+    }
+#endif
+
+  if (sotest_path == NULL)
+    {
+      sotest_path = BINDIR "/sotest";
+    }
+
 #if CONFIG_LIBC_ELF_MAXDEPEND > 0
   /* Install the first test shared library.  The first shared library only
    * verifies that symbols exported by one shared library can be used to
    * resolve undefined symbols in a second shared library.
    */
 
-  handle1 = dlopen(BINDIR "/modprint", RTLD_NOW | RTLD_LOCAL);
+  handle1 = dlopen(modprint_path, RTLD_NOW | RTLD_LOCAL);
   if (handle1 == NULL)
     {
-      fprintf(stderr, "ERROR: dlopen(%s/modprint) failed\n", BINDIR);
+      fprintf(stderr, "ERROR: dlopen(%s) failed\n", modprint_path);
       exit(EXIT_FAILURE);
     }
 #endif
 
   /* Install the second test shared library  */
 
-  handle2 = dlopen(BINDIR "/sotest", RTLD_NOW | RTLD_LOCAL);
+  handle2 = dlopen(sotest_path, RTLD_NOW | RTLD_LOCAL);
   if (handle2 == NULL)
     {
-      fprintf(stderr, "ERROR: dlopen(%s/sotest) failed\n", BINDIR);
+      fprintf(stderr, "ERROR: dlopen(%s) failed\n", sotest_path);
       exit(EXIT_FAILURE);
     }
 
@@ -288,15 +361,18 @@ int main(int argc, FAR char *argv[])
 #endif
 
 #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS
-  ret = umount(BINDIR);
-  if (ret < 0)
+  if (mounted_builtinfs)
     {
-      fprintf(stderr, "ERROR: umount(%s) failed: %d\n",
-              BINDIR, errno);
-      exit(EXIT_FAILURE);
-    }
+      ret = umount(BINDIR);
+      if (ret < 0)
+        {
+          fprintf(stderr, "ERROR: umount(%s) failed: %d\n",
+                  BINDIR, errno);
+          exit(EXIT_FAILURE);
+        }
 
-  unlink(devname);
+      unlink(devname);
+    }
 #endif /* CONFIG_EXAMPLES_SOTEST_BUILTINFS */
 
   return EXIT_SUCCESS;
diff --git a/examples/sotest/main/CMakeLists.txt 
b/examples/sotest/modprint/CMakeLists.txt
similarity index 55%
copy from examples/sotest/main/CMakeLists.txt
copy to examples/sotest/modprint/CMakeLists.txt
index caca43d22..0fbeef868 100644
--- a/examples/sotest/main/CMakeLists.txt
+++ b/examples/sotest/modprint/CMakeLists.txt
@@ -1,5 +1,5 @@
 # 
##############################################################################
-# apps/examples/sotest/main/CMakeLists.txt
+# apps/examples/sotest/modprint/CMakeLists.txt
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -21,27 +21,5 @@
 # 
##############################################################################
 
 if(CONFIG_EXAMPLES_SOTEST)
-
-  # FIXME: fix all empty a after the kernel build is implemented
-  add_custom_command(
-    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    COMMAND
-      ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${CMAKE_CURRENT_BINARY_DIR}/empty
-      g_sot > ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c)
-
-  add_custom_target(
-    sotest_romfs
-    COMMAND genromfs -f sotest_romfs.img -d empty
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
-  add_custom_command(
-    OUTPUT sotest_romfs.c
-    COMMAND xxd -i sotest_romfs.img > sotest_romfs.c
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    DEPENDS sotest_romfs)
-
-  nuttx_add_application(
-    NAME sotest SRCS sotest_main.c ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c)
-
+  nuttx_add_application(NAME modprint SRCS modprint.c DYNLIB y)
 endif()
diff --git a/examples/sotest/main/CMakeLists.txt 
b/examples/sotest/sotest/CMakeLists.txt
similarity index 55%
copy from examples/sotest/main/CMakeLists.txt
copy to examples/sotest/sotest/CMakeLists.txt
index caca43d22..d4f30c1c5 100644
--- a/examples/sotest/main/CMakeLists.txt
+++ b/examples/sotest/sotest/CMakeLists.txt
@@ -1,5 +1,5 @@
 # 
##############################################################################
-# apps/examples/sotest/main/CMakeLists.txt
+# apps/examples/sotest/sotest/CMakeLists.txt
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -21,27 +21,5 @@
 # 
##############################################################################
 
 if(CONFIG_EXAMPLES_SOTEST)
-
-  # FIXME: fix all empty a after the kernel build is implemented
-  add_custom_command(
-    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    COMMAND
-      ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${CMAKE_CURRENT_BINARY_DIR}/empty
-      g_sot > ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c)
-
-  add_custom_target(
-    sotest_romfs
-    COMMAND genromfs -f sotest_romfs.img -d empty
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
-  add_custom_command(
-    OUTPUT sotest_romfs.c
-    COMMAND xxd -i sotest_romfs.img > sotest_romfs.c
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-    DEPENDS sotest_romfs)
-
-  nuttx_add_application(
-    NAME sotest SRCS sotest_main.c ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
-    ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c)
-
+  nuttx_add_application(NAME sotest SRCS sotest.c DYNLIB y)
 endif()

Reply via email to