Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configure: META.in template with no hardcoded version number #54

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ Makefile.config
/src/glob_lexer.ml
/ocamlbuild.byte
/ocamlbuild.native

# generated from META.in
META
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ OCamlbuild 0.9.0 is an experimental release designed to help testing
OCaml software in preparation for the 4.03 release -- the first one to
not include ocamlbuild.

- #44: When ocamlbuild discover a cycle in the dependencies, the
displayed problematic path is now refined to the actual cycle (François Bobot)
- MPR#6794, MPR#6809: pass package-specific include flags when building C files
(Jérémie Dimino, request by whitequark)
- OGPR#208: add "asm" tag to ocamlbuild to enable flag -S
Expand Down
3 changes: 2 additions & 1 deletion META → META.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#%% see META rule in Makefile
# Specification for the "ocamlbuild" library
requires = "unix"
version = "0.9.0"
version = "%%VERSION%%"
description = "ocamlbuild support library"
archive(byte) = "ocamlbuildlib.cma"
archive(native) = "ocamlbuildlib.cmxa"
71 changes: 63 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,28 @@ beforedepend:: src/glob_lexer.ml

# The config file

configure: Makefile.config src/ocamlbuild_config.ml

Makefile.config src/ocamlbuild_config.ml:
# we mark only the 'configure' rule PHONY,
# not individual CONF_FILES, as all OCamlbuild
# sources depend on ocamlbuild_config.ml,
# so it would rebuild from scratch each time.
#
# The reason for marking PHONY is to let the user
# explicitly re-configure; the --version answer
# depends on the state of the git repository, so
# it may change at any time.
.PHONY: configure

CONF_FILES=Makefile.config src/ocamlbuild_config.ml
configure:
$(MAKE) -f configure.make $(CONF_FILES)

$(CONF_FILES):
$(MAKE) -f configure.make $@

clean::
rm -f Makefile.config src/ocamlbuild_config.ml
rm -f $(CONF_FILES)

beforedepend:: src/ocamlbuild_config.ml
beforedepend:: Makefile.config

# Installation

Expand Down Expand Up @@ -229,14 +242,22 @@ endif
echo ']' >> ocamlbuild.install
echo >> ocamlbuild.install

install-lib-basics:
install-lib-basics: META
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The META should be created during compilation not during installation, since the installation can be done with sudo and it is inconvenient to create root file in the user directory.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can take this commit bobot/ocamlbuild@a575494 if you want.

mkdir -p $(INSTALL_LIBDIR)/ocamlbuild
$(CP) META src/signatures.mli $(INSTALL_LIBDIR)/ocamlbuild

install-lib-basics-opam:
install-lib-basics-opam: META
echo ' "META"' >> ocamlbuild.install
echo ' "src/signatures.mli" {"signatures.mli"}' >> ocamlbuild.install

# %%FOO%% are configuration variables (only %%VERSION%% currently),
# and #%% comments are removed before installation
META: META.in VERSION
@cat META.in \
| sed s/%%VERSION%%/$$(cat VERSION)/ META.in \
| grep -v "#%%.*" \
> META

install-lib-byte:
mkdir -p $(INSTALL_LIBDIR)/ocamlbuild
$(CP) $(INSTALL_LIB) $(INSTALL_LIBDIR)/ocamlbuild
Expand All @@ -261,7 +282,7 @@ else
install-lib: install-lib-basics install-lib-byte
endif

install-lib-findlib:
install-lib-findlib: META
ifeq ($(OCAML_NATIVE), true)
ocamlfind install ocamlbuild \
META src/signatures.mli $(INSTALL_LIB) $(INSTALL_LIB_OPT)
Expand Down Expand Up @@ -339,6 +360,40 @@ ifeq ($(CHECK_IF_PREINSTALLED), true)
fi
endif

check-release:
@echo "This Makefile rule checks that:"
@echo "- the VERSION and 'git describe' values are consistent"
@echo "- NEXT_RELEASE does not appear in the sources anymore"
@echo "For any more serious release checking, see howto/release.adoc."
@echo "(We only add output below when a check fails.)"
@echo
@$(MAKE) --silent check-release-VERSION-git-describe
@$(MAKE) --silent check-release-NEXT_RELEASE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need recursive make?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use recursive make when I want to force ordering. My understanding of make semantics is that targets given in a single call may be executed in any order in presence of -jN. Is this wrong?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use dependencies to enforce ordering. Or just use order-only-prerequisite (make manual 4.2):

   Occasionally, however, you have a situation where you want to impose a specific ordering
on the rules to be invoked without forcing the target to be updated if one of those rules is
executed. In that case, you want to define order-only prerequisites. Order-only prerequisites
can be specified by placing a pipe symbol (|) in the prerequisites list: any prerequisites to
the left of the pipe symbol are normal; any prerequisites to the right are order-only:
       targets : normal-prerequisites | order-only-prerequisites


check-release-VERSION-git-describe:
ifeq ($(shell echo $(shell cat VERSION)),\
$(shell git describe --tags --always --dirty))
@
else
@echo "Bad: VERSION ($(shell cat VERSION)) and"\
"'git describe --tags --always --dirty'"\
"($(shell git describe --tags --always --dirty))"\
"disagree."
endif


