Is it possible to compile GLib (and then compile Autotrace) with Emscripten? - glib

Compiling with Emscripten seems really easy with typical configure, make and make install workflows.
I would like to compile Autotrace (which uses this workflow), but it requires GLib.
In the Emscripten doc, it is mentioned that in such case GLib must be compiled with Emscripten. However GLib uses meson and ninja as compile tools.
Is it possible to compile GLib with Emscripten? (and will it be enough to get Autotrace working in a browser?)

Meson supports cross-compiling, so you can treat Emscripten as a cross compiler by writing a 'cross file':
emscripten.txt
[binaries]
c = '/opt/emsdk-portable/emscripten/1.38.8/emcc'
cpp = '/opt/emsdk-portable/emscripten/1.38.8/em++'
ar = '/opt/emsdk-portable/emscripten/1.38.8/emar'
#exe_wrapper = 'node'
[properties]
root = '/opt/emsdk-portable/emscripten/1.38.8/system'
c_args = ['-s', 'WASM=1', '-O2']
c_link_args = ['-s', 'WASM=1','-O2']
cpp_args = ['-s', 'WASM=1','-O2']
cpp_link_args = ['-s', 'WASM=1','-O2']
shared_lib_suffix = 'js'
static_lib_suffix = 'js'
shared_module_suffix = 'js'
exe_suffix = 'js'
[host_machine]
system = 'emscripten'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
(This was taken from https://github.com/prozum/meson-samples/blob/master/emscripten.txt)
Replace the paths with the paths to your Emscripten tools. Then invoke meson with meson --cross-file=emscripten.txt.

Related

How do I check the OS in the F# preprocessor?

We're multiple persons working on the same F# project. Some use MacOS and Visual Studio Code together with Ionide while others use Windows with Visual Studio. In the F#-code, we need to access some files, but MacOS uses / to specify paths while Windows uses \. In F#, how can we make something like:
#if OS_WINDOWS
let path = "path\to\file.txt"
#elif OS_MAC
let path = "path/to/file.txt"
#endif
There is no built-in pre-defined symbol to indicate what operating system you are compiling for. When you use .NET, you generally use the same compiled assembly on all operating systems, so this is not something that you can reasonably do in a pre-processor anyway.
You can check what OS are you running on at runtime using System.Environment:
open System
let path =
if Environment.OSVersion.Platform = PlatformID.Win32NT then #"path\to\file.txt"
else #"path/to/file.txt"
That said, if your only concern is slashes and backslashes in a path, you can just use:
let path = System.IO.Path.Combine("path", "to", "file.txt")

How can I use the JAR tool with Bazel v0.19+?

Starting with Bazel v0.19, if you have Starlark (formerly known as "Skylark") code that references #bazel_tools//tools/jdk:jar, you see messages like this at build time:
WARNING: <trimmed-path>/external/bazel_tools/tools/jdk/BUILD:79:1: in alias rule #bazel_tools//tools/jdk:jar: target '#bazel_tools//tools/jdk:jar' depends on deprecated target '#local_jdk//:jar': Don't depend on targets in the JDK workspace; use #bazel_tools//tools/jdk:current_java_runtime instead (see https://github.com/bazelbuild/bazel/issues/5594)
I think I could make things work with #bazel_tools//tools/jdk:current_java_runtime if I wanted access to the java command, but I'm not sure what I'd need to do to get the jar tool to work. The contents of the linked GitHub issue didn't seem to address this particular problem.
I stumbled across a commit to Bazel that makes a similar adjustment to the Starlark java rules. It uses the following pattern: (I've edited the code somewhat)
# in the rule attrs:
"_jdk": attr.label(
default = Label("//tools/jdk:current_java_runtime"),
providers = [java_common.JavaRuntimeInfo],
),
# then in the rule implementation:
java_runtime = ctx.attr._jdk[java_common.JavaRuntimeInfo]
jar_path = "%s/bin/jar" % java_runtime.java_home
ctx.action(
inputs = ctx.files._jdk + other inputs,
outputs = [deploy_jar],
command = "%s cmf %s" % (jar_path, input_files),
)
Additionally, java is available at str(java_runtime.java_executable_exec_path) and javac at "%s/bin/javac" % java_runtime.java_home.
See also, a pull request with a simpler example.
Because my reference to the jar tool is inside a genrule within top-level macro, rather than a rule, I was unable to use the approach from Rodrigo's answer. I instead explicitly referenced the current_java_runtime toolchain and was then able to use the JAVABASE make variable as the base path for the jar tool.
native.genrule(
name = genjar_rule,
srcs = [<rules that create files being jar'd>],
cmd = "some_script.sh $(JAVABASE)/bin/jar $# $(SRCS)",
tools = ["some_script.sh", "#bazel_tools//tools/jdk:current_java_runtime"],
toolchains = ["#bazel_tools//tools/jdk:current_java_runtime"],
outs = [<some outputs>]
)

Luarocks on windows not recognizing my lua_libdir

i want to install nngraph on lua using luarocks
using this code
luarocks --from=https://raw.githubusercontent.com/torch/rocks/master/ install nngraph
but it's give me an error
it said :
Error: Failed finding Lua library. You may need to configure LUA_LIBDIR.
does anyone have same experience? can you solve it ?
this was my config-5.2.lua :
rocks_trees = {
{ name = [[user]],
root = home..[[/luarocks]],
},
{ name = [[system]],
root = [[d:\shared\ta\_bootstrap\_install\]],
},
}
variables = {
MSVCRT = 'MSVCRT',
LUALIB = 'D:\\Shared\\TA\\_bootstrap\\_install\\lib\\liblua.dll.a',
LUA_LIBDIR = 'D:\\Shared\\TA\\_bootstrap\\_install\\lib'
}
verbose = false -- set to 'true' to enable verbose output
Is your config-5.2.lua file located in one of the searched paths? I installed the stand-alone binaries (with Lua version 5.3), which searches for C:/Program Files (x86)/luarocks/config-5.3.lua & %APPDATA%/luarocks/config-5.3.lua. Neither of these files existed on my system & I had to create one manually. Running the luarocks command without any arguments will show you where it searches. If you want to use a custom location, you can set the LUAROCKS_CONFIG environment variable.
I was able to get mine working by adding the following variables to my configuration (Note: I am using MinGW/GCC compiler):
rocks_trees = {
{ name = [[system]], root = [[C:/Development/Lua53]] },
}
variables = {
LUA = 'C:/Development/Lua53/bin/lua',
LUA_BINDIR = 'C:/Development/Lua53/bin',
LUA_INCDIR = 'C:/Development/Lua53/include',
LUA_LIBDIR = 'C:/Development/Lua53/lib',
CC = 'gcc',
LD = 'gcc',
}
The CC & LD variables are only necessary if it has trouble finding the compiler or linker (defaults to mingw32-gcc on my system).
Sources:
http://lua-users.org/wiki/LuaRocksConfig
http://lua-users.org/lists/lua-l/2015-12/msg00172.html
https://github.com/luarocks/luarocks/wiki/config-file-format
I hope this helps.
Edit: If all else fails, you may want to have a look at LuaDist. It is a Lua distribution with its own package management system & includes LuaRocks & some other libraries/utilities pre-installed. I haven't tried it yet, but I plan to.

Unmanaged C# calls to a static library

I'm using swig to generate C# wrappers for some C code base to be used from C#. When I run swig, it generates a wrapper c file that exposes all the functionality to the generated PInvoke C# file... For example:
// This is in KodLogic_wrap.c
SWIGEXPORT void SWIGSTDCALL CSharp_DMGameMode_timeLimit_set(void * jarg1, unsigned short jarg2) { ... }
// This is in KodLogicPInvoke.cs
[global::System.Runtime.InteropServices.DllImport("KodLogic", EntryPoint="CSharp_DMGameMode_timeLimit_set")]
This works great when I am building a dynamic library. However, I need to support iOS now, so I've prepared a static library, and passed in the -dllimport '__Internal' option to swig for that to work.
Unfortunately, I am getting linking errors such as:
"_DMGameMode_timeLimit_set", referenced from:
RegisterMonoModules() in RegisterMonoModules.o
(maybe you meant: _CSharp_DMGameMode_timeLimit_set)
Indeed, I did mean "CSharp_DMGameMode_timeLimit_set", but that's the point of the "entrypoint" argument?
So, since this error is thrown by the Xcode project Unity generated, I am not quite sure what's the source of the failure. Does it fail for static libraries? Is this something to be fixed on Unity side or swig side?
Update: After digging more into this, I think I have a slight idea of what's going on here..
The main issue seems to be from the AOT compiler, which tries to compile all the CS code to an ARM assembly. This seems to be required for iOS, so during Unity's AOT compilation, it generates a file RegisterMonoModules.cpp, which attempts to define access functions to the native code. RegisterMonoModules.cpp doesn't honor the entrypoint parameter, which causes undefined symbol errors to be thrown...
Still attempting to find a proper workaround.
The main issue seems to be from Unity, and not Swig nor Mono. As mentioned above, Unity performs AOT compilation that doesn't honor the entry point argument. This produces cpp code that calls the function name, not the entry point name..
I've confirmed this by switching the scripting backend to IL2cpp, and the entry point name was honored there.
Let's switch over to callbacks. Not exactly related to the question, but it definitely fits the context of Unity + Native plugins + iOS.
AFAIK, you can't have a managed method marshaled to native land on iOS using Mono 2x. I previously had to delete all the string callback and exception handlers from the swig generated files. Fortunately, IL2Cpp supports callbacks, after a little tweaking:
Add using AOT;
Decorate callbacks with [MonoPInvokeCallback(typeof(method_signature))]
You can use this script, just use it to process the generated swig files:
def process_csharp_callbacks(pinvoke_file):
"""Process PInvoke file by fixing the decorators for callback methods to use:
[MonoPInvokeCallback(typeof(method_signature))]
"""
# prepare requirements
with open(pinvoke_file) as f:
content = f.read()
callback_methods_regex = re.compile(r"( +)static (?:void|string) (?:SetPending|CreateString)\w*\([\s\w\,]+\)")
callback_decorator = "[MonoPInvokeCallback(typeof(ExceptionDelegate))]"
callback_arg_decorator = "[MonoPInvokeCallback(typeof(ExceptionArgumentDelegate))]"
callback_str_decorator = "[MonoPInvokeCallback(typeof(SWIGStringDelegate))]"
# add use AOT
content = content.replace("\n\n", "\nusing AOT;\n", 1)
# fix callback methods
def method_processor(match):
match_string = match.group()
indentation = match.captures(1)[0]
if match_string.find(",") != -1:
fix = callback_arg_decorator
elif match_string.find("static string") != -1:
fix = callback_str_decorator
else:
fix = callback_decorator
return indentation + fix + "\n" + match_string
content = callback_methods_regex.sub(method_processor, content)
# write it back
with open(pinvoke_file, "w+") as f:
f.write(content)
For anyone looking for help converting their generated swig CSharp PInvoke file to something mono 2x scripting backend will allow, stick this somewhere in your build process, after the CSharp files are generated:
pinvoke_template = """{extern_prefix} CSharp_{method_signature};
{normal_prefix} {method_signature} {{
{return_statement}CSharp_{method_name}({method_args});
}}"""
def process_csharp_wrapper(csharp_dir):
"""Reads the PINVOKE csharp file, and performs the following:
1. Remove EntryPoint="xxx" from the decorators
2. Make the methods match their native counterpart name
3. Add a C# method with the original name, for compatability
"""
# prepare requirements
pinvoke_file = os.path.join(csharp_dir, "KodLogicPINVOKE.cs")
with open(pinvoke_file) as f:
content = f.read()
decorator_regex = re.compile(r', EntryPoint=".*?"')
method_regex = re.compile(r"(public static extern \w+[\w:\.]+)\s(([^S]\w+)\((?:([\w:\. ]+)\,?)*\));")
# fix decorators
content = decorator_regex.sub("", content)
# fix method definitions
def method_processor(match):
extern_prefix = match.captures(1)[0]
return pinvoke_template.format(
extern_prefix=extern_prefix,
normal_prefix=extern_prefix.replace("extern ", ""),
method_signature=match.captures(2)[0],
return_statement=("return " if extern_prefix.find("void") == -1 else ""),
method_name=match.captures(3)[0],
method_args=", ".join(map(lambda s: s.strip().split()[1], match.captures(4)))
)
content = method_regex.sub(method_processor, content)
# write it back
with open(pinvoke_file, "w+") as f:
f.write(content)

How do I disable assertions for the entire project?

I have some code in Delphi that has Assert statements all over it. I know that there is a compiler directive {$C-}, but there are too many units to add it to. Is there a way to have it done by the compiler command line or somewhere in the dpr file?
You can use $C- from the command line as well, or configure it in 'Project->Options->Compiler' from the IDE (which configures it in the .dproj file).
There's a list of command line switches and options available by typing dcc32 from the command line. It can be redirected to a text file using command redirection (as in dcc32 > dccCommands.txt), which produces the following output with XE5's version of dcc32:
Embarcadero Delphi for Win32 compiler version 26.0
Copyright (c) 1983,2013 Embarcadero Technologies, Inc.
Syntax: dcc32 [options] filename [options]
-A<unit>=<alias> = Set unit alias
-B = Build all units
-CC = Console target
-CG = GUI target
-D<syms> = Define conditionals
-E<path> = EXE/DLL output directory
-F<offset> = Find error
-GD = Detailed map file
-GP = Map file with publics
-GS = Map file with segments
-H = Output hint messages
-I<paths> = Include directories
-J = Generate .obj file
-JPHNE = Generate C++ .obj file, .hpp file, in namespace, export all
-JL = Generate package .lib, .bpi, and all .hpp files for C++
-K<addr> = Set image base addr
-LE<path> = package .bpl output directory
-LN<path> = package .dcp output directory
-LU<package> = Use package
-M = Make modified units
-NU<path> = unit .dcu output directory
-NH<path> = unit .hpp output directory
-NO<path> = unit .obj output directory
-NB<path> = unit .bpi output directory
-NX<path> = unit .xml output directory
-NS<namespaces> = Namespace search path
-O<paths> = Object directories
-P = look for 8.3 file names also
-Q = Quiet compile
-R<paths> = Resource directories
-TX<ext> = Output name extension
-U<paths> = Unit directories
-V = Debug information in EXE
-VR = Generate remote debug (RSM)
-VT = Debug information in TDS
-VN = TDS symbols in namespace
-W[+|-|^][warn_id] = Output warning messages
-Z = Output 'never build' DCPs
-$<dir> = Compiler directive
--help = Show this help screen
--version = Show name and version
--codepage:<cp> = specify source file encoding
--default-namespace:<namespace> = set namespace
--depends = output unit dependency information
--doc = output XML documentation
--drc = output resource string .drc file
--no-config = do not load default dcc32.cfg file
--description:<string> = set executable description
--inline:{on|off|auto} = function inlining control
--legacy-ifend = allow legacy $IFEND directive
--zero-based-strings[+|-] = strings are indexed starting at 0
--peflags:<flags> = set extra PE Header flags field
--peoptflags:<flags> = set extra PE Header optional flags field
--peosversion:<major>.<minor> = set OS Version fields in PE Header (default: 5.0)
--pesubsysversion:<major>.<minor> = set Subsystem Version fields in PE Header (default: 5.0)
--peuserversion:<major>.<minor> = set User Version fields in PE Header (default: 0.0)
Compiler switches: -$<letter><state> (defaults are shown below)
A8 Aligned record fields
B- Full boolean Evaluation
C+ Evaluate assertions at runtime
D+ Debug information
G+ Use imported data references
H+ Use long strings by default
I+ I/O checking
J- Writeable structured consts
L+ Local debug symbols
M- Runtime type info
O+ Optimization
P+ Open string params
Q- Integer overflow checking
R- Range checking
T- Typed # operator
U- Pentium(tm)-safe divide
V+ Strict var-strings
W- Generate stack frames
X+ Extended syntax
Y+ Symbol reference info
Z1 Minimum size of enum types
Stack size: -$M<minStackSize[,maxStackSize]> (default 16384,1048576)

Resources