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 5e0153b commit 7982f26
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 28 deletions.
10 changes: 5 additions & 5 deletions Changes
Expand Up @@ -309,11 +309,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
9 changes: 6 additions & 3 deletions Makefile
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 Expand Up @@ -822,16 +825,16 @@ clean::
# The standard library

.PHONY: library
library: ocamlc
library: ocamlc | $(SAK)
$(MAKE) -C stdlib $(BOOT_FLEXLINK_CMD) all

.PHONY: library-cross
library-cross:
library-cross: | $(SAK)
$(MAKE) -C stdlib \
$(BOOT_FLEXLINK_CMD) OCAMLRUN=../runtime/ocamlrun$(EXE) all

.PHONY: libraryopt
libraryopt:
libraryopt: | $(SAK)
$(MAKE) -C stdlib $(BOOT_FLEXLINK_CMD) allopt

partialclean::
Expand Down
2 changes: 2 additions & 0 deletions Makefile.common
Expand Up @@ -160,3 +160,5 @@ OCAMLYACCFLAGS ?=

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

SAK = $(ROOTDIR)/runtime/sak$(EXE)
2 changes: 1 addition & 1 deletion api_docgen/Makefile.common
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
@@ -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
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
44 changes: 44 additions & 0 deletions runtime/sak.c
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
- translate. Used for the OCAML_STDLIB_DIR macro in runtime/build_config.h
Expand All @@ -36,6 +47,11 @@
On Windows, `sak translate "C:\OCaml🐫\lib"` returns
`L"C:\\OCaml\xd83d\xdc2b\\lib"`
- 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 prefix stdlib camlinternalAtomic Sys` returns
` stdlib camlinternalAtomic stdlib__Sys`
*/

void usage(void)
Expand All @@ -45,6 +61,7 @@ void usage(void)
"Usage: sak command\n"
"Commands:\n"
" * translate path - converts path to a C string constant\n"
" * prefix name1 name2 ... - prefix standard library module names\n"
);
}

Expand Down Expand Up @@ -86,6 +103,31 @@ void emit_c_string(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 prefix_stdlib_modules(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 +136,8 @@ int main(int argc, char **argv)
{
if (argc == 3 && !strcmp_os(argv[1], T("translate"))) {
emit_c_string(argv[2]);
} else if (argc > 1 && !strcmp_os(argv[1], T("prefix"))) {
prefix_stdlib_modules(argc - 2, &argv[2]);
} else {
usage();
return 1;
Expand Down
26 changes: 9 additions & 17 deletions stdlib/StdlibModules
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

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) prefix $(STDLIB_MODULE_BASENAMES)))$(STDLIB_MODULES)

0 comments on commit 7982f26

Please sign in to comment.