Skip to content

Commit

Permalink
build system refactoring
Browse files Browse the repository at this point in the history
- unify the "build-..." targets
- enable a debug build by default, to simplify development
- bump vendor/DOtherSide
- avoid DOtherSide checks for docs/tests-specific tools like Doxygen
- switch to an in-place build for DOtherSide
- silence the DOtherSide build when V=0, make it more verbose with V=1
- don't delete checked out submodules in the "clean" target
- update build instructions in the README
- centralise Nim compiler options in a top-level "config.nims" (except
  `-d:debug` which needs to be on the command line)
  • Loading branch information
stefantalpalaru authored and iurimatias committed Jun 8, 2020
1 parent 5371f22 commit 4fe6d9b
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 72 deletions.
78 changes: 48 additions & 30 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ BUILD_SYSTEM_DIR := vendor/nimbus-build-system
appimage \
clean \
deps \
nim_status_client \
run \
update

ifeq ($(NIM_PARAMS),)
Expand All @@ -35,37 +37,57 @@ GIT_SUBMODULE_UPDATE := git submodule update --init --recursive

else # "variables.mk" was included. Business as usual until the end of this file.

all: nim_status_client

# must be included after the default target
-include $(BUILD_SYSTEM_DIR)/makefiles/targets.mk

ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
detected_OS := Windows
detected_OS := Windows
else
detected_OS := $(strip $(shell uname))
detected_OS := $(strip $(shell uname))
endif


DEFAULT_TARGET := None
ifeq ($(detected_OS), Darwin)
DEFAULT_TARGET := build-macos
else
DEFAULT_TARGET := build-linux
NIM_PARAMS := $(NIM_PARAMS) -L:"-framework Foundation -framework Security -framework IOKit -framework CoreServices"
endif

all: $(DEFAULT_TARGET)
DOTHERSIDE := vendor/DOtherSide/lib/libDOtherSideStatic.a

