Skip to content

libraries: track submodule fetch via its .git entry, not a stamp file#4439

Open
d-torrance wants to merge 1 commit into
Macaulay2:developmentfrom
d-torrance:fetch-submodule
Open

libraries: track submodule fetch via its .git entry, not a stamp file#4439
d-torrance wants to merge 1 commit into
Macaulay2:developmentfrom
d-torrance:fetch-submodule

Conversation

@d-torrance

Copy link
Copy Markdown
Member

This should fix an issue identified by @joel-dodge in Zulip. Let's say we want to use the autotools build to to build some dependency for which we use a submodule instead of a tarball (say, memtailor). First time around, no problem.

Now let's say we're sick of submodule changes showing up in our git status so we decide to deinitalize them. But that doesn't remove the .submodule-updated stamp file that the autotools build writes when it updates a submodule. So the next time we go to build that dependency, the build fails because we think we don't need to update the submodule again.

Before

Here's an example of the failing behavior with memtailor:

profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ make -C libraries/memtailor/ fetch
make: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make update-submodule
make[1]: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
if git rev-parse 2> /dev/null;                          \
then                                                    \
	git submodule update --init                   \
		/home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules/memtailor; \
else                                                    \
	cd /home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules;                 \
	rm -rf memtailor;                              \
	git clone https://github.com/Macaulay2/memtailor memtailor;                  \
	cd memtailor;                                  \
	git checkout v1.4;                      \
fi
Submodule 'M2/submodules/memtailor' (https://github.com/Macaulay2/memtailor) registered for path '../../../../submodules/memtailor'
Submodule path '../../../../submodules/memtailor': checked out 'a74747f70d5d4f2c79c9707b64c5086eb8c051b9'
make[1]: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
touch .submodule-updated
make: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ git submodule deinit ../../submodules/memtailor/
Cleared directory '../../submodules/memtailor'
Submodule 'M2/submodules/memtailor' (https://github.com/Macaulay2/memtailor) unregistered for path '../../submodules/memtailor'
profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ make -C libraries/memtailor/ fetch
make: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make: Nothing to be done for 'fetch'.
make: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ make -C libraries/memtailor/
make: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
if [ -d build ] ; then mv build build-old ; fi
mkdir build
cd build && /usr/bin/install -c -d memtailor-1.4 && make -C .. fetch  && cp -r /home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules/memtailor/* memtailor-1.4
make[1]: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make[1]: Nothing to be done for 'fetch'.
make[1]: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
cp: cannot stat '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules/memtailor/*': No such file or directory
make: *** [../Makefile.library:224: .patched-1.4] Error 1
make: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'

After

Now instead of using the .submodule-updated stamp file, we just check for the existence of the .git file in the submodule. It gets removed when we deinitialize, so we know it's time to initialize again.

profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ make -C libraries/memtailor fetch
make: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make update-submodule
make[1]: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
if git rev-parse 2> /dev/null;                          \
then                                                    \
	git submodule update --init                   \
		/home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules/memtailor; \
else                                                    \
	cd /home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules;                 \
	rm -rf memtailor;                              \
	git clone https://github.com/Macaulay2/memtailor memtailor;                  \
	cd memtailor;                                  \
	git checkout v1.4;                      \
fi
Submodule 'M2/submodules/memtailor' (https://github.com/Macaulay2/memtailor) registered for path '../../../../submodules/memtailor'
Submodule path '../../../../submodules/memtailor': checked out 'a74747f70d5d4f2c79c9707b64c5086eb8c051b9'
make[1]: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ git submodule deinit ../../submodules/memtailor/
Cleared directory '../../submodules/memtailor'
Submodule 'M2/submodules/memtailor' (https://github.com/Macaulay2/memtailor) unregistered for path '../../submodules/memtailor'
profzoom@peg-amy:~/src/macaulay2/M2/M2/BUILD/build$ make -C libraries/memtailor
make: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
if [ -d build ] ; then mv build build-old ; fi
mkdir build
cd build && /usr/bin/install -c -d memtailor-1.4 && make -C .. fetch  && cp -r /home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules/memtailor/* memtailor-1.4
make[1]: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make update-submodule
make[2]: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
if git rev-parse 2> /dev/null;                          \
then                                                    \
	git submodule update --init                   \
		/home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules/memtailor; \
else                                                    \
	cd /home/profzoom/src/macaulay2/M2/M2/BUILD/build/../../submodules;                 \
	rm -rf memtailor;                              \
	git clone https://github.com/Macaulay2/memtailor memtailor;                  \
	cd memtailor;                                  \
	git checkout v1.4;                      \
fi
Submodule 'M2/submodules/memtailor' (https://github.com/Macaulay2/memtailor) registered for path '../../../../submodules/memtailor'
Submodule path '../../../../submodules/memtailor': checked out 'a74747f70d5d4f2c79c9707b64c5086eb8c051b9'
make[2]: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
make[1]: Leaving directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor'
cd build && for i in  ; do patch --batch -p0 < $i ; done
touch .patched-1.4
+ set +x
make: Entering directory '/home/profzoom/src/macaulay2/M2/M2/BUILD/build/libraries/memtailor/build/memtailor-1.4'
+ autoreconf -i
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build/autotools'.
libtoolize: copying file 'build/autotools/ltmain.sh'
...

AI Disclosure

Claude wrote the code with significant hand-holding.

Here's its commit message:

If a SUBMODULE = true library was fetched and then the submodule was
deinitialized (e.g. via git submodule deinit), the old
.submodule-updated stamp file would remain, causing the build to fail
since the submodule directory is empty.

Instead of a separate stamp file, make fetch depend directly on
submodules/$(LIBNAME)/.git, which is created by
update-submodule and removed by deinit. This makes the dependency
self-correcting: if the submodule is deinitialized (or never
initialized), make reruns update-submodule; if it's already present,
fetch is a no-op.

If a SUBMODULE = true library was fetched and then the submodule was
deinitialized (e.g. via git submodule deinit), the old
.submodule-updated stamp file would remain, causing the build to fail
since the submodule directory is empty.

Instead of a separate stamp file, make fetch depend directly on
submodules/$(LIBNAME)/.git, which is created by
update-submodule and removed by deinit. This makes the dependency
self-correcting: if the submodule is deinitialized (or never
initialized), make reruns update-submodule; if it's already present,
fetch is a no-op.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@d-torrance d-torrance added build issue platform specific issues involving compiling M2, generating examples, or running tests dependencies Pull requests that update a dependency file labels Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build issue platform specific issues involving compiling M2, generating examples, or running tests dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant