Make native library easier to build/use

Makes libtsm a static library rather than dynamic so that it doesn't
have to be installed as a system library on the user's operating system.

Also updates SConstruct to work on more operating systems other than
just NixOS. Adds a number of docker files for building the library on
various distributions (NixOS, Arch Linux, Ubuntu).

Uses a fork of godot-cpp with an updated godot_headers submodule that
includes godotengine/godot_headers#76. We should go back to tracking
https://github.com/godotengine/godot-cpp once the submodule has
been updated in that repo.
This commit is contained in:
Leroy Hopson 2020-07-13 11:14:30 +07:00
parent 78eeacdc22
commit d8c8b5b272
30 changed files with 489 additions and 157 deletions

5
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "addons/godot_xterm_native/godot-cpp"]
path = addons/godot_xterm_native/godot-cpp
url = https://github.com/GodotNativeTools/godot-cpp
url = https://github.com/lihop/godot-cpp
[submodule "addons/godot_xterm_native/libtsm"]
path = addons/godot_xterm_native/libtsm
url = https://github.com/Aetf/libtsm

View file

@ -1,11 +1,17 @@
env:
- RUN_FULL_CODEPOINT_TESTS=true
language: nix
services:
- docker
install:
- docker pull barichello/godot-ci
jobs:
include:
- name: "Run tests"
env: SERVICE=tests
- name: "Build native on Arch Linux"
env: SERVICE=build-archlinux
- name: "Build native on NixOS"
env: SERVICE=build-nixos
- name: "Build native on Ubuntu"
env: SERVICE=build-ubuntu
script:
- docker run -v $(pwd):/src -e RUN_FULL_CODEPOINT_TESTS="${RUN_FULL_CODEPOINT_TESTS}" barichello/godot-ci godot --path /src -s addons/gut/gut_cmdln.gd
script: docker-compose run $SERVICE

View file

