1
0
mirror of https://github.com/janet-lang/janet synced 2025-11-04 17:43:02 +00:00

Compare commits

..

26 Commits

Author SHA1 Message Date
Calvin Rose
26513a7a16 Update changelog 2019-05-30 19:33:09 -04:00
Calvin Rose
d005ac6888 Appease MSVC. 2019-05-30 19:21:11 -04:00
Calvin Rose
7fdb098a20 Add process.h. 2019-05-30 19:14:54 -04:00
Calvin Rose
a4a200e037 Spawn.h not found in windows. 2019-05-30 19:13:13 -04:00
Calvin Rose
15d95d8803 Windows include issue. 2019-05-30 18:50:52 -04:00
Calvin Rose
46950a8cb3 Convert os/execute to use posix_spawn. 2019-05-30 18:40:10 -04:00
Calvin Rose
4867cab569 Correct changelog date. 2019-05-29 22:21:06 -04:00
Calvin Rose
c8cf7c2445 Appease MSVC. 2019-05-29 22:12:24 -04:00
Calvin Rose
1b63215aad Remove extra functions. 2019-05-29 22:00:47 -04:00
Calvin Rose
bcbe42ab23 Add API version checking for modules.
Checking now actively implemented for dynamic modules
in a fully backwards compatible way.
2019-05-29 21:58:20 -04:00
Calvin Rose
c8c6419013 Update installer again. 2019-05-29 19:48:31 -04:00
Calvin Rose
e8516c29e0 Update installer and jpm to work better on windows. 2019-05-29 19:01:12 -04:00
Calvin Rose
12247bd958 Update installer. 2019-05-29 17:48:46 -04:00
Calvin Rose
9d30d5f6e3 Update installer. 2019-05-29 13:02:15 -04:00
Calvin Rose
ba0956488d Prepare for 0.6.0 release 2019-05-29 12:19:39 -04:00
Calvin Rose
31f502b508 Add more to util.h to help with amalg build. 2019-05-29 12:07:53 -04:00
Calvin Rose
efaaead378 Update changelog 2019-05-29 11:58:41 -04:00
Calvin Rose
4d47d92a4a Windows WEXITSTATUS fix? 2019-05-29 11:53:57 -04:00
Calvin Rose
b39ad97a87 Fix up close to return proper exit code. 2019-05-29 11:50:46 -04:00
Calvin Rose
af23040d9c file/close returns an integer.
If opened with popen, returns the exit code. Otherwise
returns nil.
2019-05-29 11:40:58 -04:00
Calvin Rose
fd2d706e33 Add os/remove. 2019-05-29 11:31:19 -04:00
Calvin Rose
178d175bcf Update options for jpm and path stuff. 2019-05-29 11:04:38 -04:00
Calvin Rose
7a7f586094 Merge branch 'master' of github.com:janet-lang/janet 2019-05-28 23:03:08 -04:00
Calvin Rose
5124587c96 Merge pull request #114 from andrewchambers/configcheck
Add api for checking build compatibilty.
2019-05-28 23:02:08 -04:00
Calvin Rose
6c897b1a37 Add default for bindir. 2019-05-28 22:41:47 -04:00
Andrew Chambers
3c304ddc35 Add api for checking build compatibilty. 2019-05-28 13:51:40 +12:00
10 changed files with 324 additions and 157 deletions

View File

@@ -1,8 +1,15 @@
# Changelog
All notable changes to this project will be documented in this file.
## 0.6.0 - ??
## Unreleased
- Add API compatibility checking for modules. This will let native modules not load
when the host program is not of a compatible version or configuration.
- Change signature of `os/execute` to be much more flexible.
## 0.6.0 - 2019-05-29
- `file/close` returns exit code when closing file opened with `file/popen`.
- Add `os/rename`
- Update windows installer to include tools like `jpm`.
- Add `jpm` tool for building and managing projects.
- Change interface to `cook` tool.
- Add optional filters to `module/paths` to further refine import methods.
@@ -81,7 +88,7 @@ All notable changes to this project will be documented in this file.
- Disallow NaNs as table or struct keys
- Update module resolution paths and format
## 0.3.0 - 2019-26-01
## 0.3.0 - 2019-01-26
- Add amalgamated build to janet for easier embedding.
- Add os/date function
- Add slurp and spit to core library.

View File

