Skip to content

Commit

Permalink
Switch to CMAKE and add Windows Build Instructions (#45)
Browse files Browse the repository at this point in the history
* Oh no I broke the build

* update packages

* Upgrading to Lua 5.4 breaks my plugin at luaL_openlibs

* Man this kinda sucks

* checkpoint

* checkpoint

* Linux build WOMM

* Add version requirement for Xournalpp

* update cmake

* update cmakelists

* Fix Windows cmake script

* Get build working on Windows again. Need Lua 54. Version skew causes a segfault. Exiting the program also segfaults?

* Update Dockerfile and remove old targets from Makefile

* Update readme and add win_configure_path
  • Loading branch information
WillNilges authored Jan 1, 2025
1 parent 7a2dca1 commit f4daf33
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 45 deletions.
74 changes: 74 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
cmake_minimum_required(VERSION 3.22.1)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
PROJECT(inkpath)

# Send artifacts to /build/ImageTranscription. That will be the final artifact.
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ImageTranscription)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ImageTranscription)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ImageTranscription)

# Things work a little differently on Windows vs Linux.
if (WIN32)
message("Building for Windows")
set(INSTALL_DESTINATION "C:/Program Files/Xournal++/share/xournalpp/plugins")
ELSE()
# Need position-independent code flag enabled to make Lua work
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(INSTALL_DESTINATION /usr/share/xournalpp/plugins)
ENDIF()

