Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -455,27 +455,44 @@ function(dmod_create_module moduleName version moduleType)
)

if(TODMM)
add_custom_command(
TARGET ${moduleName} POST_BUILD
# todmm <folder> <base_url> --zip -o <output>
# For a local manifest, base_url is the local packages directory path
COMMAND ${TODMM} "${DMOD_PACKAGES_DIR}" "${DMOD_PACKAGES_DIR}" --zip -o "${DMOD_LOCAL_MANIFEST_PATH}"
COMMENT "Generating local manifest for packages: ${DMOD_LOCAL_MANIFEST_PATH}"
)
# Create a shared target (once per project) that regenerates the local
# manifest from ALL package zips after every module has been built.
# Using a dedicated target (rather than per-module POST_BUILD) guarantees
# that todmm runs only after ALL modules have created their zip archives,
# so the manifest is always complete when local .dmd files are generated.
if(NOT TARGET dmod_generate_manifest)
add_custom_target(dmod_generate_manifest ALL)
add_custom_command(
TARGET dmod_generate_manifest POST_BUILD
# todmm <folder> <base_url> --zip -o <output>
# For a local manifest, base_url is the local packages directory path
COMMAND ${TODMM} "${DMOD_PACKAGES_DIR}" "${DMOD_PACKAGES_DIR}" --zip -o "${DMOD_LOCAL_MANIFEST_PATH}"
COMMENT "Generating local manifest from all packages: ${DMOD_LOCAL_MANIFEST_PATH}"
)
endif()

# This module's zip must exist before the manifest is generated
add_dependencies(dmod_generate_manifest ${moduleName})

# Generate <module_name>-local.dmd using todmd with the local manifest
# Generate <module_name>-local.dmd using todmd AFTER the complete manifest
# is ready (i.e., after all modules' zips have been collected by todmm).
if(TODMD)
set(LOCAL_DMD_OUTPUT "${DMOD_DMF_DIR}/${moduleName}-local.dmd")

# A per-module ALL target that runs todmd once the manifest is complete
add_custom_target(${moduleName}_local_dmd ALL)
add_dependencies(${moduleName}_local_dmd dmod_generate_manifest)

get_target_property(VERSION_REQS_FILE ${moduleName} DMOD_VERSION_REQUIREMENTS_FILE)
if(VERSION_REQS_FILE AND EXISTS "${VERSION_REQS_FILE}")
add_custom_command(
TARGET ${moduleName} POST_BUILD
TARGET ${moduleName}_local_dmd POST_BUILD
COMMAND ${TODMD} ${DMF_OUTPUT} ${DMD_OUTPUT} -r ${VERSION_REQS_FILE} --local-manifest "${DMOD_LOCAL_MANIFEST_PATH}"
COMMENT "Generating local dependencies file: ${LOCAL_DMD_OUTPUT}"
)
else()
add_custom_command(
TARGET ${moduleName} POST_BUILD
TARGET ${moduleName}_local_dmd POST_BUILD
COMMAND ${TODMD} ${DMF_OUTPUT} ${DMD_OUTPUT} --local-manifest "${DMOD_LOCAL_MANIFEST_PATH}"
COMMENT "Generating local dependencies file: ${LOCAL_DMD_OUTPUT}"
)
Expand Down
18 changes: 17 additions & 1 deletion tests/integration/test_todmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ EOF
fi

echo ""
echo "Test 11: Verify local .dmd uses \$from for locally available deps"
echo "Test 11: Verify local .dmd uses \$from for locally available deps and lists non-local deps without \$from"

if [ -n "$DMF_FILE" ] && [ -f "$DMF_FILE" ]; then
# Get the list of dependencies from the regular .dmd
Expand All @@ -271,6 +271,22 @@ EOF
echo "✗ Expected \$from directive for ${FIRST_DEP} in local .dmd"
exit 1
fi

# Non-local deps (all except FIRST_DEP) must appear WITHOUT $from in the local .dmd
OTHER_DEPS=$(echo "$DEPS" | tail -n +2)
for dep in $OTHER_DEPS; do
if ! grep -v '^#' test_local_dep-local.dmd | grep -q "^${dep}"; then
echo "✗ Non-local dependency '${dep}' is missing from local .dmd"
exit 1
fi
if grep -v '^#' test_local_dep-local.dmd | grep "^${dep}" | grep -q "\$from"; then
echo "✗ Non-local dependency '${dep}' should not have \$from in local .dmd"
exit 1
fi
done
if [ -n "$OTHER_DEPS" ]; then
echo "✓ Non-local dependencies appear without \$from in local .dmd"
fi
else
echo "✗ Local .dmd file test_local_dep-local.dmd was not created"
exit 1
Expand Down
15 changes: 9 additions & 6 deletions tools/system/todmd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ void PrintHelp( const char* AppName )
printf(" --from <mod>=<manifest> Per-module manifest: adds inline $from for the named module\n");
printf(" Option can be repeated to set manifests for multiple modules\n");
printf(" --local-manifest <manifest> Local manifest (.dmm) file; generates a companion\n");
printf(" <module>-local.dmd where dependencies present in the manifest\n");
printf(" get an inline $from <manifest> directive\n");
printf(" <module>-local.dmd listing only dependencies present in\n");
printf(" the manifest, each with an inline $from <manifest> directive\n");
printf("\nArguments:\n");
printf(" path/to/file.dmf Path to the DMF module file\n");
printf(" [output.dmd] (optional) Output .dmd file path (default: module_name.dmd)\n");
Expand All @@ -247,9 +247,10 @@ void PrintHelp( const char* AppName )
printf(" only for that specific module using the $from syntax.\n");
printf("\n");
printf(" If --local-manifest is provided, a companion <module>-local.dmd file is\n");
printf(" generated alongside the regular .dmd. In this file, dependencies that are\n");
printf(" present in the local manifest receive an inline $from <manifest> directive\n");
printf(" so they can be resolved from the local build.\n");
printf(" generated alongside the regular .dmd. All non-system dependencies are listed:\n");
printf(" those present in the local manifest get an inline $from <manifest> directive\n");
printf(" so they are resolved from the local build; all other dependencies are listed\n");
printf(" without $from so they are fetched from the default remote repository.\n");
printf("\nExamples:\n");
printf(" %s myapp.dmf # Creates myapp.dmd\n", AppName);
printf(" %s myapp.dmf dependencies.dmd # Creates dependencies.dmd\n", AppName);
Expand Down Expand Up @@ -676,7 +677,9 @@ int main( int argc, char *argv[] )
}
}

// Use local manifest as $from source if this module is available locally
// Use local manifest as $from source if this module is available locally;
// non-local modules are still listed (without $from) so they are fetched
// from the default remote repository.
bool isLocal = IsModuleInLocalManifest( localManifestModules, localManifestModuleCount, reqModule->Name );

if( versionToUse != NULL )
Expand Down
Loading