Description
Problem
The default libc++ modulemap does not seem to compile and see definitions in stdint.h
when inttypes.h
refers to a copy or symlink of stdint.h
in a subdirectory (say, sys
).
I can make a guess and say that it is possible that inttypes.h
is incorrect to refer to sys/stdint.h
because that (might?) be "outside" the module if one is not defined, but I don't know enough about modules to confidently say whether this is contra to how modules work, but in trying to reason about this, I can't seem to construct an argument to say why this affirmatively shouldn't work either. Therefore, before reporting this as a platform bug, I thought I would raise this problem here first.
Note that this is only a problem when -fmodules
is enabled.
Workarounds
Also see the minimal test case, which includes some workarounds. Additional workarounds include
Adjusting the modulemap
diff --git a/c++/v1/module.modulemap b/c++/v1/module.modulemap
index d26733f..03d246d 100644
--- a/c++/v1/module.modulemap
+++ b/c++/v1/module.modulemap
@@ -4,6 +4,7 @@ module std [system] {
module depr [extern_c] {
module inttypes_h {
header "inttypes.h"
+ header "stdint.h"
export stdint_h
export *
}
(note the modules for cinttypes
may also need to be adjusted)
Changing inttypes.h
diff --git a/inttypes.h b/inttypes.h
index 6d01e5d..93fff6c 100644
--- a/inttypes.h
+++ b/inttypes.h
@@ -1,6 +1,6 @@
#ifndef _INTTYPES_H_
#define _INTTYPES_H_
-#include <sys/stdint.h>
+#include <stdint.h>
#endif
Minimal test case
Minimal test case: make a directory, then git init
and git apply
the below patch. Then, running _run.sh
will give errors like
<stdin>:2:1: error: missing '#include "/tmp/y/stdint.h"'; 'uint8_t' must be declared before it is used
uint8_t x;
^
/tmp/y/stdint.h:13:33: note: declaration here is not visible
typedef __uint8_t uint8_t;
^
1 error generated.
Patch:
diff --git a/_run.sh b/_run.sh
new file mode 100644
index 0000000..e06b4f4
--- /dev/null
+++ b/_run.sh
@@ -0,0 +1,8 @@
+echo "Unexpected failures"
+printf '#include <stdint.h>\nuint8_t x;' | clang++ -xc++ -fmodules -c - -o /dev/null -isystem ./c++/v1/ -isystem . -nostdinc
+printf '#include <cstdint>\nuint8_t x;' | clang++ -xc++ -fmodules -c - -o /dev/null -isystem ./c++/v1/ -isystem . -nostdinc
+printf '#include <cstdint>\nuint8_t x;' | clang++ -xc++ -fmodules -c - -o /dev/null -isystem ./c++/v1/ -isystem . -nostdinc -I sys
+echo "Workarounds"
+printf '#include <stdint.h>\nuint8_t x;' | clang++ -xc++ -fmodules -c - -o /dev/null -isystem ./c++/v1/ -isystem . -nostdinc -I sys
+printf '#include <inttypes.h>\nuint8_t x;' | clang++ -xc++ -fmodules -c - -o /dev/null -isystem ./c++/v1/ -isystem . -nostdinc
+printf '#include <cinttypes>\nuint8_t x;' | clang++ -xc++ -fmodules -c - -o /dev/null -isystem ./c++/v1/ -isystem . -nostdinc
diff --git a/c++/v1/cinttypes b/c++/v1/cinttypes
new file mode 100644
index 0000000..f6641d5
--- /dev/null
+++ b/c++/v1/cinttypes
@@ -0,0 +1,2 @@
+#include <cstdint>
+#include <inttypes.h>
diff --git a/c++/v1/cstdint b/c++/v1/cstdint
new file mode 100644
index 0000000..9a6118b
--- /dev/null
+++ b/c++/v1/cstdint
@@ -0,0 +1 @@
+#include <stdint.h>
diff --git a/c++/v1/inttypes.h b/c++/v1/inttypes.h
new file mode 100644
index 0000000..25805e7
--- /dev/null
+++ b/c++/v1/inttypes.h
@@ -0,0 +1,2 @@
+#include_next <inttypes.h>
+#include <stdint.h>
diff --git a/c++/v1/module.modulemap b/c++/v1/module.modulemap
new file mode 100644
index 0000000..d26733f
--- /dev/null
+++ b/c++/v1/module.modulemap
@@ -0,0 +1,29 @@
+module std [system] {
+ export std_config
+
+ module depr [extern_c] {
+ module inttypes_h {
+ header "inttypes.h"
+ export stdint_h
+ export *
+ }
+ module stdint_h {
+ header "stdint.h"
+ export *
+ export Darwin.C.stdint
+ }
+ }
+
+ module compat {
+ module cinttypes {
+ header "cinttypes"
+ export cstdint
+ export *
+ }
+ module cstdint {
+ header "cstdint"
+ export depr.stdint_h
+ export *
+ }
+ }
+}
diff --git a/c++/v1/stdint.h b/c++/v1/stdint.h
new file mode 100644
index 0000000..286f763
--- /dev/null
+++ b/c++/v1/stdint.h
@@ -0,0 +1 @@
+#include_next <stdint.h>
diff --git a/inttypes.h b/inttypes.h
new file mode 100644
index 0000000..6d01e5d
--- /dev/null
+++ b/inttypes.h
@@ -0,0 +1,6 @@
+#ifndef _INTTYPES_H_
+#define _INTTYPES_H_
+
+#include <sys/stdint.h>
+
+#endif
diff --git a/machine/_types.h b/machine/_types.h
new file mode 100644
index 0000000..8705f73
--- /dev/null
+++ b/machine/_types.h
@@ -0,0 +1,7 @@
+#ifndef _MACHINE__TYPES_H_
+#define _MACHINE__TYPES_H_
+
+typedef signed char __int8_t;
+typedef unsigned char __uint8_t;
+
+#endif
diff --git a/stdint.h b/stdint.h
new file mode 120000
index 0000000..a7a8003
--- /dev/null
+++ b/stdint.h
@@ -0,0 +1 @@
+sys/stdint.h
\ No newline at end of file
diff --git a/sys/stdint.h b/sys/stdint.h
new file mode 100644
index 0000000..0b62164
--- /dev/null
+++ b/sys/stdint.h
@@ -0,0 +1,16 @@
+#ifndef _SYS_STDINT_H_
+#define _SYS_STDINT_H_
+
+#include <machine/_types.h>
+
+#ifndef _INT8_T_DEFINED_
+#define _INT8_T_DEFINED_
+typedef __int8_t int8_t;
+#endif
+
+#ifndef _UINT8_T_DEFINED_
+#define _UINT8_T_DEFINED_
+typedef __uint8_t uint8_t;
+#endif
+
+#endif