You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2022/01/03 16:12:23 UTC

[incubator-nuttx] branch master updated: Improve dependencies for `dirlinks`.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2366795  Improve dependencies for `dirlinks`.
2366795 is described below

commit 236679578630312a1ebe6d96c2745d19cfd5d706
Author: Alan Rosenthal <al...@google.com>
AuthorDate: Tue Dec 28 12:21:50 2021 -0500

    Improve dependencies for `dirlinks`.
    
    This PR updates the dependencies for `dirlinks` so they're all real files. This allows `dirlinks` rule to not have to be rerun every time.
    This PR also changes the name from `dirlinks` to `.dirlinks`, since a file named `.dirlinks` is created to denote that all symlinks have been created
    
    Changes:
    * tools/link.sh
      * link.sh now detects broken symlinks. Previously, it would return `0` if the symlink existed, but didn't point to anything.
    
    * tools/Makefile.unix
      * Added dependencies to symlinks as order-only prerequisites. See https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html
      * Removed `touch` from symlink recipes by specifying them as order only prerequisites.
      * Check Kconfig variables before adding directories as symlinks
      * Added rule for `$(TOPDIR)/arch/dummy/Kconfig`
      * Added rule for `$(ARCH_SRC)/board/board`
      * Added pattern rule (similar to `CONTEXTDIRS_DEPS`) for external folder dirlink dependencies
      * Use $(APPDIR) instead of $(CONFIG_APPS_DIR), since on line 64 $(APPDIR) is validated and `realpath` is called on the path
      * Added a rule `clean_dirlinks` to cleanup the symlinks in the correct order
    
    * .gitignore
      * Added ignore rule for `.dirlinks`
    
    Testing
    Step 1: configure nuttx:
    ```
    $ (cd tools && ./configure.sh -a ../incubator-nuttx-apps stm32f3discovery:nsh)
    ```
    part of the configure step ends up calling `.dirlinks`.
    
    Step 2: We can confirm that `.dirlinks` doesn't need to be run again by running with the question flag: `--question`
    ```
    $ make .dirlinks --question
    $ echo $?
    0
    ```
    
    Step 3: confirm `make` succeeds.
    ```
    make
    ```
---
 .gitignore          |   2 +
 tools/Makefile.unix | 168 +++++++++++++++++++++++++++++++++++++---------------
 tools/README.txt    |   2 +-
 tools/ci/cibuild.sh |   2 +-
 tools/link.sh       |   9 ++-
 5 files changed, 130 insertions(+), 53 deletions(-)

diff --git a/.gitignore b/.gitignore
index ad14bfa..638ff91 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,5 @@ uImage
 /external
 # $(TOPDIR)/Makefile.[unix|win]::$(CONTEXTDIRS_DEPS)
 .context
+# $(TOPDIR)/Makefile.[unix|win]::$(DIRLINKS_EXTERNAL_DIRS)
+.dirlinks
diff --git a/tools/Makefile.unix b/tools/Makefile.unix
index 77e78b6..a2413a5 100644
--- a/tools/Makefile.unix
+++ b/tools/Makefile.unix
@@ -45,6 +45,7 @@ else
 # Generate .version every time from GIT history
 
 .PHONY: $(TOPDIR)/.version
+
 endif
 
 # Process architecture specific directories
@@ -146,7 +147,7 @@ endif
 BIN = nuttx$(EXEEXT)
 
 all: $(BIN)
-.PHONY: dirlinks context clean_context config oldconfig menuconfig nconfig qconfig gconfig export subdir_clean clean subdir_distclean distclean apps_clean apps_distclean
+.PHONY: context clean_context config oldconfig menuconfig nconfig qconfig gconfig export subdir_clean clean subdir_distclean distclean apps_clean apps_distclean
 .PHONY: pass1 pass1dep
 .PHONY: pass2 pass2dep
 
