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 <gargaviral99@gmail.com>
This commit is contained in:
aviralgarg05 2026-07-11 21:57:50 +05:30 committed by Xiang Xiao
parent 3ecd036f8f
commit f2ceac78db
8 changed files with 730 additions and 32 deletions

View file

@ -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

View file

@ -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)
# 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})
# 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()
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)
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})
nuttx_add_application(
NAME sotest SRCS sotest_main.c ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c
${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c)
set_source_files_properties(${SOTEST_SYMTAB} PROPERTIES GENERATED TRUE)
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()
add_custom_target(sotest_artifacts DEPENDS ${SOTEST_GENERATED_OUTPUTS})
nuttx_add_application(NAME sotest SRCS ${SOTEST_SRCS} DEPENDS
sotest_artifacts)
endif()

View file

@ -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))
$(ROMFSIMG):
$(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): $(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

View file

@ -0,0 +1,26 @@
# ##############################################################################
# apps/examples/sotest/main/host/CMakeLists.txt
#
# 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.
#
# ##############################################################################
cmake_minimum_required(VERSION 3.16)
project(sotest_fixture_host LANGUAGES C)
add_executable(mk_pkg_fixture_shared ../mk_pkg_fixture_shared.c)

View file

@ -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;
}

View file

@ -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;

View file

@ -0,0 +1,25 @@
# ##############################################################################
# apps/examples/sotest/modprint/CMakeLists.txt
#
# 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.
#
# ##############################################################################
if(CONFIG_EXAMPLES_SOTEST)
nuttx_add_application(NAME modprint SRCS modprint.c DYNLIB y)
endif()

View file

@ -0,0 +1,25 @@
# ##############################################################################
# apps/examples/sotest/sotest/CMakeLists.txt
#
# 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.
#
# ##############################################################################
if(CONFIG_EXAMPLES_SOTEST)
nuttx_add_application(NAME sotest SRCS sotest.c DYNLIB y)
endif()