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

Reply via email to