@@ -246,7 +247,7 @@ tools/mkdeps$(HOSTEXEEXT):
 tools/cnvwindeps$(HOSTEXEEXT):
 	$(Q) $(MAKE) -C tools -f Makefile.host cnvwindeps$(HOSTEXEEXT)
 
-# dirlinks, and helpers
+# .dirlinks, and helpers
 #
 # Directories links.  Most of establishing the NuttX configuration involves
 # setting up symbolic links with 'generic' directory names to specific,
@@ -255,71 +256,147 @@ tools/cnvwindeps$(HOSTEXEEXT):
 # Link the arch/<arch-name>/include directory to include/arch
 
 include/arch:
-	@echo "LN: include/arch to $(ARCH_DIR)/include"
-	$(Q) $(DIRLINK) $(TOPDIR)/$(ARCH_DIR)/include include/arch
-	$(Q) touch $@
+	@echo "LN: $@ to $(ARCH_DIR)/include"
+	$(Q) $(DIRLINK) $(TOPDIR)/$(ARCH_DIR)/include $@
 
 # Link the boards/<arch>/<chip>/<board>/include directory to include/arch/board
 
-include/arch/board: include/arch
-	@echo "LN: include/arch/board to $(BOARD_DIR)/include"
-	$(Q) $(DIRLINK) $(BOARD_DIR)/include include/arch/board
-	$(Q) touch $@
+include/arch/board: | include/arch
+	@echo "LN: $@ to $(BOARD_DIR)/include"
+	$(Q) $(DIRLINK) $(BOARD_DIR)/include $@
 
-ifneq ($(BOARD_COMMON_DIR),)
 # Link the boards/<arch>/<chip>/common dir to arch/<arch-name>/src/board
 # Link the boards/<arch>/<chip>/<board>/src dir to arch/<arch-name>/src/board/board
 
-$(ARCH_SRC)/board:
-	@echo "LN: $(ARCH_SRC)/board to $(BOARD_COMMON_DIR)"
-	$(Q) $(DIRLINK) $(BOARD_COMMON_DIR) $(ARCH_SRC)/board
-	@echo "LN: $(ARCH_SRC)/board/board to $(BOARD_DIR)/src"
-	$(Q) $(DIRLINK) $(BOARD_DIR)/src $(ARCH_SRC)/board/board
-	$(Q) touch $@
+ifneq ($(BOARD_COMMON_DIR),)
+ARCH_SRC_BOARD_SYMLINK=$(BOARD_COMMON_DIR)
+ARCH_SRC_BOARD_BOARD_SYMLINK=$(BOARD_DIR)/src
 else
-# Link the boards/<arch>/<chip>/<board>/src dir to arch/<arch-name>/src/board
+ARCH_SRC_BOARD_SYMLINK=$(BOARD_DIR)/src
+endif
 
+ifneq ($(ARCH_SRC_BOARD_SYMLINK),)
 $(ARCH_SRC)/board:
-	@echo "LN: $(ARCH_SRC)/board to $(BOARD_DIR)/src"
-	$(Q) $(DIRLINK) $(BOARD_DIR)/src $(ARCH_SRC)/board
-	$(Q) touch $@
+	@echo "LN: $@ to $(ARCH_SRC_BOARD_SYMLINK)"
+	$(Q) $(DIRLINK) $(ARCH_SRC_BOARD_SYMLINK) $@
+endif
+
+ifneq ($(ARCH_SRC_BOARD_BOARD_SYMLINK),)
+$(ARCH_SRC)/board/board: | $(ARCH_SRC)/board
+	@echo "LN: $@ to $(ARCH_SRC_BOARD_BOARD_SYMLINK)"
+	$(Q) $(DIRLINK) $(ARCH_SRC_BOARD_BOARD_SYMLINK) $@
 endif
 
 # Link the boards/<arch>/<chip>/drivers dir to drivers/platform
 
 drivers/platform:
