Linux: module for <dispatch/dispatch.h> needs -fblocks to compile


(Tom Sheffler) #1

I’m learning about Swift on Linux and using modules to wrap C libraries. One of the things I wanted to do was use libdispatch with blocks from Swift. I thought it would be easy to use a module to wrap <dispatch/dispatch.h>.

I made a module called “CDispatch” with a module.modulemap like this

···

=======
module CDispatch [system] {
    header "/usr/include/dispatch/dispatch.h"
    export *
    link "dispatch"
}

Then I created a little demo project called gcd4 whose Source/main.swift prints some things and then uses a dispatch queue and a block to print a message after 2 seconds delay.

=========
CDispatch.dispatch_after(time, queue, {
    print("Delayed!")
})

The entire project is checked in at https://github.com/sheffler/gcd4
and the CDispatch module is checked in at https://github.com/sheffler/CDispatch

If I try to “swift build” the project, it almost works but reports that dispatch_after is not found. It seems that this function is not defined if the “blocks" feature is not provided at compilation time.

========
Compiling Swift Module 'gcd4' (1 sources)
/home/sheffler/swift/gcd4/Sources/main.swift:42:1: error: module 'CDispatch' has no member named 'dispatch_after'
CDispatch.dispatch_after(time, queue, {
^~~~~~~~~ ~~~~~~~~~~~~~~
<unknown>:0: error: build had 1 command failures
swift-build: exit(1): ["/home/sheffler/src/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04/usr/bin/swift-build-tool", "-f", "/home/sheffler/swift/gcd4/.build/debug/gcd4.o/llbuild.yaml”]

I got the demo program to work by first using “swift build” to retrieve the CDispatch module, and then manually running the compiler like this (and including the “-Xcc -fblocks” arguments)

swiftc -v -o gcd4 Sources/main.swift -I .build/debug -j8 -Onone -g -Xcc -fblocks -Xcc -F-module-map=Packages/CDispatch-1.0.0/module.modulemap -I Packages/CDispatch-1.0.0 -I /usr/local/include

This is all pretty neat! I’ve got blocks, dispatch queues and ARC on Ubuntu. I have one question and one remark.

- Am i missing something about how to create the CDispatch module? Why can’t “swift build” build this?

- Creating Git repositories for simple modules that wrap a single library and include a header file or two seems like too much. I would love to have been able to create a sub-directory in my project with a modulemap that includes <dispatch/dispatch.h> and links libdispatch.so

Thanks
Tom

P.S. - I tried to make this easy to check out and compile


(Daniel Dunbar) #2

I’m learning about Swift on Linux and using modules to wrap C libraries. One of the things I wanted to do was use libdispatch with blocks from Swift. I thought it would be easy to use a module to wrap <dispatch/dispatch.h>.

I made a module called “CDispatch” with a module.modulemap like this

=======
module CDispatch [system] {
    header "/usr/include/dispatch/dispatch.h"
    export *
    link "dispatch"
}

Then I created a little demo project called gcd4 whose Source/main.swift prints some things and then uses a dispatch queue and a block to print a message after 2 seconds delay.

=========
CDispatch.dispatch_after(time, queue, {
    print("Delayed!")
})

The entire project is checked in at https://github.com/sheffler/gcd4
and the CDispatch module is checked in at https://github.com/sheffler/CDispatch

If I try to “swift build” the project, it almost works but reports that dispatch_after is not found. It seems that this function is not defined if the “blocks" feature is not provided at compilation time.

========
Compiling Swift Module 'gcd4' (1 sources)
/home/sheffler/swift/gcd4/Sources/main.swift:42:1: error: module 'CDispatch' has no member named 'dispatch_after'
CDispatch.dispatch_after(time, queue, {
^~~~~~~~~ ~~~~~~~~~~~~~~
<unknown>:0: error: build had 1 command failures
swift-build: exit(1): ["/home/sheffler/src/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04/usr/bin/swift-build-tool", "-f", "/home/sheffler/swift/gcd4/.build/debug/gcd4.o/llbuild.yaml”]

I got the demo program to work by first using “swift build” to retrieve the CDispatch module, and then manually running the compiler like this (and including the “-Xcc -fblocks” arguments)

swiftc -v -o gcd4 Sources/main.swift -I .build/debug -j8 -Onone -g -Xcc -fblocks -Xcc -F-module-map=Packages/CDispatch-1.0.0/module.modulemap -I Packages/CDispatch-1.0.0 -I /usr/local/include

This is all pretty neat! I’ve got blocks, dispatch queues and ARC on Ubuntu. I have one question and one remark.

- Am i missing something about how to create the CDispatch module? Why can’t “swift build” build this?

This is mostly an oversight, the libdispatch port has been coming up and you are perhaps the first person to try to integrate all of these things.

I'm not sure yet exactly how we should resolve this, it might be the case that swiftc should just default to enabling blocks support in the Clang importer. In any case, can you open a specific bug in JIRA for this issue?

- Creating Git repositories for simple modules that wrap a single library and include a header file or two seems like too much. I would love to have been able to create a sub-directory in my project with a modulemap that includes <dispatch/dispatch.h> and links libdispatch.so

There will be an easier avenue to getting this working once we have some amount of C support in the package manager.

Even then, one pro of encouraging the separate definition of module map packages is so that they can be used by other people. It is cumbersome until we have a the ecosystem of those packages (and easy ways for people to find them), but it would be worse if they never ever ended up being shared.

- Daniel

···

On Dec 17, 2015, at 1:40 PM, Tom Sheffler via swift-users <swift-users@swift.org> wrote:

Thanks
Tom

P.S. - I tried to make this easy to check out and compile

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Tom Sheffler) #3

I’m learning about Swift on Linux and using modules to wrap C libraries. One of the things I wanted to do was use libdispatch with blocks from Swift. I thought it would be easy to use a module to wrap <dispatch/dispatch.h>.

I made a module called “CDispatch” with a module.modulemap like this

=======
module CDispatch [system] {
    header "/usr/include/dispatch/dispatch.h"
    export *
    link "dispatch"
}

Then I created a little demo project called gcd4 whose Source/main.swift prints some things and then uses a dispatch queue and a block to print a message after 2 seconds delay.

=========
CDispatch.dispatch_after(time, queue, {
    print("Delayed!")
})

The entire project is checked in at https://github.com/sheffler/gcd4
and the CDispatch module is checked in at https://github.com/sheffler/CDispatch

If I try to “swift build” the project, it almost works but reports that dispatch_after is not found. It seems that this function is not defined if the “blocks" feature is not provided at compilation time.

========
Compiling Swift Module 'gcd4' (1 sources)
/home/sheffler/swift/gcd4/Sources/main.swift:42:1: error: module 'CDispatch' has no member named 'dispatch_after'
CDispatch.dispatch_after(time, queue, {
^~~~~~~~~ ~~~~~~~~~~~~~~
<unknown>:0: error: build had 1 command failures
swift-build: exit(1): ["/home/sheffler/src/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04/usr/bin/swift-build-tool", "-f", "/home/sheffler/swift/gcd4/.build/debug/gcd4.o/llbuild.yaml”]

I got the demo program to work by first using “swift build” to retrieve the CDispatch module, and then manually running the compiler like this (and including the “-Xcc -fblocks” arguments)

swiftc -v -o gcd4 Sources/main.swift -I .build/debug -j8 -Onone -g -Xcc -fblocks -Xcc -F-module-map=Packages/CDispatch-1.0.0/module.modulemap -I Packages/CDispatch-1.0.0 -I /usr/local/include

This is all pretty neat! I’ve got blocks, dispatch queues and ARC on Ubuntu. I have one question and one remark.

- Am i missing something about how to create the CDispatch module? Why can’t “swift build” build this?

This is mostly an oversight, the libdispatch port has been coming up and you are perhaps the first person to try to integrate all of these things.

It’s not normal, i know. I’m looking forward to using blocks/dispatch on Linux for a media project.

I'm not sure yet exactly how we should resolve this, it might be the case that swiftc should just default to enabling blocks support in the Clang importer. In any case, can you open a specific bug in JIRA for this issue?

I’ll add the issue.

- Creating Git repositories for simple modules that wrap a single library and include a header file or two seems like too much. I would love to have been able to create a sub-directory in my project with a modulemap that includes <dispatch/dispatch.h> and links libdispatch.so

There will be an easier avenue to getting this working once we have some amount of C support in the package manager.

Even then, one pro of encouraging the separate definition of module map packages is so that they can be used by other people. It is cumbersome until we have a the ecosystem of those packages (and easy ways for people to find them), but it would be worse if they never ever ended up being shared.

I think the package manager direction for Swift is great actually. I just took the opportunity to share some of my early experiences whil I had the chance.

···

On Dec 20, 2015, at 3:51 PM, Daniel Dunbar <daniel_dunbar@apple.com> wrote:

On Dec 17, 2015, at 1:40 PM, Tom Sheffler via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

- Daniel

Thanks
Tom

P.S. - I tried to make this easy to check out and compile

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users