[swift-dev] need help with GLibc module map problem

Dmitri Gribenko gribozavr at gmail.com
Thu Jun 2 17:19:33 CDT 2016

On Thu, Jun 2, 2016 at 2:58 PM, David P Grove via swift-dev
<swift-dev at swift.org> wrote:
> As part of helping to resolve old libdispatch pull requests, I have run into
> a problem with the GLibc module map on Linux that I need help understanding
> and fixing.
> The symptom I am trying to resolve is that somewhere between the March 16
> and March 24 Swift development snapshots, the Dispatch overlay for
> libdispatch on Linux stopped building. We've been hacking around the problem
> for 2 months (https://github.com/apple/swift-corelibs-libdispatch/pull/62),
> but we don't want to merge that hack back to the master branch of
> libdispatch.
> The issue is that swiftc is convinced that off_t and mode_t should be
> defined in the stdio module (by including stdio.h). We don't want to include
> stdio.h in dispatch.h; it is sufficient (and the C compilation of
> libdispatch succeeds) to only include fcntl.h and unistd.h. However without
> including stdio.h in dispatch.h, building the swiftmodule from
> Dispatch.swift fails, starting with the March 24 driver (and is still broken
> on master as of this morning).
> I can hack around this by (a) including stdio.h in dispatch.h or (b) editing
> glibc.modulemap.gyb to put the module statements for fnctl and unistd before
> the modile statement for stdio. Neither of these seem like the right fix.
> Can anyone point me to a better solution?
> I've attached the full buildlog. The actual build errors are excerpted below
> as well.
> thanks,
> --dave
> (See attached file: buildLog.txt)
> make[2]: Entering directory
> '/home/dgrove/swift/build/dpg/libdispatch-linux-x86_64/src'
> /home/dgrove/swift/build/dpg/swift-linux-x86_64/bin/swiftc -Xcc
> -fmodule-map-file=/home/dgrove/swift/swift-corelibs-libdispatch/dispatch/module.map
> -I/home/dgrove/swift/swift-corelibs-libdispatch -parse-as-library -Xcc
> -fblocks -c -o
> /home/dgrove/swift/build/dpg/libdispatch-linux-x86_64/src/Dispatch.o
> /home/dgrove/swift/swift-corelibs-libdispatch/src/swift/Dispatch.swift
> <module-includes>:1:10: note: in file included from <module-includes>:1:
> #include "dispatch.h"
> ^
> /home/dgrove/swift/swift-corelibs-libdispatch/dispatch/dispatch.h:59:10:
> note: in file included from
> /home/dgrove/swift/swift-corelibs-libdispatch/dispatch/dispatch.h:59:
> #include <dispatch/io.h>
> ^
> /home/dgrove/swift/swift-corelibs-libdispatch/dispatch/io.h:253:31: error:
> declaration of 'mode_t' must be imported from module
> 'SwiftGlibc.POSIX.sys.types' before it is required
> const char *path, int oflag, mode_t mode,
> ^
> /usr/include/x86_64-linux-gnu/sys/types.h:70:18: note: previous declaration
> is here
> typedef __mode_t mode_t;
> ^
> <module-includes>:1:10: note: in file included from <module-includes>:1:
> #include "dispatch.h"
> ^
> /home/dgrove/swift/swift-corelibs-libdispatch/dispatch/dispatch.h:59:10:
> note: in file included from
> /home/dgrove/swift/swift-corelibs-libdispatch/dispatch/dispatch.h:59:
> #include <dispatch/io.h>
> ^
> /home/dgrove/swift/swift-corelibs-libdispatch/dispatch/io.h:355:2: error:
> declaration of 'off_t' must be imported from module 'SwiftGlibc.C.stdio'
> before it is required
> off_t offset,
> ^
> /usr/include/stdio.h:90:17: note: previous declaration is here
> typedef __off_t off_t;

Could you check if there are multiple definitions of off_t or mode_t
in different headers guarded by macros?  Something like this,
duplicated across several headers:

#if !defined(_OFF_T_DEFINED)
typedef __off_t off_t;
#define _OFF_T_DEFINED

This is a frequent pattern used in C headers, but it is an antipattern
for modules.  With modules, all headers that are included into the
module get #included into a single translation unit and compiled into
a module, so only one of those typedefs will get activated (let's say
in foo.h), and the other one will get hidden because it is seen second
in the translation unit (let's say the one in bar.h gets hidden).  If
you then import just the submodule for bar.h, the off_t definition
won't be visible, because it was #ifdef'ed out.

There are fragile solutions to this (like including a header that
happens to fix the build this time), but the only real fix is to make
sure that there is only one place where a declaration can be located
in a module, regardless of the set of headers.


(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/

More information about the swift-dev mailing list