-	@echo "LN: $(TOPDIR)/drivers/platform to $(BOARD_DRIVERS_DIR)"
-	$(Q) $(DIRLINK) $(BOARD_DRIVERS_DIR) $(TOPDIR)/drivers/platform
-	$(Q) touch $@
+	@echo "LN: $@ to $(BOARD_DRIVERS_DIR)"
+	$(Q) $(DIRLINK) $(BOARD_DRIVERS_DIR) $@
 
 # Link arch/<arch-name>/src/<chip-name> to arch/<arch-name>/src/chip
 
-$(ARCH_SRC)/chip:
 ifeq ($(CONFIG_ARCH_CHIP_CUSTOM),y)
-	@echo "LN: $(ARCH_SRC)/chip to $(CHIP_DIR)"
-	$(Q) $(DIRLINK) $(CHIP_DIR) $(ARCH_SRC)/chip
+ARCH_SRC_CHIP_SYMLINK_DIR=$(CHIP_DIR)
 else ifneq ($(CONFIG_ARCH_CHIP),)
-	@echo "LN: $(ARCH_SRC)/chip to $(ARCH_SRC)/$(CONFIG_ARCH_CHIP)"
-	$(Q) $(DIRLINK) $(TOPDIR)/$(ARCH_SRC)/$(CONFIG_ARCH_CHIP) $(ARCH_SRC)/chip
+ARCH_SRC_CHIP_SYMLINK_DIR=$(TOPDIR)/$(ARCH_SRC)/$(CONFIG_ARCH_CHIP)
+endif
+
+ifneq ($(ARCH_SRC_CHIP_SYMLINK_DIR),)
+$(ARCH_SRC)/chip:
+	@echo "LN: $@ to $(ARCH_SRC_CHIP_SYMLINK_DIR)"
+	$(Q) $(DIRLINK) $(ARCH_SRC_CHIP_SYMLINK_DIR) $@
 endif
-	$(Q) cp -f $(CHIP_KCONFIG) $(TOPDIR)/arch/dummy/Kconfig
-	$(Q) touch $@
 
 # Link arch/<arch-name>/include/<chip-name> to include/arch/chip
 
-include/arch/chip: include/arch
 ifeq ($(CONFIG_ARCH_CHIP_CUSTOM),y)
-	@echo "LN: include/arch/chip to $(CHIP_DIR)/include"
-	$(Q) $(DIRLINK) $(CHIP_DIR)/include include/arch/chip
+INCLUDE_ARCH_CHIP_SYMLINK_DIR=$(CHIP_DIR)/include
 else ifneq ($(CONFIG_ARCH_CHIP),)
-	@echo "LN: include/arch/chip to $(ARCH_INC)/$(CONFIG_ARCH_CHIP)"
-	$(Q) $(DIRLINK) $(TOPDIR)/$(ARCH_INC)/$(CONFIG_ARCH_CHIP) include/arch/chip
+INCLUDE_ARCH_CHIP_SYMLINK_DIR=$(TOPDIR)/$(ARCH_INC)/$(CONFIG_ARCH_CHIP)
+endif
+
+ifneq ($(INCLUDE_ARCH_CHIP_SYMLINK_DIR),)
+include/arch/chip:
+	@echo "LN: $@ to $(INCLUDE_ARCH_CHIP_SYMLINK_DIR)"
+	$(DIRLINK) $(INCLUDE_ARCH_CHIP_SYMLINK_DIR) $@
+endif
+
+# Copy $(CHIP_KCONFIG) to arch/dummy/Kconfig
+
+arch/dummy/Kconfig:
+	@echo "CP: $@ to $(CHIP_KCONFIG)"
+	$(Q) cp -f $(CHIP_KCONFIG) $@
+
+DIRLINKS_SYMLINK = \
+  include/arch \
+  include/arch/board \
+  drivers/platform \
+
+DIRLINKS_FILE = \
+  arch/dummy/Kconfig \
+
+ifneq ($(INCLUDE_ARCH_CHIP_SYMLINK_DIR),)
+DIRLINKS_SYMLINK += include/arch/chip
+endif
+
+ifneq ($(ARCH_SRC_CHIP_SYMLINK_DIR),)
+DIRLINKS_SYMLINK += $(ARCH_SRC)/chip
+endif
+
+ifneq ($(ARCH_SRC_BOARD_SYMLINK),)
+DIRLINKS_SYMLINK += $(ARCH_SRC)/board
+endif
+
+ifneq ($(ARCH_SRC_BOARD_BOARD_SYMLINK),)
+DIRLINKS_SYMLINK += $(ARCH_SRC)/board/board
+endif
+
+DIRLINKS_EXTERNAL_DIRS = boards
+
+ifneq ($(APPDIR),)
+DIRLINKS_EXTERNAL_DIRS += $(APPDIR)
 endif