# Define our sources
file(GLOB CV_SOURCES src/cv/*.cpp)
file(GLOB PLUGIN_SOURCES src/ipcv_obj/*.cpp)

# Locate dependent packages
FIND_PACKAGE(OpenCV REQUIRED)
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})

FIND_PACKAGE(Lua 5.4 REQUIRED)
INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR})

# We link OpenCV statically in Linux,
# but link totally dynamically and redistribute dlls in Windows
IF(WIN32)
# FIXME (wdn): Fix FIND_PACKAGE behavior for Lua on Windows
set(LUA_INCLUDE_DIR "C:/msys64/mingw64/include")
set(LUA_LIBRARIES "C:/msys64/mingw64/lib")

ADD_LIBRARY(inkpath SHARED ${CV_SOURCES} ${PLUGIN_SOURCES})
target_link_libraries(inkpath ${LUA_LIBRARIES}/liblua.a)
ELSE()
# Compile the CV component of Inkpath separately. This is mostly so that we
# can build our debug program and such.
ADD_LIBRARY(ipcv STATIC ${CV_SOURCES})
target_link_libraries(ipcv ${OpenCV_LIBRARIES})

# Compile plugin component of Inkpath.
ADD_LIBRARY(inkpath SHARED ${PLUGIN_SOURCES})
target_compile_options(inkpath PRIVATE)
target_link_libraries(inkpath ipcv)
ENDIF()

# OpenCV Gets linked the same way for both platforms
target_link_libraries(inkpath ${OpenCV_LIBRARIES})


# Copy the script and manifest into the build artifact
file(GLOB PLUGIN_FILES "${CMAKE_CURRENT_SOURCE_DIR}/plugin/*")
foreach(FILE ${PLUGIN_FILES})
file(COPY ${FILE} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endforeach()

IF(WIN32)
#add_custom_command(
# OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib
# COMMAND bash -c "echo chom && ldd ${LIBRARY_OUTPUT_NAME} | grep mingw64 | awk '{ print $3 }' | xargs -I {} cp {} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
#)

#install(CODE "execute_process(COMMAND ../scripts/copy_dlls.sh)")

install(CODE "execute_process(COMMAND bash \"${CMAKE_SOURCE_DIR}/scripts/copy_dlls.sh\")")
ENDIF()

# Finally, set an install target.
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} DESTINATION ${INSTALL_DESTINATION})
20 changes: 7 additions & 13 deletions HACKING/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
FROM docker.io/debian
FROM docker.io/debian:bookworm

RUN touch /root/.Xauthority
RUN apt-get update

# Line 10: Inkpath
# Line 11: Xournalpp
# Line 13: debugging tools
RUN apt-get install -y make liblua5.3-dev build-essential pkg-config libglib2.0-dev libpng-dev && \
apt-get install -y cmake libgtk-3-dev libpoppler-glib-dev portaudio19-dev libsndfile-dev \
dvipng texlive libxml2-dev libzip-dev librsvg2-dev gettext lua-lgi \
libgtksourceview-4-dev \
unzip git wget
# Inkpath, Xournalpp, and debugging tools
RUN apt-get -y update && apt-get install -y make liblua5.4-dev build-essential \
pkg-config libglib2.0-dev libpng-dev cmake libgtk-3-dev libpoppler-glib-dev \
portaudio19-dev libsndfile-dev dvipng texlive libxml2-dev libzip-dev \
librsvg2-dev gettext lua-lgi libgtksourceview-4-dev unzip git wget tmux gdb \
vim x11-apps tree nautilus eog clang-format

# Build and install OpenCV into the container
COPY ./build-opencv.sh .
Expand All @@ -20,6 +17,3 @@ RUN bash /build-opencv.sh 16
COPY ./build-xopp.sh .
RUN bash /build-xopp.sh 16

# Install dev tools
RUN apt-get update
RUN apt-get install --fix-missing -y tmux gdb vim x11-apps tree nautilus eog clang-format
42 changes: 15 additions & 27 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
CC=gcc
CXX=g++

# Warnings
WARNINGS = -Wall -Wextra -Wpedantic -Wconversion -Wformat=2 -Winit-self \
Expand All @@ -7,9 +8,11 @@ WARNINGS = -Wall -Wextra -Wpedantic -Wconversion -Wformat=2 -Winit-self \
-Wstrict-prototypes -Wwrite-strings
LIGHT_WARNINGS = -Wall
PLUGIN_NAME=ImageTranscription
SO_NAME=ipcvobj.so
LIB_NAME=inkpath.a
ARTIFACT=build/$(PLUGIN_NAME)
INSTALL_PATH=/usr/share/xournalpp/plugins/
XOPP_DEV_INSTALL_PATH=/xournalpp
LUA_VERSION=lua53
LUA_VERSION=lua54

.PHONY: clean install uninstall dev-install dev-uninstall

Expand All @@ -23,44 +26,29 @@ cv_deps=`pkg-config --cflags --libs --static opencv4`
build_dir:
@mkdir -p build

# Compiles and statically links Inkpath's OpenCV code to the necessary OpenCV libraries
ipcv: $(cv_source)
@mkdir -p build
g++ -c $(cv_source) $(lua_deps) $(cv_deps) -fPIC -static
@mv *.o build
ar -crsT build/libipcv.a build/*.o

# Compiles Inkpath's shared object library
lua-plugin: $(ip_source) ipcv
g++ $(LIGHT_WARNINGS) $(ip_source) -L./build -lipcv $(cv_deps) $(lua_deps) -g -fPIC -shared -o $(PLUGIN_NAME)/$(SO_NAME)

# Installs the plugin into your Xournalpp installation
# FIXME: Not smart enough to avoid re-building the app every time :(
install: lua-plugin
cp -r $(PLUGIN_NAME) /usr/share/xournalpp/plugins/

# Remove the plugin files from the xournalpp install dir
uninstall:
rm -rf /usr/share/xournalpp/plugins/$(PLUGIN_NAME)
rm -rf $(INSTALL_PATH)$(PLUGIN_NAME)

# Used to install the plugin into a source code repository of xournalpp
dev-install: lua-plugin
cp -r $(PLUGIN_NAME) $(XOPP_DEV_INSTALL_PATH)/plugins
cp -r HACKING/StrokeTest $(XOPP_DEV_INSTALL_PATH)/plugins
# TODO: Port to CMake
#dev-install: plugin
# cp -r $(ARTIFACT) $(XOPP_DEV_INSTALL_PATH)/plugins
# cp -r HACKING/StrokeTest $(XOPP_DEV_INSTALL_PATH)/plugins

# Remove the plugin from the development environment
dev-uninstall:
rm -rf $(XOPP_DEV_INSTALL_PATH)/plugins/$(PLUGIN_NAME)
rm -rf HACKING/StrokeTest $(XOPP_DEV_INSTALL_PATH)/plugins

# For generating a CV debugging binary
debug: $(cv_source)
mkdir -p build
g++ src/cv/debug/debug.cpp -DINKPATH_DEBUG $(cv_source) $(cv_deps) -static -o build/inkpath-debug
# TODO: Port to CMake
#debug: $(cv_source)
# mkdir -p build
# $(CXX) src/cv/debug/debug.cpp -DINKPATH_DEBUG $(cv_source) $(cv_deps) -static -o build/inkpath-debug

help:
@echo ipcv lua-plugin install uninstall dev-install dev-uninstall ipcv-debug
@echo uninstall dev-uninstall

clean:
rm -rf build
rm $(PLUGIN_NAME)/$(SO_NAME)
5 changes: 5 additions & 0 deletions PreLoad.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
IF (WIN32)
# Need to specify specific generator b/c building on MSYS2 MINGW64
set (CMAKE_GENERATOR "MinGW Makefiles" CACHE INTERNAL "" FORCE)
message("generator is set to ${CMAKE_GENERATOR}")
ENDIF()
58 changes: 55 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Xournal++ API. Unlike the previous implementation, this operates purely on raste

## Installation and Usage

Requires Xournalpp >=1.2.0

Inkpath is packaged as a statically-linked `.so` file coupled with a Lua script,
so you should be able to download the release from the [releases page](https://github.com/WillNilges/inkpath/releases)
and have it Just Work™.
Expand All @@ -42,15 +44,38 @@ in order to get them._

_Inkpath is coming to a package manager near you soon™!_

## Manual Installation
### Installation on Windows

1. Download the latest release of [ImageTranscription-win.zip](https://github.com/WillNilges/inkpath/releases/)

2. Unzip the archive and copy ImageTranscription/ to the plugin path:

`C:\Program Files\Xournal++\share\xournalpp\plugins\ImageTranscription`

3. Run install.ps1 to update the user Path

4. Run Xournal++ and enjoy

#### To Uninstall

1. Delete `C:\Program Files\Xournal++\share\xournalpp\plugins\ImageTranscription`

2. Remove environment variable

- Type `Win+R` and type `sysdm.cpl`
- Go to Advanced > Enviornment Variables > Path > Edit
- Delete ImageTranscription entry
- Press OK until all dialogs are closed

## Compiling

### Arch

```BASH
# Install dependencies
pacman -S \
cmake gtk3 base-devel libxml2 portaudio libsndfile \
poppler-glib texlive-bin texlive-pictures gettext libzip lua53 lua53-lgi \
poppler-glib texlive-bin texlive-pictures gettext libzip lua54 lua54-lgi \
gtksourceview4 wget unzip git tmux

# Build openCV
Expand All @@ -62,7 +87,7 @@ gtksourceview4 wget unzip git tmux
```BASH
# Install dependencies
apt -y install \
make liblua5.3-dev build-essential pkg-config libglib2.0-dev libpng-dev \
make liblua5.4-dev build-essential pkg-config libglib2.0-dev libpng-dev \
cmake libgtk-3-dev libpoppler-glib-dev portaudio19-dev libsndfile-dev \
dvipng texlive libxml2-dev libzip-dev librsvg2-dev gettext lua-lgi \
libgtksourceview-4-dev git gdb x11-apps wget unzip
Expand All @@ -72,3 +97,30 @@ make install
```

<img src="https://forthebadge.com/images/badges/works-on-my-machine.svg" alt="C badge" height="30px"/>

### Windows

1. Install MSYS2

2. Open MSYS2 MINGW64 shell

3. Install dependencies

```
pacman -S \
mingw-w64-x86_64-cmake mingw-w64-x86_64-gtk3 base-devel libxml2 mingw-w64-x86_64-portaudio mingw-w64-x86_64-libsndfile mingw-w64-x86_64-poppler mingw-w64-x86_64-libzip mingw-w64-x86_64-lua53 mingw-w64-x86_64-lua53-lgi mingw-w64-x86_64-gtksourceview4 mingw-w64-x86_64-opencv wget unzip git tmux
```

4. Launch MSYS2 MINGW64 shell as Administrator, and use `cmake` to build and
run post-build script to gather dependencies and assemble the plugin

```
mkdir build
cd build
cmake .. # Use ${MINGW_PREFIX}/bin/cmake if normal cmake doesn't work
mingw32-make.exe install
```

6. Run scripts/win_configure_path.ps1 to update the user Path

7. Run Xournal++ and enjoy
7 changes: 6 additions & 1 deletion ImageTranscription/main.lua → plugin/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ end
-- Callback if the menu item is executed
function drawStroke()
print("Inkpath Activated. Transcribing image....")
local inkpath = assert(package.loadlib("/usr/share/xournalpp/plugins/ImageTranscription/ipcvobj.so", "luaopen_ipcvobj"))
-- Inkpath is installed differently depending on Windows vs Unix platforms
local library_path = package.config:sub(1,1) == "\\" and [[C:\Program Files\Xournal++\share\xournalpp\plugins\ImageTranscription\libinkpath.dll]] or "/usr/share/xournalpp/plugins/ImageTranscription/libinkpath.so"
print("Loading Library...")
local inkpath = assert(package.loadlib(library_path, "luaopen_ipcvobj"))
print("Initializing inkpath()")
inkpath()
print("Initialized inkpath()")
local path = app.getFilePath({'*.jpg', '*.png', '*.bmp'})
-- Floating point value to scale stroke data coordinates. 0.1x is usually
-- necessary to cleanly map strokes to the document
Expand Down
File renamed without changes.
5 changes: 5 additions & 0 deletions scripts/copy_dlls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

INKPATH_LIB=libinkpath.dll
echo "Copying $INKPATH_LIB dependencies..."
ldd ImageTranscription/$INKPATH_LIB | grep mingw64 | awk '{ print $3 }' | xargs -I {} cp {} ./ImageTranscription
16 changes: 16 additions & 0 deletions scripts/win_configure_path.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Inkpath stores its dependencies in the plugin folder on Windows. To make this work, we need to update the path to allow Xournal++ to see the dependencies, so we use this Powershell script to do that.

$inkpathLibPath = "C:\Program Files\Xournal++\share\xournalpp\plugins\ImageTranscription"

$userPath = [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::User)

if (-not ($userPath -split ";" | ForEach-Object { $_.Trim() } | Where-Object { $_ -eq $inkpathLibPath })) {
$newPath = $userPath + ";" + $inkpathLibPath
[Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::User)
Write-Host "Configured Path."
} else {
Write-Host "Path already updated."
}

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
3 changes: 2 additions & 1 deletion src/ipcv_obj/ipcv_obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ static void register_ipcvobj(lua_State* L) {

extern "C" {
// Program entry
int luaopen_ipcvobj(lua_State* L) {
WINEXPORT int luaopen_ipcvobj(lua_State* L) {
printf("Entered Inkpath.");
luaL_openlibs(L);
register_ipcvobj(L);
return 1;
Expand Down
8 changes: 8 additions & 0 deletions src/ipcv_obj/ipcv_obj.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#ifndef IPCV_OBJ
#define IPCV_OBJ

#ifdef _WIN32
#define WINEXPORT __declspec(dllexport)
#else
#define WINEXPORT
#endif

/*
* This is a barebones-af interface for allowing Lua to get data directly™ from
* OpenCV
Expand Down Expand Up @@ -46,4 +52,6 @@ static int ipcvobj_getContourLength(lua_State* L);
// Receiving data
static int ipcvobj_getContour(lua_State* L);

extern "C" WINEXPORT int luaopen_ipcvobj(lua_State *L);

#endif

0 comments on commit f4daf33

Please sign in to comment.