# Qt5 dirs (we can't indent with tabs here)
QT5_PCFILEDIR := $(shell pkg-config --variable=pcfiledir Qt5Core 2>/dev/null)
QT5_LIBDIR := $(shell pkg-config --variable=libdir Qt5Core 2>/dev/null)
ifeq ($(QT5_PCFILEDIR),)
ifeq ($(QTDIR),)
$(error Can't find your Qt5 installation. Please run "$(MAKE) QTDIR=/path/to/your/Qt5/installation/prefix ...")
else
ifeq ($(detected_OS), Darwin)
QT5_PCFILEDIR := $(QTDIR)/clang_64/lib/pkgconfig
QT5_LIBDIR := $(QTDIR)/clang_64/lib
# some manually installed Qt5 instances have wrong paths in their *.pc files, so we pass the right one to the linker here
NIM_PARAMS += --passL:"-F$(QT5_LIBDIR)"
else
QT5_PCFILEDIR := $(QTDIR)/gcc_64/lib/pkgconfig
QT5_LIBDIR := $(QTDIR)/gcc_64/lib
NIM_PARAMS += --passL:"-L$(QT5_LIBDIR)"
endif
endif
endif
export QT5_LIBDIR
# order matters here, due to "-Wl,-as-needed"
NIM_PARAMS += --passL:"$(DOTHERSIDE) $(shell PKG_CONFIG_PATH="$(QT5_PCFILEDIR)" pkg-config --libs Qt5Core Qt5Qml Qt5Gui Qt5Quick Qt5QuickControls2 Qt5Widgets)"

# must be included after the default target
-include $(BUILD_SYSTEM_DIR)/makefiles/targets.mk
# TODO: control debug/release builds with a Make var
# We need `-d:debug` to get Nim's default stack traces.
NIM_PARAMS += --outdir:./bin -d:debug
# Enable debugging symbols in DOtherSide, in case we need GDB backtraces from it.
CFLAGS += -g
CXXFLAGS += -g

deps: | deps-common

update: | update-common

DOTHERSIDE := None
ifeq ($(detected_OS), Darwin)
DOTHERSIDE := vendor/DOtherSide/build/lib/libDOtherSide.dylib
else
DOTHERSIDE := vendor/DOtherSide/build/lib/libDOtherSide.so
endif

APPIMAGETOOL := appimagetool-x86_64.AppImage

$(APPIMAGETOOL):
Expand All @@ -75,28 +97,23 @@ $(APPIMAGETOOL):
$(DOTHERSIDE): | deps
echo -e $(BUILD_MSG) "DOtherSide"
+ cd vendor/DOtherSide && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. $(HANDLE_OUTPUT) && \
$(MAKE) DOtherSide # IF WE WANT TO USE LIBDOTHERSIDE AS STATIC LIBRARY, USE `$(MAKE) DOtherSideStatic` INSTEAD
rm -f CMakeCache.txt && \
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_DOCS=OFF -DENABLE_TESTS=OFF -DENABLE_DYNAMIC_LIBS=OFF -DENABLE_STATIC_LIBS=ON . $(HANDLE_OUTPUT) && \
$(MAKE) VERBOSE=$(V) $(HANDLE_OUTPUT)

STATUSGO := vendor/status-go/build/bin/libstatus.a

$(STATUSGO): | deps
echo -e $(BUILD_MSG) "status-go"
+ cd vendor/status-go && \
$(MAKE) statusgo-library

build-linux: $(DOTHERSIDE) $(STATUSGO) src/nim_status_client.nim | deps
echo -e $(BUILD_MSG) "$@" && \
$(ENV_SCRIPT) nim c -d:nimDebugDlOpen -L:$(STATUSGO) -d:ssl -L:-lm $(NIM_PARAMS) -L:$(DOTHERSIDE) --outdir:./bin src/nim_status_client.nim
$(MAKE) statusgo-library $(HANDLE_OUTPUT)

build-macos: $(DOTHERSIDE) $(STATUSGO) src/nim_status_client.nim | deps
nim_status_client: | $(DOTHERSIDE) $(STATUSGO) deps
echo -e $(BUILD_MSG) "$@" && \
$(ENV_SCRIPT) nim c -d:nimDebugDlOpen -L:$(STATUSGO) -d:ssl -L:-lm -L:"-framework Foundation -framework Security -framework IOKit -framework CoreServices" $(NIM_PARAMS) -L:$(DOTHERSIDE) --outdir:./bin src/nim_status_client.nim
$(ENV_SCRIPT) nim c $(NIM_PARAMS) --passL:"$(STATUSGO)" --passL:"-lm" src/nim_status_client.nim

run:
LD_LIBRARY_PATH=vendor/DOtherSide/build/lib ./bin/nim_status_client
LD_LIBRARY_PATH="$(QT5_LIBDIR)" ./bin/nim_status_client

APPIMAGE := NimStatusClient-x86_64.AppImage

Expand Down Expand Up @@ -135,6 +152,7 @@ $(APPIMAGE): $(DEFAULT_TARGET) $(APPIMAGETOOL) nim-status.desktop
appimage: $(APPIMAGE)

clean: | clean-common
rm -rf $(APPIMAGE) bin/* vendor/* tmp/dist
rm -rf $(APPIMAGE) bin/* tmp/dist $(STATUSGO)
+ $(MAKE) -C vendor/DOtherSide --no-print-directory clean

endif # "variables.mk" was not included
57 changes: 27 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ Experiments calling status-go from nim, inspired in [nim-stratus](https://github

* QT

install QT https://www.qt.io/download-qt-installer
Linux users should install Qt through the system's package manager:

```
# Debian/Ubuntu:
sudo apt install qtbase5-dev qtdeclarative5-dev qml-module-qt-labs-platform
```

If that's not possible, manually install QT from https://www.qt.io/download-qt-installer
and add it to the PATH

```
# Linux
export PATH=$PATH:/path/to/Qt/5.14.2/gcc_64/bin
Expand All @@ -18,51 +26,43 @@ export PATH=$PATH:/path/to/Qt/5.14.2/gcc_64/bin
export PATH=$PATH:/path/to/Qt/5.14.2/clang_64/bin
```

Linux users can also install Qt through the system's package manager:
* Go - (used to build status-go)

```
# Debian/Ubuntu:
sudo apt install qtbase5-dev qtdeclarative5-dev qml-module-qt-labs-platform
```

* go - (used to build status-go)

```
# linux
# Linux
<TODO>
# macos
# macOS
brew install go
```

### 1. Install QT, and add it to the PATH

```
# Linux
# Linux users should use their distro's package manager, but in case they do a manual install:
export PATH=$PATH:/path/to/Qt/5.14.2/gcc_64/bin
# macos
# macOS:
export PATH=$PATH:/path/to/Qt/5.14.2/clang_64/bin
```

### 2. Clone the repo and build `nim-status-client`
```
git clone https://github.com/status-im/nim-status-client/ --recurse-submodules
git clone https://github.com/status-im/nim-status-client
cd nim-status-client
make update
make
```

if you previously cloned the repo without the `--recurse-submodule` options, then do
For more output use `make V=1 ...`.

```
git submodule update --init --recursive
make
```
Use 4 CPU cores with `make -j4 ...`.

for more output use `make V=1`
Users with manually installed Qt5 packages need to run `make QTDIR="/path/to/Qt" ...`

**Trouble Shooting**:
**Troubleshooting**:

If the `make` command fails due to already installed homebrew packages, such as:
If the `make` command fails due to already installed Homebrew packages, such as:

```
Error: protobuf 3.11.4 is already installed
Expand All @@ -74,15 +74,12 @@ make: *** [vendor/status-go/build/bin/libstatus.a] Error 2
This can be fixed by uninstalling the package e.g. `brew uninstall protobuf` followed by rerunning `make`.


### 3. Setup Library Path
```
export LD_LIBRARY_PATH=vendor/DOtherSide/build/lib/
```

### 4. Run the app
### 3. Run the app

```
./bin/nim_status_client
make run
# or
LD_LIBRARY_PATH=vendor/DOtherSide/lib ./bin/nim_status_client
```

## Development
Expand All @@ -92,7 +89,7 @@ If making changes in the nim code `src/` then doing `make` again is needed (it's

## Cold Reload

### 5. "Cold" reload using VSCode
### "Cold" reload using VSCode

We can setup a "cold" reload, whereby the app will be rebuilt and restarted when changes in the source are saved. This will not save state, as the app will be restarted, but it will save us some time from manually restarting the app. We can handily force an app rebuild/relaunch with the shortcut `Cmd+Shift+b` (execute the default build task, which we'll setup below).

Expand Down
51 changes: 51 additions & 0 deletions config.nims
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
when defined(macosx):
import algorithm, strutils

if defined(release):
switch("nimcache", "nimcache/release/$projectName")
else:
switch("nimcache", "nimcache/debug/$projectName")

proc linkLib(name: string): string =
var resLib = name

when defined(macosx):
# In macOS Catalina, unversioned libraries may be broken stubs, so we need to
# find a versioned one: https://github.com/status-im/nim-status-client/pull/209
var matches: seq[string]
for path in listFiles("/usr/lib"):
# /usr/lib/libcrypto.0.9.8.dylib
let file = path[9..^1]
# libcrypto.0.9.8.dylib
if file.startsWith("lib" & name) and file != "lib" & name & ".dylib":
matches.add(path)
matches.sort(order = SortOrder.Descending)
if matches.len > 0:
resLib = matches[0]
# Passing "/usr/lib/libcrypto.44.dylib" directly to the linker works for
# dynamic linking.
return resLib

return "-l" & resLib

--threads:on
--opt:speed # -O3
--debugger:native # passes "-g" to the C compiler
--dynliboverrideall # don't use dlopen()
--define:ssl # needed by the stdlib to enable SSL procedures

if defined(macosx):
--tlsEmulation:off
# DYLD_LIBRARY_PATH doesn't seem to work with Qt5
switch("passL", "-rpath" & " " & getEnv("QT5_LIBDIR"))
switch("passL", "-lstdc++")
# dynamically link these libs, since we're opting out of dlopen()
switch("passL", linkLib("crypto"))
switch("passL", linkLib("ssl"))
# https://code.videolan.org/videolan/VLCKit/-/issues/232
switch("passL", "-Wl,-no_compact_unwind")
else:
switch("passL", linkLib("crypto") & " " & linkLib("ssl")) # dynamically link these libs, since we're opting out of dlopen()
switch("passL", "-Wl,-as-needed") # don't link libraries we're not actually using

--define:chronicles_line_numbers # useful when debugging
3 changes: 3 additions & 0 deletions nim.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# we need to link C++ libraries
gcc.linkerexe="g++"

4 changes: 2 additions & 2 deletions src/nim_status_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ proc mainProc() =

login.init(nodeAccounts)
engine.setRootContextProperty("loginModel", login.variant)

onboarding.init()
engine.setRootContextProperty("onboardingModel", onboarding.variant)

Expand All @@ -76,7 +76,7 @@ proc mainProc() =
signalController.addSubscriber(SignalType.DiscoverySummary, chat)
signalController.addSubscriber(SignalType.NodeLogin, login)
signalController.addSubscriber(SignalType.NodeLogin, onboarding)

engine.setRootContextProperty("signals", signalController.variant)

engine.load("../ui/main.qml")
Expand Down
9 changes: 0 additions & 9 deletions src/nim_status_client.nim.cfg

This file was deleted.

2 changes: 1 addition & 1 deletion vendor/DOtherSide

0 comments on commit 4fe6d9b

Please sign in to comment.