@@ -1,20 +1,31 @@
# Version
!define VERSION "0.6.0"
!define PRODUCT_VERSION "${VERSION}.0"
VIProductVersion "${PRODUCT_VERSION}"
VIFileVersion "${PRODUCT_VERSION}"
# Use the modern UI
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "Software\Janet\${VERSION}"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME ""
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\Janet\${VERSION}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
!define MULTIUSER_INSTALLMODE_INSTDIR "Janet-${VERSION}"
!include "MultiUser.nsh"
!include "MUI2.nsh"
!include ".\tools\EnvVarUpdate.nsh"
# Basics
Name "Janet"
OutFile "janet-installer.exe"
OutFile "janet-v${VERSION}-windows-installer.exe"
# Some Configuration
!define APPNAME "Janet"
!define DESCRIPTION "The Janet Programming Language"
!define HELPURL "http://janet-lang.org"
BrandingText "Janet Installer"
BrandingText "The Janet Programming Language"
# MUI Configuration
!define MUI_ICON "assets\icon.ico"
@@ -22,31 +33,32 @@ BrandingText "Janet Installer"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "assets\janet-w200.png"
!define MUI_HEADERIMAGE_RIGHT
!define MUI_ABORTWARNING
# Show a welcome page first
!insertmacro MUI_PAGE_WELCOME
# License page
!insertmacro MUI_PAGE_LICENSE "LICENSE"
# Pick Install Directory
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
page instfiles
# Done
!insertmacro MUI_PAGE_FINISH
# Need to set a language.
!insertmacro MUI_LANGUAGE "English"
function .onInit
setShellVarContext all
!insertmacro MULTIUSER_INIT
functionEnd
section "install"
section "Janet" BfWSection
createDirectory "$INSTDIR\Library"
createDirectory "$INSTDIR\C"
createDirectory "$INSTDIR\bin"
setOutPath $INSTDIR
setOutPath "$INSTDIR"
file /oname=bin\janet.exe dist\janet.exe
file /oname=logo.ico assets\icon.ico
@@ -61,7 +73,7 @@ section "install"
file /oname=bin\jpm.janet dist\jpm
file /oname=bin\jpm.bat dist\jpm.bat
# Uninstaller - See function un.onInit and section "uninstall" for configuration
writeUninstaller "$INSTDIR\uninstall.exe"
@@ -71,11 +83,11 @@ section "install"
# HKLM (all users) vs HKCU (current user)
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_PATH "$INSTDIR\Library"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_HEADERPATH "$INSTDIR\C"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_BINDIR "$INSTDIR\bin"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_BINPATH "$INSTDIR\bin"
WriteRegExpandStr HKCU "Environment" JANET_PATH "$INSTDIR\Library"
WriteRegExpandStr HKCU "Environment" JANET_HEADERPATH "$INSTDIR\C"
WriteRegExpandStr HKCU "Environment" JANET_BINDIR "$INSTDIR\bin"
WriteRegExpandStr HKCU "Environment" JANET_BINPATH "$INSTDIR\bin"
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
@@ -106,12 +118,7 @@ sectionEnd
# Uninstaller
function un.onInit
SetShellVarContext all
#Verify the uninstaller - last chance to back out
MessageBox MB_OKCANCEL "Permanantly remove Janet?" IDOK next
Abort
next:
!insertmacro MULTIUSER_UNINIT
functionEnd
section "uninstall"
@@ -120,29 +127,20 @@ section "uninstall"
delete "$SMPROGRAMS\Janet.lnk"
# Remove files
delete $INSTDIR\logo.ico
delete $INSTDIR\C\janet.c
delete $INSTDIR\C\janet.h
delete $INSTDIR\C\janet.lib
delete $INSTDIR\C\janet.exp
delete $INSTDIR\C\janetconf.h
delete $INSTDIR\bin\jpm.janet
delete $INSTDIR\bin\jpm.bat
delete $INSTDIR\bin\janet.exe
delete $INSTDIR\Library\cook.janet
delete "$INSTDIR\logo.ico"
rmdir /r "$INSTDIR\Library"
rmdir /r "$INSTDIR\bin"
rmdir /r "$INSTDIR\C"
# Remove env vars
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_PATH
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_HEADERPATH
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_BINDIR
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" JANET_BINPATH
DeleteRegValue HKCU "Environment" JANET_PATH
DeleteRegValue HKCU "Environment" JANET_HEADERPATH
DeleteRegValue HKCU "Environment" JANET_BINDIR
DeleteRegValue HKCU "Environment" JANET_BINPATH
# Unset PATH
${un.EnvVarUpdate} $0 "PATH" "R" "HKCU" "$INSTDIR\bin" ; Remove
@@ -152,12 +150,8 @@ section "uninstall"
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
# Always delete uninstaller as the last action
delete $INSTDIR\uninstall.exe
rmDir "$INSTDIR\Library"
rmDir "$INSTDIR\C"
rmDir "$INSTDIR\bin"
delete "$INSTDIR\uninstall.exe"
# Remove uninstaller information from the registry
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Janet"
sectionEnd
sectionEnd