+
+# Generate a pattern to build $(DIRLINKS_EXTERNAL_DIRS)
+
+DIRLINKS_EXTERNAL_DEP = $(patsubst %,%/.dirlinks,$(DIRLINKS_EXTERNAL_DIRS))
+DIRLINKS_FILE += $(DIRLINKS_EXTERNAL_DEP)
+
+.dirlinks: $(DIRLINKS_FILE) | $(DIRLINKS_SYMLINK)
+	touch $@
+
+# Pattern rule for $(DIRLINKS_EXTERNAL_DEP)
+
+%/.dirlinks:
+	$(Q) $(MAKE) -C $(patsubst %/.dirlinks,%,$@) dirlinks
 	$(Q) touch $@
 
-dirlinks: include/arch include/arch/board include/arch/chip $(ARCH_SRC)/board $(ARCH_SRC)/chip drivers/platform
-	$(Q) $(MAKE) -C boards dirlinks
-	$(Q) $(MAKE) -C $(CONFIG_APPS_DIR) dirlinks
+# clean_dirlinks
+#
+# This is part of the distclean target. It removes all symbolic links created by the dirlink target.
+
+# The symlink subfolders need to be removed before the parent symlinks
+
+.PHONY: clean_dirlinks
+clean_dirlinks:
+	$(Q) $(call DELFILE, $(DIRLINKS_FILE))
+	$(Q) $(call DELFILE, .dirlinks)
+	$(Q) $(DIRUNLINK) drivers/platform
+ifneq ($(INCLUDE_ARCH_CHIP_SYMLINK_DIR),)
+	$(Q) $(DIRUNLINK) include/arch/chip
+endif
+	$(Q) $(DIRUNLINK) include/arch/board
+	$(Q) $(DIRUNLINK) include/arch
+ifneq ($(ARCH_SRC_BOARD_BOARD_SYMLINK),)
+	$(Q) $(DIRUNLINK) $(ARCH_SRC)/board/board
+endif
+ifneq ($(ARCH_SRC_BOARD_SYMLINK),)
+	$(Q) $(DIRUNLINK) $(ARCH_SRC)/board
+endif
+ifneq ($(ARCH_SRC_CHIP_SYMLINK_DIR),)
+	$(Q) $(DIRUNLINK) $(ARCH_SRC)/chip
+endif
+
 
 # context
 #
