Windows support

This commit is contained in:
Robert Bendun 2022-10-08 20:32:41 +02:00
parent ecabf885f3
commit e8ef207ec9
8 changed files with 95 additions and 42 deletions

View File

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `scan` builtin, which computes prefix sum of passed values when provided with addition operator
* Added [rtmidi](https://github.com/thestk/rtmidi/) dependency which should provide multiplatform MIDI support
* Support for Windows (with only basic REPL)
### Changed

View File

@ -8,11 +8,12 @@ all: bin/musique
include scripts/debug.mk
include scripts/release.mk
include scripts/test.mk
include scripts/windows.mk
# http://www.music.mcgill.ca/~gary/rtmidi/#compiling
bin/rtmidi.o: lib/rtmidi/RtMidi.cpp lib/rtmidi/RtMidi.h
@echo "CXX $@"
@$(CXX) $< -c -O2 -o $@ -D__WINDOWS_MM__
@$(CXX) $< -c -O2 -o $@ $(CPPFLAGS)
doc: Doxyfile musique/*.cc musique/*.hh
doxygen

View File

@ -21,9 +21,8 @@ $ sudo apt install -y build-essential libasound2-dev
## Budowanie interpretera
```console
$ make bin/musique
```
- Aby wybudować wersję Linux+ALSA: `make`
- Aby wybudować wersję Windows: `make os=windows`
Żeby zainstalować interpreter języka Musique w systemie, należy dodatkowo wykonać polecenie:
@ -38,6 +37,7 @@ $ make bin/musique
- `make` - Buduje interpreter `bin/musique` (tryb release)
- `make debug` - Buduje interpreter `bin/debug/musique` (tryb debug)
- `make clean` - Usuwa reprodukowalne elementy projektu (automatycznie stworzone pliki binarne czy raporty)
### Dokumentacja
- `make doc` - Tworzy `doc/build/html/` zawierający dokumentację projektu
@ -45,28 +45,6 @@ $ make bin/musique
### Testowanie
- `make test` - Uruchom wszystkie dostępne testy automatyczne
- `scripts/test.py test examples` - Uruchamia testy zachowań przykładów
- `scripts/test.py record examples` - Nagrywa testy zachowań przykładów
### Debugowanie
- `scripts/log-function-calls.sh` - Tworzy listę wywołań funkcji używając GDB
## Budowa projektu
```
.
├── bin Miejsce produkcji plików wykonywalnych
├── doc Dokumentacja języka, interpretera
│   └── build Miejsce produkcji dokumentacji
├── editor Pluginy do edytorów dodające wsparcie dla języka
├── lib Zewnętrzne zależności projektu
│   ├── expected
│   └── ut
└── include Główny katalog z plikami nagłówkowymi
├── scripts Skrypty wspierające budowanie i tworzenie
└── src Główny katalog z plikami źródłowymi
```
## Kolorowanie składni

View File

@ -2,12 +2,21 @@ MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)"
CXXFLAGS:=$(CXXFLAGS) -std=c++20 -Wall -Wextra -Werror=switch -Werror=return-type -Werror=unused-result -Wno-maybe-uninitialized
CPPFLAGS:=$(CPPFLAGS) -Ilib/expected/ -I. -Ilib/bestline/ -Ilib/rtmidi/
LDFLAGS=-flto
LDLIBS= -lpthread -static-libgcc -static-libstdc++
RELEASE_FLAGS=-O2
DEBUG_FLAGS=-O0 -ggdb -fsanitize=undefined -DDebug
ifeq ($(os),windows)
CC=i686-w64-mingw32-gcc
CXX=i686-w64-mingw32-g++
CPPFLAGS:=$(CPPFLAGS) -D__WINDOWS_MM__
LDLIBS:=-lwinmm $(LDLIBS)
else
CC=gcc
CXX=g++
CPPFLAGS:=$(CPPFLAGS) -D __LINUX_ALSA__
LDLIBS:=-lasound $(LDLIBS)
endif
LDFLAGS=-flto
LDLIBS=-lwinmm -lpthread -static-libgcc -static-libstdc++

View File

@ -16,6 +16,16 @@
#include <musique/try.hh>
#include <musique/unicode.hh>
#ifdef _WIN32
extern "C" {
#include <io.h>
}
#else
extern "C" {
#include <bestline.h>
}
#endif
namespace fs = std::filesystem;
static bool ast_only_mode = false;
@ -190,12 +200,27 @@ struct Runner
/// some of the strings are only views into source
std::vector<std::string> eternal_sources;
#ifndef _WIN32
void completion(char const* buf, bestlineCompletions *lc)
{
std::string_view in{buf};
for (auto scope = Runner::the->interpreter.env.get(); scope != nullptr; scope = scope->parent.get()) {
for (auto const& [name, _] : scope->variables) {
if (name.starts_with(in)) {
bestlineAddCompletion(lc, name.c_str());
}
}
}
}
#endif
bool is_tty()
{
#ifdef __linux__
return isatty(STDOUT_FILENO);
#ifdef _WIN32
return _isatty(STDOUT_FILENO);
#else
return true;
return isatty(STDOUT_FILENO);
#endif
}
@ -306,13 +331,29 @@ static std::optional<Error> Main(std::span<char const*> args)
if (runnables.empty() || enable_repl) {
repl_line_number = 1;
enable_repl = true;
#ifndef _WIN32
bestlineSetCompletionCallback(completion);
#else
std::vector<std::string> repl_source_lines;
#endif
for (;;) {
std::string_view raw;
if (auto s = new std::string{}; std::getline(std::cin, *s)) {
raw = *s;
#ifndef _WIN32
char const* input_buffer = bestlineWithHistory("> ", "musique");
if (input_buffer == nullptr) {
break;
}
#else
std::cout << "> " << std::flush;
char const* input_buffer;
if (std::string s{}; std::getline(std::cin, s)) {
repl_source_lines.push_back(std::move(s));
input_buffer = repl_source_lines.back().c_str();
} else {
break;
}
#endif
// Raw input line used for execution in language
std::string_view raw = input_buffer;
// Used to recognize REPL commands
std::string_view command = raw;
@ -320,6 +361,11 @@ static std::optional<Error> Main(std::span<char const*> args)
if (command.empty()) {
// Line is empty so there is no need to execute it or parse it
#ifndef _WIN32
free(const_cast<char*>(input_buffer));
#else
repl_source_lines.pop_back();
#endif
continue;
}

View File

@ -16,13 +16,14 @@ fi
mkdir -p "$Target"
if ! [ -f bin/musique ]; then
make bin/musique
fi
echo "Copy bin/musique, examples, license and documentation"
make clean && make bin/musique
cp bin/musique "$Target"/
make clean && make bin/musique os=windows
cp bin/musique.exe "$Target"/
echo "Copy examples, license and documentation"
cp LICENSE "$Target"/LICENSE
cp CHANGELOG.md "$Target/CHANGELOG.md"
cp -r examples "$Target"/examples

View File

@ -1,9 +1,15 @@
ifneq ($(os),windows)
Release_Obj=$(addprefix bin/,$(Obj))
bin/bestline.o: lib/bestline/bestline.c lib/bestline/bestline.h
@echo "CC $@"
@$(CC) $< -c -O3 -o $@
bin/%.o: musique/%.cc
@echo "CXX $@"
@$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(CPPFLAGS) -o $@ $< -c
bin/musique: $(Release_Obj) bin/main.o bin/rtmidi.o
bin/musique: $(Release_Obj) bin/main.o bin/rtmidi.o bin/bestline.o
@echo "CXX $@"
@$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(CPPFLAGS) -o $@ $(Release_Obj) bin/rtmidi.o $(LDFLAGS) $(LDLIBS)
@$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(CPPFLAGS) -o $@ $(Release_Obj) bin/rtmidi.o bin/bestline.o $(LDFLAGS) $(LDLIBS)
endif

11
scripts/windows.mk Normal file
View File

@ -0,0 +1,11 @@
ifeq ($(os),windows)
Release_Obj=$(addprefix bin/,$(Obj))
bin/%.o: musique/%.cc
@echo "CXX $@"
@$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(CPPFLAGS) -o $@ $< -c
bin/musique: $(Release_Obj) bin/main.o bin/rtmidi.o
@echo "CXX $@"
@$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(CPPFLAGS) -o $@ $(Release_Obj) bin/rtmidi.o $(LDFLAGS) $(LDLIBS)
endif