[cfe-dev] How do I try out C++ modules with clang?

Stephen Kelly steveire at gmail.com
Sun Oct 26 10:25:20 PDT 2014


Stephen Kelly wrote:

> Actually I think I hit similar errors from files in /usr/include when I
> tried this a few weeks ago on linux, and I think my solution was to add a
> modulemap in /usr/include for a few things. I'll check that in a few days.

I checked what I was running into regarding this, and made a testcase:

$ cat include/foo.map 
module foo {
  requires cplusplus
  header "foo.h"
}

$ cat include/foo.h

#include <utility>

#include <stdlib.h>

$ cat test.cpp 

#include "foo.h"

int main(int, char **)
{
  return 0;
}

$ clang++-libc++ -std=c++14 -fmodules -E test.cpp -fmodule-map-
file=include/foo.map -fmodules-cache-path=cache -fPIE -I include -I .
# 1 "test.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 340 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "test.cpp" 2
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:41:
/usr/include/x86_64-linux-gnu/bits/waitflags.h:52:3: error: redefinition of 
enumerator 'P_ALL'
  P_ALL,                /* Wait for any child.  */
  ^
/usr/include/x86_64-linux-gnu/bits/waitflags.h:52:3: note: previous 
definition is here
  P_ALL,                /* Wait for any child.  */
  ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:41:
/usr/include/x86_64-linux-gnu/bits/waitflags.h:53:3: error: redefinition of 
enumerator 'P_PID'
  P_PID,                /* Wait for specified process.  */
  ^
/usr/include/x86_64-linux-gnu/bits/waitflags.h:53:3: note: previous 
definition is here
  P_PID,                /* Wait for specified process.  */
  ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:41:
/usr/include/x86_64-linux-gnu/bits/waitflags.h:54:3: error: redefinition of 
enumerator 'P_PGID'
  P_PGID                /* Wait for members of process group.  */
  ^
/usr/include/x86_64-linux-gnu/bits/waitflags.h:54:3: note: previous 
definition is here
  P_PGID                /* Wait for members of process group.  */
  ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:42:
/usr/include/x86_64-linux-gnu/bits/waitstatus.h:66:7: error: redefinition of 
'wait'
union wait
      ^
/usr/include/x86_64-linux-gnu/bits/waitstatus.h:66:7: note: previous 
definition is here
union wait
      ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:235:
/usr/include/xlocale.h:27:16: error: redefinition of '__locale_struct'
typedef struct __locale_struct
               ^
/usr/include/xlocale.h:27:16: note: previous definition is here
typedef struct __locale_struct
               ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:239:17: error: conflicting types for 'strtol_l'
extern long int strtol_l (const char *__restrict __nptr,
                ^
/usr/include/stdlib.h:239:17: note: previous declaration is here
extern long int strtol_l (const char *__restrict __nptr,
                ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:243:26: error: conflicting types for 'strtoul_l'
extern unsigned long int strtoul_l (const char *__restrict __nptr,
                         ^
/usr/include/stdlib.h:243:26: note: previous declaration is here
extern unsigned long int strtoul_l (const char *__restrict __nptr,
                         ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:249:22: error: conflicting types for 'strtoll_l'
extern long long int strtoll_l (const char *__restrict __nptr,
                     ^
/usr/include/stdlib.h:249:22: note: previous declaration is here
extern long long int strtoll_l (const char *__restrict __nptr,
                     ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:255:31: error: conflicting types for 'strtoull_l'
extern unsigned long long int strtoull_l (const char *__restrict __nptr,
                              ^
/usr/include/stdlib.h:255:31: note: previous declaration is here
extern unsigned long long int strtoull_l (const char *__restrict __nptr,
                              ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:260:15: error: conflicting types for 'strtod_l'
extern double strtod_l (const char *__restrict __nptr,
              ^
/usr/include/stdlib.h:260:15: note: previous declaration is here
extern double strtod_l (const char *__restrict __nptr,
              ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:264:14: error: conflicting types for 'strtof_l'
extern float strtof_l (const char *__restrict __nptr,
             ^
/usr/include/stdlib.h:264:14: note: previous declaration is here
extern float strtof_l (const char *__restrict __nptr,
             ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:268:20: error: conflicting types for 'strtold_l'
extern long double strtold_l (const char *__restrict __nptr,
                   ^
/usr/include/stdlib.h:268:20: note: previous declaration is here
extern long double strtold_l (const char *__restrict __nptr,
                   ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:314:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:219:
In file included from /usr/include/x86_64-linux-gnu/sys/select.h:43:
/usr/include/time.h:120:8: error: redefinition of 'timespec'
struct timespec
       ^
/usr/include/time.h:120:8: note: previous definition is here
struct timespec
       ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:314:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:219:
In file included from /usr/include/x86_64-linux-gnu/sys/select.h:45:
/usr/include/x86_64-linux-gnu/bits/time.h:30:8: error: redefinition of 
'timeval'
struct timeval
       ^
/usr/include/x86_64-linux-gnu/bits/time.h:30:8: note: previous definition is 
here
struct timeval
       ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:314:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:219:
/usr/include/x86_64-linux-gnu/sys/select.h:106:12: error: conflicting types 
for 'select'
extern int select (int __nfds, fd_set *__restrict __readfds,
           ^
/usr/include/x86_64-linux-gnu/sys/select.h:106:12: note: previous 
declaration is here
extern int select (int __nfds, fd_set *__restrict __readfds,
           ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:314:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:219:
/usr/include/x86_64-linux-gnu/sys/select.h:118:12: error: conflicting types 
for 'pselect'
extern int pselect (int __nfds, fd_set *__restrict __readfds,
           ^
/usr/include/x86_64-linux-gnu/sys/select.h:118:12: note: previous 
declaration is here
extern int pselect (int __nfds, fd_set *__restrict __readfds,
           ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:314:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:270:
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h:63:7: error: redefinition 
of 'pthread_attr_t'
union pthread_attr_t
      ^
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h:63:7: note: previous 
definition is here
union pthread_attr_t
      ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
In file included from /usr/include/stdlib.h:314:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:270:
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h:75:16: error: redefinition 
of '__pthread_internal_list'
typedef struct __pthread_internal_list
               ^
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h:75:16: note: previous 
definition is here
typedef struct __pthread_internal_list
               ^
While building module 'foo' imported from test.cpp:2:
In file included from <module-includes>:1:
In file included from 
/home/stephen/dev/src/playground/modules/modulestry/include/foo.h:4:
/usr/include/stdlib.h:343:8: error: redefinition of 'random_data'
struct random_data
       ^
/usr/include/stdlib.h:343:8: note: previous definition is here
struct random_data
       ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
test.cpp:2:10: fatal error: could not build module 'foo'
#include "foo.h"
 ~~~~~~~~^~~~~~~



int main(int, char **)
{
  return 0;
}
21 errors generated.


To "fix" that, I created this module.modulemap in /usr/include : 

module systemheaders {
  header "stdio.h"
  header "stdlib.h"
  header "math.h"
}

After I did that, I was able to create a Qt5Core.modulemap on linux. I 
expect that file to grow if I add more modules for other Qt libraries.

I do find all this very inconvenient, and I expect things like this will 
hurt adoption for some time until there's a better solution in place (eg 
having modulemaps already in place). 

Thanks,

Steve.





More information about the cfe-dev mailing list