Thread overview
DUB and Gtk-d reduce size of huge executable, build dynamic dependencies
Mar 07, 2018
CSim
Mar 10, 2018
Gerald
Mar 11, 2018
CSim
Mar 12, 2018
CSim
March 07, 2018
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?
March 10, 2018
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"]
        }
March 11, 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.
March 12, 2018
OK.  With the right compiler options (ldc2 -Oz and removing -g) the app_d file size, after stripping, becomes 10.5K.