NEXT_RELEASE_EXCLUDE="(Makefile|howto)"
NEXT_RELEASE_FILES=$(shell git grep --files-with-matches "NEXT_RELEASE" \
| grep -v -E $(NEXT_RELEASE_EXCLUDE))
check-release-NEXT_RELEASE:
ifeq ($(strip $(NEXT_RELEASE_FILES)),)
@
else
@echo "The following occurrences of NEXT_RELEASE"\
"should probably be fixed:"
@git grep "NEXT_RELEASE" -- $(NEXT_RELEASE_FILES)
endif

# The generic rules

.SUFFIXES: .ml .mli .cmo .cmi .cmx
Expand Down
13 changes: 12 additions & 1 deletion configure.make
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ OCAMLBUILD_LIBDIR ?= \
# OCAMLBUILD_{PREFIX,BINDIR,LIBDIR}, which are the ones that should
# generally be used, as the shorted names {PREFIX,BINDIR,LIBDIR}.

# if run from a git development repository,
# prefer $(git describe --always --dirty)
# to the VERSION file. This trick comes from Daniel Bünzli.
VERSION ?= \
$(or $(shell git describe --tags --always --dirty 2>/dev/null),\
$(shell ocaml scripts/cat.ml VERSION))

ifeq ($(ARCH), none)
OCAML_NATIVE ?= false
else
Expand Down Expand Up @@ -76,6 +83,10 @@ Makefile.config:
echo "LIBDIR=$(OCAMLBUILD_LIBDIR)"; \
) > $@

# the configuration file depends on the git environment,
# so it should be rebuilt each time
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of rebuilding each time you can do that:

#force allows to always run the rules that depends on it
.PHONY: force

#.version_stamp remember the last version for knowing when rebuilding
.version_stamp: force
    @echo '$(VERSION)' | cmp -s - $@ || echo '$(VERSION)' > $@

And make src/ocamlbuild_config.ml depend on .version_stamp

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However since it is in configure.make it is not really important.

.PHONY: src/ocamlbuild_config.ml

src/ocamlbuild_config.ml:
(echo "(* This file was generated from ../configure.make *)"; \
echo ;\
Expand All @@ -87,5 +98,5 @@ src/ocamlbuild_config.ml:
echo 'let so = "$(SO)"'; \
echo 'let ext_dll = "$(EXT_DLL)"'; \
echo 'let exe = "$(EXE)"'; \
echo 'let version = "$(shell ocaml scripts/cat.ml VERSION)"'; \
echo 'let version = "$(VERSION)"'; \
) > $@
61 changes: 30 additions & 31 deletions howto/release.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,11 @@ release number, so any occurence of +NEXT_RELEASE+ in the development
repository should be replaced by this version number. There is at
least one such occurence in the 'Changes' file.

Furthermore, the version coded is hardcoded in some parts of the
codebase and needs to be updated:

- the 'VERSION' file contains the current version number, with no
ending newline

- the 'META' file contains the current version number to inform ocamlfind

You can use +git grep+ to look for all occurrences of +NEXT_RELEASE+
and a given version number, from the root of the repository:

----
git grep NEXT_RELEASE
git grep -F "0.9"
----
Furthermore, the version number is written in the 'VERSION' file (no
ending newline), and it is used to derive the version number at
installation time -- for example ocamlfind's 'META' file is generated
from the 'META.in' template. This 'VERSION' file should thus be
updated.

== Doing the release ==

Expand All @@ -118,29 +108,15 @@ central git repository.

Mark the current release day in the Changes file.


=== Performing the release through github ===

Github's interface allows to create a release tag and publish
a release. From the https://github.com/ocaml/ocamlbuild[github project
page] you can go to the
https://github.com/ocaml/ocamlbuild/releases[release tab] which lists
the current tags and has
a https://github.com/ocaml/ocamlbuild/releases/new[draft a new
release] button. Clicking this button (or the latter link in the
previous sentence) will let you pick a tag name, release title, and
description.
=== Create a git release tag ===

The tag name should be just the release version number. See +git
tag --list+ to see existing tags from a command-line. The release name
should be just +Release <version-number>+. The description should be
the Changes section corresponding to the release (release summary and
detailed list of entries).

==== Releasing from the command-line instead ====

If you prefer, you can also perform the same steps using the
command-line:
To create the tag, run

----
git tag <VERSION> -a
Expand All @@ -149,6 +125,29 @@ git tag <VERSION> -a
This command should start an editor to ask for a tag message. You can
use the <<change-summary,release change summary>> as the tag message.

As long as you do not <<push-release-tag,push the release tag
upstream>>, you can delete the tag if you find out you made a mistake
and some things still need to be changed before the release.

----
git tag --delete <VERSION>
----

=== Run +make check-release+ ===

The +check-release+ target automates what little part of the release
checking we could automate. It checks that 'VERSION' and the last git
tag agree, and that no dubious +NEXT_RELEASE+ occurrences persist.

The script that check for +NEXT_RELEASE+ is somewhat fragile, you may
need to whitelist new files by modifying the 'Makefile' rule.

[[push-release-tag]]
=== Publish the release upstream ===

You need the commit rights to the upstream repository to run this
command.

----
git push --tags origin
----
Expand Down