View File

@@ -57,13 +57,37 @@ typedef void *Clib;
JanetModule janet_native(const char *name, const uint8_t **error) {
Clib lib = load_clib(name);
JanetModule init;
JanetModconf getter;
if (!lib) {
*error = janet_cstring(error_clib());
return NULL;
}
init = (JanetModule) symbol_clib(lib, "_janet_init");
if (!init) {
*error = janet_cstring("could not find _janet_init symbol");
*error = janet_cstring("could not find the _janet_init symbol");
return NULL;
}
getter = (JanetModconf) symbol_clib(lib, "_janet_mod_config");
if (!getter) {
*error = janet_cstring("could not find the _janet_mod_config symbol");
return NULL;
}
JanetBuildConfig modconf = getter();
JanetBuildConfig host = janet_config_current();
if (host.major != modconf.major ||
host.minor < modconf.minor ||
host.bits != modconf.bits) {
char errbuf[128];
sprintf(errbuf, "config mismatch - host %d.%.d.%d(%.4x) vs. module %d.%d.%d(%.4x)",
host.major,
host.minor,
host.patch,
host.bits,
modconf.major,
modconf.minor,
modconf.patch,
modconf.bits);
*error = janet_cstring(errbuf);
return NULL;
}
return init;
@@ -830,6 +854,9 @@ JanetTable *janet_core_env(JanetTable *replacements) {
JDOC("The version number of the running janet program."));
janet_def(env, "janet/build", janet_cstringv(JANET_BUILD),
JDOC("The build identifier of the running janet program."));
janet_def(env, "janet/config-bits", janet_wrap_integer(JANET_CURRENT_CONFIG_BITS),
JDOC("The flag set of config options from janetconf.h which is used to check "
"if native modules are compatible with the host program."));
/* Allow references to the environment */
janet_def(env, "_env", janet_wrap_table(env), JDOC("The environment table for the current scope."));

View File

@@ -32,6 +32,10 @@
#include "util.h"
#endif
#ifndef JANET_WINDOWS
#include <sys/wait.h>
#endif
#define IO_WRITE 1
#define IO_READ 2
#define IO_APPEND 4
@@ -285,13 +289,17 @@ static Janet cfun_io_fclose(int32_t argc, Janet *argv) {
if (iof->flags & IO_PIPED) {
#ifdef JANET_WINDOWS
#define pclose _pclose
#define WEXITSTATUS(x) x
#endif
if (pclose(iof->file)) janet_panic("could not close file");
int status = pclose(iof->file);
iof->flags |= IO_CLOSED;
if (status == -1) janet_panic("could not close file");
return janet_wrap_integer(WEXITSTATUS(status));
} else {
if (fclose(iof->file)) janet_panic("could not close file");
iof->flags |= IO_CLOSED;
return janet_wrap_nil();
}
iof->flags |= IO_CLOSED;
return argv[0];
}
/* Seek a file */

View File

@@ -41,7 +41,9 @@
#include <direct.h>
#include <sys/utime.h>
#include <io.h>
#include <process.h>
#else
#include <spawn.h>
#include <utime.h>
#include <unistd.h>
#include <dirent.h>
@@ -88,7 +90,7 @@ static Janet os_exit(int32_t argc, Janet *argv) {
}
#ifdef JANET_REDUCED_OS
/* Provide a dud os/getenv so init.janet works, but nothing else */
/* Provide a dud os/getenv so boot.janet and init.janet work, but nothing else */
static Janet os_getenv(int32_t argc, Janet *argv) {
(void) argv;
@@ -99,97 +101,152 @@ static Janet os_getenv(int32_t argc, Janet *argv) {
#else
/* Provide full os functionality */
#ifdef JANET_WINDOWS
static Janet os_execute(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_buffer(10);
for (int32_t i = 0; i < argc; i++) {
const uint8_t *argstring = janet_getstring(argv, i);
janet_buffer_push_bytes(buffer, argstring, janet_string_length(argstring));
if (i != argc - 1) {
janet_buffer_push_u8(buffer, ' ');
#define JANET_OS_EFLAG_E 0x1
#define JANET_OS_EFLAG_P 0x2
/* Get flags */
/* Unfortunately, execvpe is linux (glibc) only. Instead, we can switch
* between the more portable execve, execvp, or execv.
* Use the :e or :p flag for execve and execvp respectively. Eventually
* :ep or :pe could be execvpe. */
static int os_execute_flags(int32_t argc, const Janet *argv) {
if (argc < 2) return 0;
int flags = 0;
if (argc > 1) {
const uint8_t *f = janet_getkeyword(argv, 1);
int32_t len = janet_string_length(f);
for (int32_t i = 0; i < len; i++) {
if (f[i] == 'e') flags |= JANET_OS_EFLAG_E;
if (f[i] == 'p') flags |= JANET_OS_EFLAG_P;
}
}
janet_buffer_push_u8(buffer, 0);
/* Convert to wide chars */
wchar_t *sys_str = malloc(buffer->count * sizeof(wchar_t));
if (NULL == sys_str) {
JANET_OUT_OF_MEMORY;
}
int nwritten = MultiByteToWideChar(
CP_UTF8,
MB_PRECOMPOSED,
buffer->data,
buffer->count,
sys_str,
buffer->count);
if (nwritten == 0) {
free(sys_str);
janet_panic("could not create process");
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Start the child process.
if (!CreateProcess(NULL,
(LPSTR) sys_str,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi)) {
free(sys_str);
janet_panic("could not create process");
}
free(sys_str);
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
WORD status;
GetExitCodeProcess(pi.hProcess, (LPDWORD)&status);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return janet_wrap_integer(status);
return flags;
}
#else
/* Get env for os_execute (execv family of functions, as well as CreateProcess) */
static char **os_execute_env(int32_t argc, const Janet *argv) {
char **envp = NULL;
if (argc > 2) {
JanetDictView dict = janet_getdictionary(argv, 2);
envp = malloc(sizeof(char *) * (dict.len + 1));
if (NULL == envp) {
JANET_OUT_OF_MEMORY;
}
int32_t j = 0;
for (int32_t i = 0; i < dict.cap; i++) {
const JanetKV *kv = dict.kvs + i;
if (!janet_checktype(kv->key, JANET_STRING)) continue;
if (!janet_checktype(kv->value, JANET_STRING)) continue;
const uint8_t *keys = janet_unwrap_string(kv->key);
const uint8_t *vals = janet_unwrap_string(kv->value);
int32_t klen = janet_string_length(keys);
int32_t vlen = janet_string_length(vals);
/* Check keys has no embedded 0s or =s. */
int skip = 0;
for (int32_t k = 0; k < klen; k++) {
if (keys[k] == '\0' || keys[k] == '=') {
skip = 1;
break;
}
}
if (skip) continue;
char *envitem = malloc(klen + vlen + 2);
if (NULL == envitem) {
JANET_OUT_OF_MEMORY;
}
memcpy(envitem, keys, klen);
envitem[klen] = '=';
memcpy(envitem + klen + 1, vals, vlen);
envitem[klen + vlen + 1] = 0;
envp[j++] = envitem;
}
envp[j] = NULL;
}
return envp;
}
/* Free memory from os_execute */
static void os_execute_cleanup(char **envp, const char **child_argv) {
free((void *)child_argv);
if (NULL != envp) {
char **envitem = envp;
while (*envitem != NULL) {
free(*envitem);
envitem++;
}
}
free(envp);
}
static Janet os_execute(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
const char **child_argv = malloc(sizeof(char *) * (argc + 1));
janet_arity(argc, 1, 3);
/* Get arguments */
JanetView exargs = janet_getindexed(argv, 0);
const char **child_argv = malloc(sizeof(char *) * (exargs.len + 1));
int status = 0;
if (NULL == child_argv) {
JANET_OUT_OF_MEMORY;
}
for (int32_t i = 0; i < argc; i++) {
child_argv[i] = janet_getcstring(argv, i);
for (int32_t i = 0; i < exargs.len; i++) {
child_argv[i] = janet_getcstring(exargs.items, i);
}
child_argv[argc] = NULL;
child_argv[exargs.len] = NULL;
/* Fork child process */
pid_t pid = fork();
if (pid < 0) {
janet_panic("failed to execute");
} else if (pid == 0) {
if (-1 == execve(child_argv[0], (char **)child_argv, NULL)) {
exit(1);
}
/* Get flags */
int flags = os_execute_flags(argc, argv);
/* Get environment */
char **envp = os_execute_env(argc, argv);
/* Coerce to form that works for spawn. I'm fairly confident no implementation
* of posix_spawn would modify the argv array passed in. */
char *const *cargv = (char *const *)child_argv;
#ifdef JANET_WINDOWS
/* Use _spawn family of functions. */
/* Windows docs say do this before any spawns. */
_flushall();
if (flags & (JANET_OS_EFLAG_P | JANET_OS_EFLAG_E)) {
status = (int) _spawnvpe(_P_WAIT, child_argv[0], cargv, envp);
} else if (flags & JANET_OS_EFLAG_P) {
status = (int) _spawnvp(_P_WAIT, child_argv[0], cargv);
} else if (flags & JANET_OS_EFLAG_E) {
status = (int) _spawnve(_P_WAIT, child_argv[0], cargv, envp);
} else {
status = (int) _spawnv(_P_WAIT, child_argv[0], cargv);
}
os_execute_cleanup(envp, child_argv);
return janet_wrap_integer(status);
#else
/* Use posix_spawn to spawn new process */
pid_t pid;
if (flags & JANET_OS_EFLAG_P) {
status = posix_spawnp(&pid,
child_argv[0], NULL, NULL, cargv,
(flags & JANET_OS_EFLAG_E) ? envp : NULL);
} else {
status = posix_spawn(&pid,
child_argv[0], NULL, NULL, cargv,
(flags & JANET_OS_EFLAG_E) ? envp : NULL);
}
/* Wait for child */
if (status) {
os_execute_cleanup(envp, child_argv);
janet_panic(strerror(status));
} else {
waitpid(pid, &status, 0);
}
free(child_argv);
return janet_wrap_integer(status);
}
os_execute_cleanup(envp, child_argv);
return janet_wrap_integer(WEXITSTATUS(status));
#endif
}
static Janet os_shell(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 1);
@@ -607,6 +664,17 @@ static Janet os_dir(int32_t argc, Janet *argv) {
return janet_wrap_array(paths);
}
static Janet os_rename(int32_t argc, Janet *argv) {
janet_fixarity(argc, 2);
const char *src = janet_getcstring(argv, 0);
const char *dest = janet_getcstring(argv, 1);
int status = rename(src, dest);
if (status) {
janet_panic(strerror(errno));
}
return janet_wrap_nil();
}
#endif /* JANET_REDUCED_OS */
static const JanetReg os_cfuns[] = {
@@ -690,9 +758,15 @@ static const JanetReg os_cfuns[] = {
},
{
"os/execute", os_execute,
JDOC("(os/execute program & args)\n\n"
"Execute a program on the system and pass it string arguments. Returns "
"the exit status of the program.")
JDOC("(os/execute args &opts flags env)\n\n"
"Execute a program on the system and pass it string arguments. Flags "
"is a keyword that modifies how the program will execute.\n\n"
"\t:e - enables passing an environment to the program. Without :e, the "
"current environment is inherited.\n"
"\t:p - allows searching the current PATH for the binary to execute. "
"Without this flag, binaries must use absolute paths.\n\n"
"env is a table or struct mapping environment variables to values. "
"Returns the exit status of the program.")
},
{
"os/shell", os_shell,
@@ -742,6 +816,11 @@ static const JanetReg os_cfuns[] = {
"\t:year-day - day of the year [0-365]\n"
"\t:dst - If Day Light Savings is in effect")
},
{
"os/rename", os_rename,
JDOC("(os/rename oldname newname)\n\n"
"Rename a file on disk to a new path. Returns nil.")
},
#endif
{NULL, NULL, NULL}
};

View File

@@ -23,6 +23,9 @@
#ifndef JANET_UTIL_H_defined
#define JANET_UTIL_H_defined
#include <stdio.h>
#include <errno.h>
#ifndef JANET_AMALG
#include <janet.h>
#endif

View File

@@ -184,6 +184,38 @@ extern "C" {
#endif
#endif
/* Runtime config constants */
#ifdef JANET_NO_NANBOX
#define JANET_NANBOX_BIT 0
#else
#define JANET_NANBOX_BIT 0x1
#endif
#ifdef JANET_SINGLE_THREADED
#define JANET_SINGLE_THREADED_BIT 0x2
#else
#define JANET_SINGLE_THREADED_BIT 0
#endif
#define JANET_CURRENT_CONFIG_BITS \
(JANET_SINGLE_THREADED_BIT | \
JANET_NANBOX_BIT)
/* Represents the settings used to compile Janet, as well as the version */
typedef struct {
unsigned major;
unsigned minor;
unsigned patch;
unsigned bits;
} JanetBuildConfig;
/* Get config of current compilation unit. */
#define janet_config_current() ((JanetBuildConfig){ \
JANET_VERSION_MAJOR, \
JANET_VERSION_MINOR, \
JANET_VERSION_PATCH, \
JANET_CURRENT_CONFIG_BITS })
/***** END SECTION CONFIG *****/
/***** START SECTION TYPES *****/
@@ -1184,6 +1216,7 @@ JANET_API void *janet_abstract(const JanetAbstractType *type, size_t size);
/* Native */
typedef void (*JanetModule)(JanetTable *);
typedef JanetBuildConfig(*JanetModconf)(void);
JANET_API JanetModule janet_native(const char *name, const uint8_t **error);
/* Marshaling */
@@ -1254,7 +1287,12 @@ JANET_API void janet_register(const char *name, JanetCFunction cfun);
/* New C API */
#define JANET_MODULE_ENTRY JANET_API void _janet_init
#define JANET_MODULE_ENTRY \
JANET_API JanetBuildConfig _janet_mod_config(void) { \
return janet_config_current(); \
} \
JANET_API void _janet_init
JANET_API void janet_panicv(Janet message);
JANET_API void janet_panic(const char *message);
JANET_API void janet_panics(const uint8_t *message);

View File

@@ -25,7 +25,11 @@
#ifndef JANETCONF_H
#define JANETCONF_H
#define JANET_VERSION "0.6.0"
#define JANET_VERSION_MAJOR 0
#define JANET_VERSION_MINOR 6
#define JANET_VERSION_PATCH 0
#define JANET_VERSION_EXTRA "-dev"
#define JANET_VERSION "0.6.0-dev"
/* #define JANET_BUILD "local" */

View File

@@ -97,7 +97,10 @@
(def [realpath] (module/find path))
(def env (make-env))
(loop [k :keys _env :when (symbol? k)]
(unless ((_env k) :private) (put env k (_env k))))
(unless ((_env k) :private) (put env k (_env k))))
(def currenv (fiber/getenv (fiber/current)))
(loop [k :keys currenv :when (keyword? k)]
(put env k (currenv k)))
(require path :env env ;args)
(when-let [rules (env :rules)] (merge-into (getrules) rules)))
@@ -112,9 +115,9 @@
#
# Installation settings
(def BINDIR (os/getenv "JANET_BINDIR"))
(def LIBDIR (or (os/getenv "JANET_PATH") module/*syspath*))
(def INCLUDEDIR (or (os/getenv "JANET_HEADERPATH") module/*headerpath*))
(def JANET_MODPATH (or (os/getenv "JANET_MODPATH") module/*syspath*))
(def JANET_HEADERPATH (or (os/getenv "JANET_HEADERPATH") module/*headerpath*))
(def JANET_BINPATH (or (os/getenv "JANET_BINPATH") (unless is-win "/usr/local/bin")))
# Compilation settings
(def OPTIMIZE (or (os/getenv "OPTIMIZE") 2))
@@ -161,7 +164,7 @@
(defn copy
"Copy a file or directory recursively from one location to another."
[src dest]
(shell (if is-win "xcopy " "cp -rf ") src " " dest (if is-win " /h /y /t /e" "")))
(shell (if is-win "xcopy " "cp -rf ") `"` src `" "` dest (if is-win `" /y /e` `"`)))
#
# C Compilation
@@ -221,10 +224,12 @@
"Generate the c flags from the input options."
[opts]
(string (opt opts :cflags CFLAGS)
(if is-win " /I" " -I")
(opt opts :includedir INCLUDEDIR)
(if is-win " /O" " -O")
(opt opts :optimize OPTIMIZE)))
(if is-win " /I\"" " \"-I")
(opt opts :headerpath JANET_HEADERPATH)
`"`
(if is-win " /O\"" " \"-O")
(opt opts :optimize OPTIMIZE)
`"`))
(defn- compile-c
"Compile a C file into an object file."
@@ -234,8 +239,8 @@
(def defines (interpose " " (make-defines (opt opts :defines {}))))
(rule dest [src]
(if is-win
(shell cc " " ;defines " /nologo /c " cflags " /Fo" dest " " src)
(shell cc " -c " src " " ;defines " " cflags " -o " dest))))
(shell cc " " ;defines " /nologo /c " cflags " /Fo\"" dest `" "` src `"`)
(shell cc " -c '" src "' " ;defines " " cflags " -o '" dest `'`))))
(defn- link-c
"Link a number of object files together."
@@ -243,11 +248,11 @@
(def ld (opt opts :linker LD))
(def cflags (getcflags opts))
(def lflags (opt opts :lflags LDFLAGS))
(def olist (string/join objects " "))
(def olist (string/join objects `" "`))
(rule target objects
(if is-win
(shell ld " " lflags " /DLL /OUT:" target " " olist " " (opt opts :includedir INCLUDEDIR) "\\janet.lib")
(shell ld " " cflags " -o " target " " olist " " lflags))))
(shell ld " " lflags " /DLL /OUT:" target ` "` olist `" "` (opt opts :headerpath JANET_HEADERPATH) `"\\janet.lib`)
(shell ld " " cflags ` -o "` target `" "` olist `" ` lflags))))
(defn- create-buffer-c
"Inline raw byte file as a c file."
@@ -306,24 +311,24 @@
(compile-c opts c-src o-src)))
(link-c opts lname ;objects)
(add-dep "build" lname)
(def libdir (opt opts :libdir LIBDIR))
(install-rule lname LIBDIR))
(def path (opt opts :modpath JANET_MODPATH))
(install-rule lname path))
(defn declare-source
"Create a Janet modules. This does not actually build the module(s),
but registers it for packaging and installation."
[&keys opts]
(def sources (opts :source))
(def libdir (opt opts :libdir LIBDIR))
(def path (opt opts :modpath JANET_MODPATH))
(each s sources
(install-rule s libdir)))
(install-rule s path)))
(defn declare-binscript
"Declare a janet file to be installed as an executable script."
[&keys opts]
(def main (opts :main))
(def bindir (opt opts :bindir BINDIR))
(install-rule main bindir))
(def binpath (opt opts :binpath JANET_BINPATH))
(install-rule main binpath))
(defn declare-archive
"Build a janet archive. This is a file that bundles together many janet
@@ -335,8 +340,8 @@
(def iname (string "build" sep name ".jimage"))
(rule iname (or (opts :deps) [])
(spit iname (make-image (require entry))))
(def libdir (opt opts :libdir LIBDIR))
(install-rule iname libdir))
(def path (opt opts :modpath JANET_MODPATH))
(install-rule iname path))
(defn declare-project
"Define your project metadata. This should

View File

@@ -2,9 +2,7 @@
# CLI tool for building janet projects. Wraps cook.
(import cook :prefix "")
(import-rules "./project.janet")
(import cook)
(def- argpeg
(peg/compile
@@ -19,9 +17,9 @@
(print `
Keys are:
--libdir : The directory to install modules to. Defaults to $JANET_PATH or module/*syspath*
--includedir : The directory containing janet headers. Defaults to $JANET_HEADERPATH or module/*headerpath*
--bindir : The directory to install binaries and scripts. Defaults to $JANET_BINDIR.
--modpath : The directory to install modules to. Defaults to $JANET_MODPATH or module/*syspath*
--headerpath : The directory containing janet headers. Defaults to $JANET_HEADERPATH or module/*headerpath*
--binpath : The directory to install binaries and scripts. Defaults to $JANET_BINPATH.
--optimize : Optimization level for natives. Defaults to $OPTIMIZE or 2.
--compiler : C compiler to use for natives. Defaults to $CC or cc.
--linker : C linker to use for linking natives. Defaults to $LINKER or cc.
@@ -30,10 +28,14 @@ Keys are:
`))
(def args (tuple/slice process/args 2))
(def todo @[])
(each arg args
(if (string/has-prefix? "--" arg)
(let [[key value] (peg/match argpeg arg)]
(setdyn (keyword key) value))
(do-rule arg)))
(array/push todo arg)))
(if (empty? args) (help))
(cook/import-rules "./project.janet")
(if (empty? todo) (help))
(each rule todo (cook/do-rule rule))