Skip to content

Commit

Permalink
Compute STDLIB_MODULES with a C auxiliary
Browse files Browse the repository at this point in the history
Eliminates the dependency on many invocations of `tr` and `cut` to a
single invocation of a C auxiliary.

On Windows, the C auxiliary is considerably faster than the large number
of calls to tr and cut which were necessary in stdlib/StdlibModules.
  • Loading branch information
dra27 committed Jul 5, 2021
1 parent 88676f6 commit 1c7e469
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 25 deletions.
10 changes: 5 additions & 5 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,11 @@ OCaml 4.13.0
(Gabriel Scherer, review by Nicolás Ojeda Bär, Alain Frisch, Xavier Leroy,
Daniel Bünzli and Stephen Dolan)

* #10169, #10270, #10301: Use capitalized module names in the Standard Library
prefixing scheme to match Dune, e.g. Stdlib__String instead of Stdlib__string.
This is a breaking change only to code which attempted to use the internal
names before. The Standard Library generated by the Dune rules is now
equivalent to the main build (the Dune rules still do not generate a
* #10169, #10270, #10301, #10451: Use capitalized module names in the Standard
Library prefixing scheme to match Dune, e.g. Stdlib__String instead of
Stdlib__string. This is a breaking change only to code which attempted to use
the internal names before. The Standard Library generated by the Dune rules is
now equivalent to the main build (the Dune rules still do not generate a
distributable compiler).
(David Allsopp and Mark Shinwell, review by Gabriel Scherer)

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,9 @@ partialclean::

# The runtime system for the bytecode compiler

$(SAK):
$(MAKE) -C runtime sak$(EXE)

.PHONY: runtime
runtime: stdlib/libcamlrun.$(A)

Expand Down
12 changes: 12 additions & 0 deletions Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,15 @@ OCAMLYACCFLAGS ?=

%.ml %.mli: %.mly
$(OCAMLYACC) $(OCAMLYACCFLAGS) $<

SAK = $(ROOTDIR)/runtime/sak$(EXE)

# stdlib/StdlibModules cannot be include'd unless $(SAK) has been built. These
# two rules add that dependency. They have to be pattern rules since
# Makefile.common is included before default targets.
$(ROOTDIR)/%/sak$(EXE):
$(MAKE) -C $(ROOTDIR)/$* sak$(EXE)

ifneq "$(REQUIRES_CONFIGURATION)" ""
$(ROOTDIR)/%/StdlibModules: $(SAK) ;
endif
2 changes: 1 addition & 1 deletion api_docgen/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
ROOTDIR = ..
DOCGEN= $(ROOTDIR)/api_docgen

-include $(ROOTDIR)/stdlib/StdlibModules
include $(ROOTDIR)/Makefile.common
include $(ROOTDIR)/stdlib/StdlibModules
include $(ROOTDIR)/Makefile.best_binaries
include $(DOCGEN)/Makefile.docfiles

Expand Down
2 changes: 1 addition & 1 deletion manual/tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ROOTDIR = ../..
include $(ROOTDIR)/stdlib/StdlibModules
include $(ROOTDIR)/api_docgen/Makefile.docfiles
include $(ROOTDIR)/Makefile.common
include $(ROOTDIR)/stdlib/StdlibModules
include $(ROOTDIR)/Makefile.best_binaries
STDLIBFLAGS = -nostdlib -I $(ROOTDIR)/stdlib
OCAMLC ?= $(BEST_OCAMLC) $(STDLIBFLAGS)
Expand Down
3 changes: 2 additions & 1 deletion runtime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ endif
# Build, install and clean targets

.PHONY: all
all: $(BYTECODE_STATIC_LIBRARIES) $(BYTECODE_SHARED_LIBRARIES) $(PROGRAMS)
all: $(BYTECODE_STATIC_LIBRARIES) $(BYTECODE_SHARED_LIBRARIES) $(PROGRAMS) \
sak$(EXE)

.PHONY: allopt
ifneq "$(NATIVE_COMPILER)" "false"
Expand Down
45 changes: 45 additions & 0 deletions runtime/sak.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#ifdef _WIN32
#define strncmp_os wcsncmp
#define toupper_os towupper
#define printf_os wprintf
#else
#define strncmp_os strncmp
#define toupper_os toupper
#define printf_os printf
#endif

/* Operations
- encode-C-literal. Used for the OCAML_STDLIB_DIR macro in
Expand All @@ -36,6 +47,12 @@
On Windows, `sak encode-C-literal "C:\OCaml🐫\lib"` returns
`L"C:\\OCaml\xd83d\xdc2b\\lib"`
- add-stdlib-prefix. Used in stdlib/StdlibModules to convert the list of
basenames given in STDLIB_MODULE_BASENAMES to the actual file basenames
in STDLIB_MODULES.
For example, `sak add-stdlib-prefix stdlib camlinternalAtomic Sys` returns
` stdlib camlinternalAtomic stdlib__Sys`
*/

void usage(void)
Expand All @@ -45,6 +62,7 @@ void usage(void)
"Usage: sak command\n"
"Commands:\n"
" * encode-C-literal path - encodes path as a C string literal\n"
" * add-stdlib-prefix name1 ... - prefix standard library module names\n"
);
}

