Skip to content

Commit 69310c6

Browse files
authored
Merge pull request #87 from kornilova-l/optional-static-linking
Optional static linking and doc improvements
2 parents 834b601 + 1573de7 commit 69310c6

File tree

4 files changed

+91
-37
lines changed

4 files changed

+91
-37
lines changed

README.md

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ This tool generates Scala Native bindings from C headers. It's built upon clang
88

99
Calling the tool is pretty easy, you need to specify the file(s) and the name of the created bindings.
1010

11-
`./scala-native-bindgen /usr/include/uv.h -name uv --`
11+
```sh
12+
scala-native-bindgen --name uv /usr/include/uv.h --
13+
```
1214

1315
Running the previous command wild also yield warnings along with the translation. To keep only the bindings please redirect the output to a file like this:
1416

15-
`./scala-native-bindgen /usr/include/uv.h -name uv -- > uv.scala`
17+
```sh
18+
scala-native-bindgen --name uv /usr/include/uv.h -- > uv.scala
19+
```
1620

17-
Run `./scala-native-bindgen -help` to see all available options.
21+
Run `scala-native-bindgen --help` to see all available options.
1822

1923
## Obtaining bindgen
2024

@@ -53,28 +57,58 @@ each merge to the `master` branch.
5357
[Docker]: https://www.docker.com/
5458
[docker-bindgen.sh]: scripts/docker-bindgen.sh
5559

56-
### Building
60+
## Building
5761

58-
Building this tool requires [CMake], [LLVM] and [Clang]. See the [Scala
59-
Native setup guide] for instructions on installing the dependencies.
62+
Building `scala-native-bindgen` requires the following tools and libraries:
63+
64+
- [CMake] version 3.9 or higher
65+
- [LLVM] and [Clang] version 5.0 or 6.0.
66+
67+
```sh
68+
# On apt-based systems
69+
apt install cmake clang-$LLVM_VERSION libclang-$LLVM_VERSION-dev llvm-$LLVM_VERSION-dev
70+
71+
# With `brew`
72+
brew install cmake llvm@6
73+
```
74+
75+
To run the tests you also need the required Scala Native libraries.
76+
See the [Scala Native setup guide] for instructions on installing the dependencies.
6077

6178
```sh
6279
mkdir -p bindgen/target
6380
cd bindgen/target
6481
cmake ..
6582
make
66-
./scala-native-bindgen /usr/include/ctype.h -name ctype --
83+
./scala-native-bindgen --name ctype /usr/include/ctype.h --
6784
```
6885

86+
To build a statically linked executable pass `-DSTATIC_LINKING=ON` when invoking `cmake`:
87+
88+
```sh
89+
cmake -DSTATIC_LINKING=ON ..
90+
```
91+
92+
Additional compiler and linker flags may be passed as environment variable sor their CMake
93+
equivalent, e.g. to compile with debug symbols the following are the same:
94+
95+
```sh
96+
cmake -DCMAKE_CXX_FLAGS=-g ..
97+
CXXFLAGS=-g cmake ..
98+
```
99+
100+
### Building with `docker-compose`
101+
69102
Alternatively, you can use [docker-compose] to build and test the program:
70103

71104
```sh
72105
# Build the docker image with LLVM version 6.0.
73106
docker-compose build ubuntu-18.04-llvm-6.0
74107
# Build the bindgen tool and run the tests.
75-
docker-compose run --rm ubuntu-18.04-llvm-6.0
108+
docker-compose run --rm ubuntu-18.04-llvm-6.0 ./script/test.sh
76109
# Run the bindgen tool inside the container.
77-
docker-compose run --rm ubuntu-18.04-llvm-6.0 bindgen/target/scala-native-bindgen -name union tests/samples/Union.h --
110+
docker-compose run --rm ubuntu-18.04-llvm-6.0 \
111+
bindgen/target/scala-native-bindgen --name union tests/samples/Union.h --
78112
```
79113

80114
[CMake]: https://cmake.org/
@@ -85,17 +119,19 @@ docker-compose run --rm ubuntu-18.04-llvm-6.0 bindgen/target/scala-native-bindge
85119

86120
## Testing
87121

88-
The tests assume that the above instructions for building has been
89-
followed.
122+
The tests assume that the above instructions for building `scala-native-bindgen` from source
123+
has been followed.
90124

91125
```sh
92126
cd tests
93127
sbt test
94128
```
95129