@ -6,6 +6,14 @@
![Godot Version](https://img.shields.io/badge/godot-3.2+-blue.svg)
![License](https://img.shields.io/badge/license-MIT-green.svg)
Native implementation of Godot Xterm using GDNative with [libtsm](https://github.com/Aetf/libtsm).
## Demo
Click the thumbnail to watch a demo video on youtube:
[![Demo video thumbnail](https://img.youtube.com/vi/_Tt4eQEBybo/0.jpg)](https://www.youtube.com/watch?v=_Tt4eQEBybo)
## License
If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license.
@ -14,4 +22,4 @@ You are also implicitly verifying that all code is your original work, or unorig
Copyright (c) 2020 Leroy Hopson (MIT License)
The fonts used in this project are published under a seperate license.
See: [addons/godot_xterm_native/fonts/LICENSE](addons/godot_xterm_native/fonts/LICENSE).
See: [addons/godot_xterm_native/fonts/LICENSE.txt](addons/godot_xterm_native/fonts/LICENSE.txt).

359
addons/godot_xterm_native/.gitignore vendored Normal file
View file

@ -0,0 +1,359 @@
# Godot auto generated files
*.gen.*
.import/
# Documentation generated by doxygen or from classes.xml
doc/_build/
# Javascript specific
*.bc
# CLion
cmake-build-debug
# Android specific
.gradle
local.properties
*.iml
.idea
.gradletasknamecache
project.properties
platform/android/java/app/libs/*
platform/android/java/libs/*
platform/android/java/lib/.cxx/
# General c++ generated files
*.lib
*.o
*.ox
*.a
*.ax
*.d
*.so
*.os
*.Plo
*.lo
# Libs generated files
.deps/*
.dirstamp
# Gprof output
gmon.out
# Vim temp files
*.swo
*.swp
# Qt project files
*.config
*.creator
*.creator.*
*.files
*.includes
*.cflags
*.cxxflags
# Code::Blocks files
*.cbp
*.layout
*.depend
# Eclipse CDT files
.cproject
.settings/
*.pydevproject
*.launch
# Geany/geany-plugins files
*.geany
.geanyprj
# Jetbrains IDEs
.idea/
# Misc
.DS_Store
__MACOSX
logs/
# for projects that use SCons for building: http://http://www.scons.org/
.sconf_temp
.sconsign*.dblite
*.pyc
# https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
*.sln
*.vcxproj*
# Custom SCons configuration override
/custom.py
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
x64/
build/
bld/
[Oo]bj/
*.debug
*.dSYM
# Visual Studio cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# Hints for improving IntelliSense, created together with VS project
cpp.hint
#NUNIT
*.VisualState.xml
TestResult.xml
*.o
*.a
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.bak
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
*.nib
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.opendb
*.VC.VC.opendb
enc_temp_folder/
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# CodeLite project files
*.project
*.workspace
.codelite/
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/*
## TODO: If the tool you use requires repositories.config, also uncomment the next line
#!packages/repositories.config
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
__pycache__/
# KDE
.directory
#Kdevelop project files
*.kdev4
# Xcode
xcuserdata/
*.xcscmblueprint
*.xccheckout
*.xcodeproj/*
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# =========================
# Windows detritus
# =========================
# Windows image file caches
[Tt]humbs.db
[Tt]humbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Windows stackdumps
*.stackdump
# Windows shortcuts
*.lnk
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
logo.h
*.autosave
# https://github.com/github/gitignore/blob/master/Global/Tags.gitignore
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
TAGS
!TAGS/
tags
*.tags
!tags/
gtags.files
GTAGS
GRTAGS
GPATH
cscope.files
cscope.out
cscope.in.out
cscope.po.out
godot.creator.*
projects/
platform/windows/godot_res.res
# Visual Studio 2017 and Visual Studio Code workspace folder
/.vs
/.vscode
# Visual Studio Code workspace file
*.code-workspace
# Scons construction environment dump
.scons_env.json
# Scons progress indicator
.scons_node_count
# ccls cache (https://github.com/MaskRay/ccls)
.ccls-cache/
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
compile_commands.json
# Cppcheck
*.cppcheck

View file

@ -1,14 +0,0 @@
{
"configurations": [
{
"name": "Linux",
"includePath": ["${workspaceFolder}/**"],
"defines": [],
"compilerPath": "/nix/store/l2sqva7kzr8y68lji2aajk2s8017jyq4-gcc-wrapper-8.3.0/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}

View file

@ -1 +0,0 @@
/nix/store/c4l4iva7dm7fpfx8y3jb6hdzlsm1cvmj-libvterm-neovim-0.1.3/include/vterm.h

View file

@ -1 +0,0 @@
/nix/store/c4l4iva7dm7fpfx8y3jb6hdzlsm1cvmj-libvterm-neovim-0.1.3/include/vterm_keycodes.h

View file

@ -1,50 +0,0 @@
{
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"typeinfo": "cpp",
"filesystem": "cpp"
},
"nixEnvSelector.nixShellConfig": "${workspaceRoot}/default.nix"
}

View file

@ -1,16 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "nix-shell --run 'scons platform=linux -j12'",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View file

View file

@ -6,6 +6,9 @@ opts = Variables([], ARGUMENTS)
# Gets the standard flags CC, CCX, etc.
env = DefaultEnvironment()
# Add PATH to environment so scons can find commands such as g++, etc.
env.AppendENVPath('PATH', os.getenv('PATH'))
# Define our options
opts.Add(EnumVariable('target', "Compilation target", 'debug', ['d', 'debug', 'r', 'release']))
opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx']))
@ -18,6 +21,7 @@ opts.Add(PathVariable('target_name', 'The library name.', 'libgodotxtermnative',
godot_headers_path = "godot-cpp/godot_headers/"
cpp_bindings_path = "godot-cpp/"
cpp_library = "libgodot-cpp"
libtsm_path = "libtsm/"
# only support 64 at this time..
bits = 64
@ -30,8 +34,8 @@ if env['use_llvm']:
env['CC'] = 'clang'
env['CXX'] = 'clang++'
else:
env['CC'] = '/home/leroy/.nix-profile/bin/gcc'
env['CXX'] = '/home/leroy/.nix-profile/bin/g++'
env['CC'] = 'gcc'
env['CXX'] = 'g++'
if env['p'] != '':
env['platform'] = env['p']
@ -64,7 +68,6 @@ elif env['platform'] in ('x11', 'linux'):
env['target_path'] += 'x11/'
cpp_library += '.linux'
env.Append(CCFLAGS=['-fPIC', '-shared'])
env.Append(CCFLAGS=os.environ['NIX_CFLAGS_COMPILE'])
env.Append(CXXFLAGS=['-std=c++17', '-shared', '-pthread'])
if env['target'] in ('debug', 'd'):
env.Append(CCFLAGS=['-g3', '-Og'])
@ -96,8 +99,8 @@ else:
cpp_library += '.' + str(bits)
# make sure our binding library is properly includes
env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/'])
env.Append(LIBPATH=[cpp_bindings_path + 'bin/'] + os.environ['LD_LIBRARY_PATH'].split(':'))
env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', libtsm_path + 'src/tsm'])
env.Append(LIBPATH=[cpp_bindings_path + 'bin/', libtsm_path + 'build/src/tsm'])
env.Append(LIBS=[cpp_library, 'tsm', 'util']) # Note util used by pseudoterminal, tsm used by terminal.
# tweak this if you want to use different folders, or more folders, to store your source code in.

View file

@ -0,0 +1,2 @@
*
!.gitignore

View file

@ -0,0 +1,27 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash --pure -p binutils.bintools cmake scons
# Make sure we are in the addons/godot_xterm_native directory
cd ${BASH_SOURCE%/*}
# Initialize godot-cpp
if [ ! -d "godot-cpp/bin" ]
then
cd godot-cpp
scons platform=linux generate_bindings=yes -j12
cd ..
fi
# Build libtsm
if [ ! -f "libtsm/build/src/tsm/libtsm.a" ]
then
cd libtsm
mkdir -p build
cd build
cmake -DBUILD_SHARED_LIBS=n ..
make
cd ../..
fi
# Build godotxtermnative
scons platform=linux

View file

@ -1,20 +0,0 @@
with import /home/leroy/nixpkgs { overlays = [ (import ./overlay.nix) ]; };
stdenv.mkDerivation rec {
name = "systemnauts";
buildInputs = [
gcc
scons
libaudit
libvterm
libtsm
];
enablePrallelBuilding = true;
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
libaudit
libvterm
libtsm
];
}

@ -1 +1 @@
Subproject commit 9eceb16f0553884094d0f659461649be5d333866
Subproject commit 20d57e6cf5d0353de0905f4edd3697b6de32bc74

@ -0,0 +1 @@
Subproject commit f70e37982f382b03c6939dac3d5f814450bda253

View file

@ -1,19 +0,0 @@
self: super:
{
libtsm = super.libtsm.overrideAttrs (oldAttrs: {
src = super.fetchFromGitHub {
owner = "Aetf";
repo = "libtsm";
rev = "a5a9ea0c23b28aa2c9cf889105b75981fdebbc25";
sha256 = "0hqb0fjh5cwr2309sy2626ghhbnx7g64s8f3qqyvk7j8aysxgggh";
};
nativeBuildInputs = with super; [ cmake gtk3 cairo pango libxkbcommon pkgconfig ];
dontDisableStatic = true;
});
libaudit = super.libaudit.overrideAttrs (oldAttrs: { dontDisableStatic = true; });
libvterm = super.libvterm-neovim.overrideAttrs (oldAttrs: { dontDisableStatic = true; });
}

View file

@ -1,6 +1,7 @@
#include "pseudoterminal.h"
#include <pty.h>
#include <unistd.h>
#include <termios.h>
using namespace godot;
@ -36,6 +37,14 @@ void Pseudoterminal::process_pty()
should_process_pty = true;
struct termios termios = {};
termios.c_iflag = IGNPAR | ICRNL;
termios.c_oflag = 0;
termios.c_cflag = B38400 | CRTSCTS | CS8 | CLOCAL | CREAD;
termios.c_lflag = ICANON;
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
pid_t pty_pid = forkpty(&fd, NULL, NULL, NULL);
if (pty_pid == -1)
@ -71,13 +80,27 @@ void Pseudoterminal::process_pty()
FD_SET(fd, &write_fds);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
ready = select(fd + 1, &read_fds, &write_fds, NULL, &timeout);
if (ready > 0)
{
if (FD_ISSET(fd, &write_fds))
{
std::lock_guard<std::mutex> guard(write_buffer_mutex);
if (bytes_to_write > 0)
{
write(fd, write_buffer, bytes_to_write);
Godot::print(String("wrote {0} bytes").format(Array::make(bytes_to_write)));
bytes_to_write = 0;
}
}
if (FD_ISSET(fd, &read_fds))
{
std::lock_guard<std::mutex> guard(read_buffer_mutex);
@ -85,8 +108,9 @@ void Pseudoterminal::process_pty()
int ret;
int bytes_read = 0;
bytes_read = read(fd, read_buffer, 1);
bytes_read = read(fd, read_buffer, MAX_READ_BUFFER_LENGTH);
// TODO: handle error (-1)
if (bytes_read <= 0)
continue;
@ -112,19 +136,7 @@ void Pseudoterminal::process_pty()
if (bytes_read > 0)
{
Godot::print(String("read {0} bytes").format(Array::make(bytes_read)));
}
}
if (FD_ISSET(fd, &write_fds))
{
std::lock_guard<std::mutex> guard(write_buffer_mutex);
if (bytes_to_write > 0)
{
write(fd, write_buffer, bytes_to_write);
bytes_to_write = 0;
//Godot::print(String("read {0} bytes").format(Array::make(bytes_read)));
}
}
}

View file

@ -13,15 +13,19 @@ class Pseudoterminal : public Node
{
GODOT_CLASS(Pseudoterminal, Node)
public:
static const int MAX_READ_BUFFER_LENGTH = 1024;
static const int MAX_WRITE_BUFFER_LENGTH = 1024;
private:
std::thread pty_thread;
bool should_process_pty;
char write_buffer[4096];
char write_buffer[MAX_WRITE_BUFFER_LENGTH];
int bytes_to_write;
std::mutex write_buffer_mutex;
char read_buffer[4096];
char read_buffer[MAX_READ_BUFFER_LENGTH];
int bytes_to_read;
std::mutex read_buffer_mutex;

24
docker-compose.yml Normal file
View file

@ -0,0 +1,24 @@
version: "3.3"
services:
tests:
image: barichello/godot-ci:3.2.2
environment:
- RUN_FULL_CODEPOINT_TESTS=true
volumes:
- .:/src
command: godot --path /src -s addons/gut/gut_cmdln.gd
build-archlinux:
build:
context: .
dockerfile: ./dockerfiles/archlinux
command: bash /src/addons/godot_xterm_native/build.sh
build-nixos:
build:
context: .
dockerfile: ./dockerfiles/nixos
command: /src/addons/godot_xterm_native/build.sh
build-ubuntu:
build:
context: .
dockerfile: ./dockerfiles/ubuntu
command: bash /src/addons/godot_xterm_native/build.sh

3
dockerfiles/archlinux Normal file
View file

@ -0,0 +1,3 @@
FROM archlinux:20200908
RUN pacman -Sy --needed --noconfirm base-devel cmake scons
COPY . /src

2
dockerfiles/nixos Normal file
View file

@ -0,0 +1,2 @@
FROM lnl7/nix:2.3.6
COPY . /src

4
dockerfiles/ubuntu Normal file
View file

@ -0,0 +1,4 @@
FROM ubuntu:18.04
RUN apt-get update -y
RUN apt-get install -y build-essential cmake python3 scons
COPY . /src

View file

@ -15,7 +15,6 @@ onready var viewport = get_viewport()
func _ready():
$Pseudoterminal.connect("data_received", $Terminal, "write")
$Pseudoterminal.connect("data_received", self, "_on_data_received")
viewport.connect("size_changed", self, "_resize")
_resize()
@ -51,10 +50,6 @@ func _input(event):
$Pseudoterminal.put_data(data)
func _on_data_received(data: PoolByteArray):
print("Got data: %s" % data.get_string_from_utf8())
func _resize():
rect_size = viewport.size
$Terminal.rect_size = rect_size

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 4 KiB