Expand Down Expand Up @@ -86,6 +104,31 @@ void encode_C_literal(char_os *path)
putchar('"');
}

/* Print the given array of module names to stdout. "stdlib" and names beginning
"camlinternal" are printed unaltered. All other names are prefixed "stdlib__"
with the original name capitalised (i.e. "foo" prints "stdlib__Foo"). */
void add_stdlib_prefix(int count, char_os **names)
{
int i;
char_os *name;

for (i = 0; i < count; i++) {
name = *names++;

/* "stdlib" and camlinternal* do not get changed. All other names get
capitalised and prefixed "stdlib__". */
if (strcmp_os(T("stdlib"), name) == 0
|| strncmp_os(T("camlinternal"), name, 12) == 0) {
printf_os(T(" %s"), name);
} else {
/* name is a null-terminated string, so an empty string simply has the
null-terminator "capitalised". */
*name = toupper_os(*name);
printf_os(T(" stdlib__%s"), name);
}
}
}

#ifdef _WIN32
int wmain(int argc, wchar_t **argv)
#else
Expand All @@ -94,6 +137,8 @@ int main(int argc, char **argv)
{
if (argc == 3 && !strcmp_os(argv[1], T("encode-C-literal"))) {
encode_C_literal(argv[2]);
} else if (argc > 1 && !strcmp_os(argv[1], T("add-stdlib-prefix"))) {
add_stdlib_prefix(argc - 2, &argv[2]);
} else {
usage();
return 1;
Expand Down
26 changes: 9 additions & 17 deletions stdlib/StdlibModules
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#* *
#**************************************************************************

# This file must be self-contained.
# This file should be included after Makefile.common

# This file lists all standard library modules. It is used by:
# 1. stdlib/Makefile when building stdlib.cma
Expand All @@ -33,7 +33,7 @@

# Basenames of the source files for the standard library (i.e. unprefixed and
# with lowercase first letters). These must be listed in dependency order.
STDLIB_MODULE_BASENAMES=\
STDLIB_MODULE_BASENAMES = \
camlinternalFormatBasics camlinternalAtomic \
stdlib pervasives seq option either result bool char uchar \
sys list int bytes string unit marshal obj array float int32 int64 nativeint \
Expand All @@ -44,20 +44,12 @@ STDLIB_MODULE_BASENAMES=\
filename complex arrayLabels listLabels bytesLabels stringLabels moreLabels \
stdLabels bigarray in_channel out_channel

STDLIB_PREFIXED_MODULES=\
STDLIB_PREFIXED_MODULES = \
$(filter-out stdlib camlinternal%, $(STDLIB_MODULE_BASENAMES))

define add_stdlib_prefix_first
$(shell echo $1 | cut -c1 | tr '[:lower:]' '[:upper:]')
endef

# add stdlib__ as prefix to a module except for internal modules
# and the stdlib module itself
define add_stdlib_prefix
$(or $(filter-out $(STDLIB_PREFIXED_MODULES), $1), \
stdlib__$(call add_stdlib_prefix_first,$1)$(shell echo $1 | cut -c2-))
endef

STDLIB_MODULES:=\
$(foreach module, $(STDLIB_MODULE_BASENAMES), \
$(call add_stdlib_prefix,$(module)))
# The pattern FOO = $(eval FOO := $$(shell <cmd>)$(FOO) ensures that <cmd> is
# executed either once or not at all, giving us GNU make's equivalent of a
# string lazy_t.
STDLIB_MODULES = \
$(eval STDLIB_MODULES := $$(shell \
$(SAK) add-stdlib-prefix $(STDLIB_MODULE_BASENAMES)))$(STDLIB_MODULES)

0 comments on commit 1c7e469

Please sign in to comment.