Skip to content

Commit b65aa22

Browse files
committed
SR-2309: embed BlocksRuntime in libdispatch to eliminate external dependency
Eliminate the external dependency on libBlocksRuntime.so by copying the blocks runtime code from swift-corelibs-foundation/closure and building it into libdispatch. Added a configure option to control whether or not the blocks runtime is embedded; defaults to embedded on Linux and not embedded on other platforms. Since the blocks runtime is embedded; we can take the link directive out of the module.modulemap file. This change enables dispatch to be built and run on a system without the libblocksruntime-dev package installed.
1 parent f99215a commit b65aa22

File tree

8 files changed

+1162
-44
lines changed

8 files changed

+1162
-44
lines changed

dispatch/module.modulemap

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ module Dispatch {
22
requires blocks
33
export *
44
link "dispatch"
5-
link "BlocksRuntime"
65
}
76

87
module DispatchIntrospection [system] [extern_c] {
@@ -16,5 +15,4 @@ module CDispatch [system] [extern_c] {
1615
export *
1716
requires blocks
1817
link "dispatch"
19-
link "BlocksRuntime"
2018
}

m4/blocks.m4

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ AC_ARG_WITH([blocks-runtime],
1010
LIBS="$LIBS -L$blocks_runtime"]
1111
)
1212
13+
#
14+
# Configure argument to enable/disable using an embedded blocks runtime
15+
#
16+
AC_ARG_ENABLE([embedded_blocks_runtime],
17+
[AS_HELP_STRING([--enable_embedded_blocks_runtime],
18+
[Enable usage of blocks runtime embedded in libdispatch])],,
19+
[case $target_os in
20+
linux*)
21+
enable_embedded_blocks_runtime=yes
22+
;;
23+
*)
24+
enable_embedded_blocks_runtime=no
25+
esac]
26+
)
27+
1328
#
1429
# Detect compiler support for Blocks; perhaps someday -fblocks won't be
1530
# required, in which case we'll need to change this.
@@ -29,30 +44,32 @@ AC_CACHE_CHECK([for C Blocks support], [dispatch_cv_cblocks], [
2944
AS_IF([test "x$dispatch_cv_cblocks" != "xno"], [
3045
CBLOCKS_FLAGS="$dispatch_cv_cblocks"
3146
32-
#
33-
# It may be necessary to directly link the Blocks runtime on some
34-
# systems, so give it a try if we can't link a C program that uses
35-
# Blocks. We will want to remove this at somepoint, as really -fblocks
36-
# should force that linkage already.
37-
#
38-
saveCFLAGS="$CFLAGS"
39-
CFLAGS="$CFLAGS -fblocks -O0"
40-
AC_MSG_CHECKING([whether additional libraries are required for the Blocks runtime])
41-
AC_TRY_LINK([], [
42-
^{ int j; j=0; }();
43-
], [
44-
AC_MSG_RESULT([no]);
45-
], [
46-
saveLIBS="$LIBS"
47-
LIBS="$LIBS -lBlocksRuntime"
48-
AC_TRY_LINK([], [
49-
^{ int k; k=0; }();
50-
], [
51-
AC_MSG_RESULT([-lBlocksRuntime])
52-
], [
53-
AC_MSG_ERROR([can't find Blocks runtime])
54-
])
55-
])
47+
AS_IF([test "x$enable_embedded_blocks_runtime" != "xyes"], [
48+
#
49+
# It may be necessary to directly link the Blocks runtime on some
50+
# systems, so give it a try if we can't link a C program that uses
51+
# Blocks. We will want to remove this at somepoint, as really -fblocks
52+
# should force that linkage already.
53+
#
54+
saveCFLAGS="$CFLAGS"
55+
CFLAGS="$CFLAGS -fblocks -O0"
56+
AC_MSG_CHECKING([whether additional libraries are required for the Blocks runtime])
57+
AC_TRY_LINK([], [
58+
^{ int j; j=0; }();
59+
], [
60+
AC_MSG_RESULT([no]);
61+
], [
62+
saveLIBS="$LIBS"
63+
LIBS="$LIBS -lBlocksRuntime"
64+
AC_TRY_LINK([], [
65+
^{ int k; k=0; }();
66+
], [
67+
AC_MSG_RESULT([-lBlocksRuntime])
68+
], [
69+
AC_MSG_ERROR([can't find Blocks runtime])
70+
])
71+
])
72+
])
5673
CFLAGS="$saveCFLAGS"
5774
have_cblocks=true
5875
], [
@@ -61,6 +78,7 @@ AS_IF([test "x$dispatch_cv_cblocks" != "xno"], [
6178
])
6279
AM_CONDITIONAL(HAVE_CBLOCKS, $have_cblocks)
6380
AC_SUBST([CBLOCKS_FLAGS])
81+
AM_CONDITIONAL([BUILD_OWN_BLOCKS_RUNTIME], [test "x$enable_embedded_blocks_runtime" = "xyes"])
6482
6583
#
6684
# Because a different C++ compiler may be specified than C compiler, we have
@@ -82,24 +100,26 @@ AC_CACHE_CHECK([for C++ Blocks support], [dispatch_cv_cxxblocks], [
82100
AS_IF([test "x$dispatch_cv_cxxblocks" != "xno"], [
83101
CXXBLOCKS_FLAGS="$dispatch_cv_cxxblocks"
84102
85-
saveCXXFLAGS="$CXXFLAGS"
86-
CXXFLAGS="$CXXFLAGS -fblocks -O0"
87-
AC_MSG_CHECKING([whether additional libraries are required for the Blocks runtime])
88-
AC_TRY_LINK([], [
89-
^{ int j; j=0; }();
90-
], [
91-
AC_MSG_RESULT([no]);
92-
], [
93-
saveLIBS="$LIBS"
94-
LIBS="$LIBS -lBlocksRuntime"
95-
AC_TRY_LINK([], [
96-
^{ int k; k=0; }();
97-
], [
98-
AC_MSG_RESULT([-lBlocksRuntime])
99-
], [
100-
AC_MSG_ERROR([can't find Blocks runtime])
101-
])
102-
])
103+
AS_IF([test "x$enable_embedded_blocks_runtime" != "xyes"], [
104+
saveCXXFLAGS="$CXXFLAGS"
105+
CXXFLAGS="$CXXFLAGS -fblocks -O0"
106+
AC_MSG_CHECKING([whether additional libraries are required for the Blocks runtime])
107+
AC_TRY_LINK([], [
108+
^{ int j; j=0; }();
109+
], [
110+
AC_MSG_RESULT([no]);
111+
], [
112+
saveLIBS="$LIBS"
113+
LIBS="$LIBS -lBlocksRuntime"
114+
AC_TRY_LINK([], [
115+
^{ int k; k=0; }();
116+
], [
117+
AC_MSG_RESULT([-lBlocksRuntime])
118+
], [
119+
AC_MSG_ERROR([can't find Blocks runtime])
120+
])
121+
])
122+
])
103123
CXXFLAGS="$saveCXXFLAGS"
104124
have_cxxblocks=true
105125
], [

src/BlocksRuntime/Block.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
11+
#ifndef _Block_H_
12+
#define _Block_H_
13+
14+
#if !defined(BLOCK_EXPORT)
15+
# if defined(__cplusplus)
16+
# define BLOCK_EXPORT extern "C" __attribute__((visibility("default")))
17+
# else
18+
# define BLOCK_EXPORT extern __attribute__((visibility("default")))
19+
# endif
20+
#endif
21+
22+
#if __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
// Create a heap based copy of a Block or simply add a reference to an existing one.
27+
// This must be paired with Block_release to recover memory, even when running
28+
// under Objective-C Garbage Collection.
29+
BLOCK_EXPORT void *_Block_copy(const void *aBlock);
30+
31+
// Lose the reference, and if heap based and last reference, recover the memory
32+
BLOCK_EXPORT void _Block_release(const void *aBlock);
33+
34+
// Used by the compiler. Do not call this function yourself.
35+
BLOCK_EXPORT void _Block_object_assign(void *, const void *, const int);
36+
37+
// Used by the compiler. Do not call this function yourself.
38+
BLOCK_EXPORT void _Block_object_dispose(const void *, const int);
39+
40+
// Used by the compiler. Do not use these variables yourself.
41+
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
42+
BLOCK_EXPORT void * _NSConcreteStackBlock[32];
43+
44+
#if __cplusplus
45+
}
46+
#endif
47+
48+
// Type correct macros
49+
50+
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
51+
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
52+
53+
54+
#endif

0 commit comments

Comments
 (0)