DUB and Gtk-d reduce size of huge executable, build dynamic dependencies

CSim mail at csim.ai
Sun Mar 11 00:24:58 UTC 2018


On Saturday, 10 March 2018 at 15:46:58 UTC, Gerald wrote:
> On Wednesday, 7 March 2018 at 10:51:49 UTC, CSim wrote:
>> Hi,
>>
>> I'm trying to decide whether it is better to use DLang for Gtk 
>> development or Vala/Genie.
>>
>> When I make a simple Vala/Genie Gtk executable the file is 
>> tiny whereas the DLang file is huge.  First I used the default 
>> Dub build and the file was in excess of 60mb (assuming this 
>> includes debug build).  Using dub build=release the file is 
>> still more than 7 mb.  Using a native Vala/Genie build the 
>> file is less than 500k.
>>
>> Trying to understand what is going on, but I assume from this 
>> that Dub is linking static dependencies, whereas the 
>> Vala/Genie builds will link to dynamic libraries.
>>
>>
>> So my (two pronged) question is this:  Is there any way to 
>> specify in dub.json to build and link dependencies as dynamic 
>> libraries, and are there any other tips that can be used to 
>> reduce these (relatively) huge executables?
>
> Personally, I do not worry too much about the executable size, 
> however a couple of tips as follows:
>
> a. If this is on linux use "strip" to remove symbols out of the 
> executable
>
> b. In dub.json you can specify just the portions of GtkD that 
> your application depends on, i.e.:
>
>     "dependencies": {
>         "gtk-d:gtkd": {
>             "version": "3.7.5"
>         },
>         "gtk-d:vte": {
>             "version": "3.7.5"
>         }
>     }
>
> Is what I use in tilix (https://github.com/gnunn1/tilix)
>
> c. You can dynamically link to GtkD, in tilix I have the config 
> below to do so. Interestingly on ldc it doesn't make any 
> difference in size though using ldd I can see the dependency to 
> GtkD. With DMD it is smaller however I cannpt run it since the 
> Arch Linux GtkD package is compiled with ldc2.
>
>         {
>             "name": "dynamic",
>             "targetType": "executable",
>             "libs": ["gtkd-3"],
>             "libs-linux": ["X11"],
>             "lflags": ["-defaultlib=libgtkd-3.so"],
>             "versions": ["StdLoggerDisableTrace"]
>         }

Thank you for this - I didn't have much luck with DUB/DMD but 
I'll give it another try.  The only thing I could get to work 
properly so far is LDC2 (1.8.0) and Make (4.2.1).  Meson (0.44.1) 
+ LDC2 did not work (using -XLinker by default - I had to hand 
edit the ninja.build file which kind of defeats the purpose of 
using Meson).

I managed to produce an executable less than 100k, whereas before 
it was between 6mb minimum.  Of course the shared LDC runtime and 
phobos libs were needed as well as the gtkd-3 lib - these are 
about 40mb cumulatively (about 23mb when debugs are removed).  
Here is a snippet from the Makefile containing the DLang settings 
(trying to combine DLang with other existing C and CPP libs too 
but this is not shown):

==================== Begin Makefile ======================

# General settings
TARGET := app_d
LIB_DIR := ./lib
BUILD_DIR := ./build

# Assemble all source files.
SRC.d := -name *.d
SRC_DIRS := ./source
SRCS := $(shell find $(SRC_DIRS) $(SRC.d))

# Assemble all include directories
HDR_DIRS := ./source
INC_DIRS := $(shell find $(HDR_DIRS) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))

# D source settings
DC := ldc2
DCFLAGS := $(INC_FLAGS) -I/usr/local/include/d/gtkd-3/ 
-enable-color -wi -g -O0
DLFLAGS := -link-defaultlib-shared 
-L-L/usr/local/lib/x86_64-linux-gnu/ -L-rpath=$(LIB_DIR) 
-L-lgtkd-3 -L-ldl
COMPILE.d = $(DC) $(DCFLAGS) -c $<
OUTPUT.d = -of $@
BUILD.d = $(DC) $(DCFLAGS) $^ $(DLFLAGS)

# Assemble all objects to be built.
ALL_OBJECTS := $(SRCS:%=$(BUILD_DIR)/%.o)

# Compile D source to object files.
$(BUILD_DIR)/%.d.o:%.d
	$(COMPILE.d) $(OUTPUT.d)	

# Make the target at the top level.
$(TARGET):$(ALL_OBJECTS)
	$(BUILD.d) $(OUTPUT.d)

# Build everything.
all: $(TARGET)

====================== End Makefile =====================

And here is the file tree (I just copied the libs over from the 
default LDC2 install):

├── app_d
├── build
│   └── source
│       └── app.d.o
├── lib
│   ├── libdruntime-ldc-debug-shared.so -> 
libdruntime-ldc-debug-shared.so.78
│   ├── libdruntime-ldc-debug-shared.so.2.0.78
│   ├── libdruntime-ldc-debug-shared.so.78 -> 
libdruntime-ldc-debug-shared.so.2.0.78
│   ├── libdruntime-ldc-shared.so -> libdruntime-ldc-shared.so.78
│   ├── libdruntime-ldc-shared.so.2.0.78
│   ├── libdruntime-ldc-shared.so.78 -> 
libdruntime-ldc-shared.so.2.0.78
│   ├── libgtkd-3.so -> libgtkd-3.so.0
│   ├── libgtkd-3.so.0 -> libgtkd-3.so.0.8.0
│   ├── libgtkd-3.so.0.8.0
│   ├── libphobos2-ldc-debug-shared.so -> 
libphobos2-ldc-debug-shared.so.78
│   ├── libphobos2-ldc-debug-shared.so.2.0.78
│   ├── libphobos2-ldc-debug-shared.so.78 -> 
libphobos2-ldc-debug-shared.so.2.0.78
│   ├── libphobos2-ldc-shared.so -> libphobos2-ldc-shared.so.78
│   ├── libphobos2-ldc-shared.so.2.0.78
│   └── libphobos2-ldc-shared.so.78 -> 
libphobos2-ldc-shared.so.2.0.78
├── Makefile
└── source
     └── app.d

Anyway, I wanted to see if I could produce something smaller than 
a native Vala binary - so here is the result:

Vala Gtk Hello World: 68.9k (10.7K after stripping)
DLang Gtk Hello World: 34.8k (15.9K after stripping)

So yes, mission accomplished! (sort of - if we ignore the shared 
libs, of course).  Anyway its all good clean fun, as they say.


More information about the Digitalmars-d-learn mailing list