@@ -332,14 +409,14 @@ dirlinks: include/arch include/arch/board include/arch/chip $(ARCH_SRC)/board $(
 
 CONTEXTDIRS_DEPS = $(patsubst %,%/.context,$(CONTEXTDIRS))
 
-context: include/nuttx/config.h include/nuttx/version.h dirlinks $(CONTEXTDIRS_DEPS) | staging
+context: include/nuttx/config.h include/nuttx/version.h .dirlinks $(CONTEXTDIRS_DEPS) | staging
 
 staging:
 	$(Q) mkdir -p $@
 
 # Pattern rule for $(CONTEXTDIRS_DEPS)
 
-%.context: include/nuttx/config.h dirlinks
+%.context: include/nuttx/config.h .dirlinks
 	$(Q) $(MAKE) -C $(patsubst %.context,%,$@) TOPDIR="$(TOPDIR)" context
 	$(Q) touch $@
 
@@ -364,7 +441,7 @@ endif
 # This is part of the distclean target.  It removes all of the header files
 # and symbolic links created by the context target.
 
-clean_context:
+clean_context: clean_dirlinks
 	$(Q) for dir in $(CCLEANDIRS) ; do \
 		if [ -e $$dir/Makefile ]; then \
 			$(MAKE) -C $$dir clean_context ; \
@@ -378,13 +455,6 @@ clean_context:
 	$(call DELFILE, include/setjmp.h)
 	$(call DELFILE, arch/dummy/Kconfig)
 	$(call DELFILE, $(CONTEXTDIRS_DEPS))
-	$(Q) $(DIRUNLINK) include/arch/board
-	$(Q) $(DIRUNLINK) include/arch/chip
-	$(Q) $(DIRUNLINK) include/arch
-	$(Q) $(DIRUNLINK) $(ARCH_SRC)/board/board
-	$(Q) $(DIRUNLINK) $(ARCH_SRC)/board
-	$(Q) $(DIRUNLINK) $(ARCH_SRC)/chip
-	$(Q) $(DIRUNLINK) $(TOPDIR)/drivers/platform
 
 # Archive targets.  The target build sequence will first create a series of
 # libraries, one per configured source file directory.  The final NuttX
@@ -648,7 +718,7 @@ endif
 # apps_distclean: Perform the distclean operation only in the user application
 #                 directory.
 
-apps_preconfig: dirlinks
+apps_preconfig: .dirlinks
 ifneq ($(APPDIR),)
 	$(Q) $(MAKE) -C $(APPDIR) preconfig
 endif
diff --git a/tools/README.txt b/tools/README.txt
index bc2ee62..4e78bf8 100644
--- a/tools/README.txt
+++ b/tools/README.txt
@@ -154,7 +154,7 @@ kconfig2html.c
 
   or more quickly with:
 
-    make dirlinks
+    make .dirlinks
 
 Libraries.mk, FlatLibs.mk, ProtectedLibs.mk, and KernelLib.mk
 -------------------------------------------------------------
diff --git a/tools/ci/cibuild.sh b/tools/ci/cibuild.sh
index 17f73f8..8f441e7 100755
--- a/tools/ci/cibuild.sh
+++ b/tools/ci/cibuild.sh
@@ -335,7 +335,7 @@ function binutils {
       Darwin)
         brew install binutils
         # It is possible we cached prebuilt but did brew install so recreate
-        # simlink if it exists
+        # symlink if it exists
         rm -f "${prebuilt}"/bintools/bin/objcopy
         ln -s /usr/local/opt/binutils/bin/objcopy "${prebuilt}"/bintools/bin/objcopy
         ;;
diff --git a/tools/link.sh b/tools/link.sh
index f7e8d5f..2027b3a 100755
--- a/tools/link.sh
+++ b/tools/link.sh
@@ -82,15 +82,20 @@ ln -s "${src}" "${dest}" || \
 
 # Verify that the link was created
 
-if [ ! -h ${dest} ]; then
+if [ -e ${dest} ] && [ -h ${desg} ]; then
+  # The file exists and is a symlink (i.e. the symlink isn't broken)
+
+  exit 0
+else
   # The MSYS 'ln' command actually does a directory copy
 
   if [ -d ${dest} ]; then
     # Create the .fakelnk for unlink.sh
 
     touch ${dest}/.fakelnk
+    exit 0
   else
-    echo "Error:  link at ${dest} not created."
+    echo "Error: link at ${dest} not created."
     exit 1
   fi
 fi