96-
## Current limitations
130+
## Limitations
131+
97132
There are multiple unsupported cases that should be considered when generating bindings:
98-
1. Currently bindgen does not support passing structs by value.
133+
134+
1. Currently bindgen does not support passing structs by value.
99135
For example, it will not be possible to call these two functions from Scala Native code:
100136
```c
101137
struct MyStruct {
@@ -107,12 +143,26 @@ There are multiple unsupported cases that should be considered when generating b
107143
void handleStruct(struct MyStruct mystr);
108144
```
109145
To support such cases one should generate bindings for C wrapper functions that use pointers to structs instead of actual structs.
110-
2. Bindgen does not generate bindings for defines.
111-
In order to use defines one should write wrapper functions that return defined values.
112-
3. There is no way to reuse already generated bindings.
113-
Bindgen outputs bindings also for headers that were included in a given header.
114-
4. Type qualifiers `const`, `volatile` and `restrict` are not supported.
115-
5. Extern variables are read-only.
146+
2. `#define`s for literals and variables are supported. For other types of `#define`s,
147+
write wrapper functions that return defined values.
148+
```c
149+
// Supported
150+
#define ESC 0x1b /* Defines for numerical and string literals. */
151+
extern const int pi_const;
152+
#define PI pi_const /* Defines aliasing extern variables. */
153+
154+
// Not supported (non-exhaustive list)
155+
#define COLS (getenv("COLS") ? atoi(getenv("COLS")) : 80)
156+
#define MAX(a, b) (a > b ? a : b)
157+
```
158+
159+
3. There is no way to reuse already generated bindings.
160+
Bindgen outputs bindings also for headers that were included in a given header. See [#2].
161+
4. Type qualifiers `const`, `volatile` and `restrict` are not supported.
162+
5. Extern variables are read-only. See [scala-native/scala-native#202].
163+
164+
[#2]: https://github.com/kornilova-l/scala-native-bindgen/issues/2
165+
[scala-native/scala-native#202]: https://github.com/scala-native/scala-native/issues/202
116166

117167
## License
118168

bindgen/CMakeLists.txt

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.9)
22
project(scala-native-bindgen)
33

4-
set(USE_SHARED OFF)
4+
option(STATIC_LINKING "Statically link the executable" OFF)
55

66
# Locate LLVMConfig.cmake
77
find_package(LLVM REQUIRED CONFIG)
@@ -14,22 +14,11 @@ include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
1414
message(STATUS "Using LLVM defs: ${LLVM_DEFINITIONS}")
1515
add_definitions(${LLVM_DEFINITIONS})
1616

17-
add_compile_options(-fexceptions -std=c++11 -Wall -Wconversion -Werror)
18-
19-
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
20-
# macOS does not guarantee backwards compatible system calls and therefore
21-
# discourages statically linked binaries. Instead add -L/usr/lib before the
22-
# LLVM LDFLAGS to link against the dynamic system libc++ instead of the one
23-
# from LLVM.
24-
set(BINDGEN_LINK_FLAG "-L/usr/lib")
25-
else()
26-
set(BINDGEN_LINK_FLAG "-static")
27-
endif()
28-
message(STATUS "Using link flag: ${BINDGEN_LINK_FLAG}")
29-
3017
message(STATUS "Using LLVM library directories: ${LLVM_LIBRARY_DIRS}")
3118
link_directories(${LLVM_LIBRARY_DIRS})
3219

20+
add_compile_options(-fexceptions -std=c++11 -Wall -Wconversion -Werror)
21+
3322
add_executable(bindgen
3423
Main.cpp
3524
visitor/ScalaFrontendAction.h
@@ -85,14 +74,29 @@ add_executable(bindgen
8574
ir/types/ArrayType.h
8675
)
8776

77+
if (STATIC_LINKING)
78+
set(USE_SHARED OFF)
79+
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
80+
# macOS does not guarantee backwards compatible system calls and therefore
81+
# discourages statically linked binaries. Instead add -L/usr/lib before the
82+
# LLVM LDFLAGS to link against the dynamic system libc++ instead of the one
83+
# from LLVM.
84+
set(BINDGEN_LINK_FLAG "-L/usr/lib")
85+
else()
86+
set(BINDGEN_LINK_FLAG "-static")
87+
endif()
88+
llvm_map_components_to_libnames(LLVM_LIBS support core irreader object option profiledata)
89+
else()
90+
set(LLVM_LIBS LLVM)
91+
endif()
92+
message(STATUS "Using link flag: ${BINDGEN_LINK_FLAG}")
93+
8894
set_target_properties(bindgen
8995
PROPERTIES
9096
OUTPUT_NAME scala-native-bindgen
9197
LINK_FLAGS "${BINDGEN_LINK_FLAG}"
9298
)
9399

94-
llvm_map_components_to_libnames(LLVM_LIBS support core irreader object option profiledata)
95-
96100
target_link_libraries(bindgen
97101
PRIVATE
98102
clangFrontend

bindgen/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ COPY . /src
88
RUN set -x \
99
&& mkdir target \
1010
&& cd target \
11-
&& cmake .. \
11+
&& cmake -DSTATIC_LINKING=ON .. \
1212
&& make
1313

1414
FROM scratch

bindgen/Main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <clang/Tooling/CommonOptionsParser.h>
44

55
int main(int argc, const char *argv[]) {
6-
llvm::cl::OptionCategory Category("Binding Generator");
6+
llvm::cl::OptionCategory Category("Scala Native Binding Generator");
77
llvm::cl::extrahelp CommonHelp(
88
clang::tooling::CommonOptionsParser::HelpMessage);
99
llvm::cl::extrahelp MoreHelp("\nProduce Bindings for scala native. Please "

0 commit comments

Comments
 (0)