I'm having trouble getting executables compiled from Haxe source to work on computers that don't have Haxe installed. The problem first appeared with a simple networking program but it seems to come up for any program at all. Even something like
class Test
{
static function main()
{
trace("test");
}
}
compiled to an exe with haxe -main Test.hx -neko Test.n and nekotools boot Test.n will run on my computer but on anything else gives a neko.dll is missing from your computer error. I get a similar error if I compile the haxe source to c++ or c# and run the generated exe.
I'm not sure what neko.dll is, but I don't see how it should be required for the exe to run. I feel like I must have some basic misconception! Is this intended behavior? How can I compile Haxe code so that it will run on any windows machine without installing neko?
neko.dll is normally located at C:\HaxeToolkit\neko. You may just copy and paste that next to the exe.
Generally when distributing a exe, you have to also distribute the required dlls. You can check the dll dependency with various tools. For example, using Dependency Walker, open the exe by it and it will list out the dlls. Right click a dll item in its menu and select properties, there you will find where it locates.
Related
I have built Game Music Emu from source to use with Love2d. (Note: I am not very familiar with C/C++.)
In lua I load the dll with FFI and on my computer it works great, but when I sent my friend the app for testing, his machine doesn't recognize the DLL.
I sent him the love2d binaries with the libgme DLL included to make sure he didn't just misplace the DLL file. So what he is running is the exact same thing I am running.
My code looks like this:
ffi.cdef[[ ... ]]
local gme = ffi.load("libgme")
This is the exact error my friend gets:
lovegme.lua:4: cannot load module 'libgme.dll': The specified module could not be found.
Depending on how libgme is compiled you may have some dependencies that are satisfied on your computer (for example, mingw libraries), but not satisfied on the other computer.
I'd try several things: (1) use the full filename in the load command, (2) use "profile" mode in dependency walker to check what is failing during DLL load, or (3) use the same dependency walker on your machine to see what other DLLs libgme may depend upon and include those in your package/installation as well.
I've dynamically linked libhunspell.dll (HunSpell) to my application. It works, but there is a dumb problem which I don't know why it happens.
Even before I use LoadLibrary("path\\to\\libhunspell.dll"); to load it and use it, on the start of the application it attempts to load the library by itself. If I place the libhunspell.dll into the path where my main executable resides, it can load it, otherwise it reports an error, immediately after starting the application - This application has failed to start because LIBHUNSPELL.DLL was not found. Re-installing the application may fix this problem. and the application doesn't start.
I would understand if the LoadLibrary would use invalid path but this happens as soon as the executable runs, even before the first statement in WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) executes (I've tried to place a breakpoint and it doesn't even reach it, so this happens before).
So, as a result, I must place libhunspell.dll in the same folder as my application executable, and not in the path I want.
This is probably easy to fix although I don't what to look for.
So the question is - how do I avoid it loading it immediately and have it wait until I use LoadLibrary call?
Here is how I linked if it can help:
1) compiled libhunspell.dll in Visual Studio 2015 (I used /MT option to link it statically so it doesn't have VC++ Redistributable as a dependency).
2) created import library (libhunspell.lib) using implib.exe -a -c -f libhunspell.lib libhunspell.dll
3) linked that to the source .cpp unit which is using it using #pragma comment(lib, "libhunspell.lib") (it is RAD Studio 2010 so the .lib is required unlike newer versions).
4) later in the same .cpp used LoadLibrary to load this library and used it.
By linking in the import stubs (libhunspell.lib) the OS will load the DLL for you as it is now a static dependency.
One approach would be specify the library as a delayload dependency: /DELAYLOAD:libhunspell.lib via the linker options. You can then call LoadLibrary on the DLL.
The only other option is to stop including the .lib in the linker step, making it truly a dynamic dependency.
I assume you did Add to project a *.lib file for your DLL. That is a kind of "static" linkage done in the App initialization (prior to your forms are created). So it has two disadvantages.
You DLL must be in the same path as the Apps EXE file
Sometimes DLL file name is locked (can not be changed)
The advantage is that you do not need to do any coding for the DLL loading as the VCL do it for you ... so your app should not contain the LoadLibrary,GetProcAddress calls you just include the *.h file with propper import declarations ...
For dynamic linkage you need to remove the *.lib from your project and use WinAPI LoadLibrary + GetProcAddress for loading your DLL as josh poley suggested. Here an example:
Builder C++ calling VC++ class
Beware there was/(is?) a bug in the GetProcAddress preventing from loading all the functions from your DLL in some cases. Especially if the DLL has old legacy mangling of names the count of functions is high and the DLL was created on compiler incompatible with the mangling in question.
I have compiled Lua 5.3 as a 32 bit c++ DLL and exe. The DLL contains all the lua code except for lua.cpp and luac.cpp. The exe compiles lua.cpp and uses the DLL to run the lua interpreter. This works fine when running on its own from the command line. I wish to be able to run from the IDE using this DLL and exe.
If I replace /ZeroBraneStudio/bin/lua53.dll and lua53.exe with my own versions, I can run scripts (clicking the two green arrows). However, debugging does not work, giving the following error:
The procedure entry point luaL_addlstring could not be located in the dynamic link library lua53.dll.
I can see that this is happening because the debugger is making use of luasocket. \ZeroBraneStudio\bin\clibs53\socket\core.dll is dependent on lua53.dll, and is expecting it to contain lua compiled as c.
So, what is the correct solution to this - is it to compile luasocket as c++ as well?
(And, if so, does anybody have instructions/guidance for doing so? I have been unable to find anything on this.)
Thanks.
I'm not sure how exactly the DLL was compiled, but the error message likely indicates that the luaL_addlstring and other functions are not exported by it. If the symbols are exported correctly, you should be able to load luasocket and get the debugging working. See this thread for the related discussion.
Also, you don't need to replace lua53 library and executable, as you can configure the IDE to use your own copy of it using path.lua53 configuration setting as described in the documentation.
Okay, I was able to get it working. The solution was to compile luasocket as c++. I won't give full instructions on how to do this here, but some points to hopefully help anybody else with the same issue:
Got luasocket from here: https://github.com/diegonehab/luasocket
Renamed all *.c files to *.cpp
Renamed Lua52.props to Lua.props (I am using lua 5.3 but seems like it is compatible?)
Placed lua headers and lib in appropriate folders
Opened solution in Visual Studio 2012
Fixed up minor issues with project files, like the renaming of the files.
Added 'extern "C"' to declaration of luaopen_socket_core and luaopen_mime_core functions (necessary for lua to be able to load libraries).
Built solution
Copied new dlls into clibs53/socket and clibs53/mime folders.
I used Dependency Walker to help with this. If anybody wants further details in the future please leave a comment.
Trying investigate how to create "Hello world" on different languages via HaxeDevelop. I'm newbie and may be inacurate at terminology.
1) C# project. Pressing F8 gives me error:
haxe -cp src -cs D:/Programs/Projects/CsTestHaxe/bin/ -main Main
Unix.Unix_error(8, "mkdir", "D:/Programs/Projects/CsTestHaxe/bin/")
Build halted with errors (haxe.exe).
Via googling pretty much outdated info at least found solution:
haxe -main Main -cs out
And it works but ouput go to "src" location which is bad. Next googling led me to "Custom build" and using .hxml with pre-build command at project settings.
But why default template/settings not works for such simple thing as "Hello world" (used cs.system.Console)?
How default build may be fixed / probably I've installed or setup something wrong via HaxeDevelop installation?
2) C++ project. Pressing F8 gives me error:
Warning: Could not find environment variables for Visual Studio
Missing HXCPP_VARS
Error: Could not automatically setup MSVC
Error: Build failed
Build halted with errors (haxe.exe).
Using command line (similar to C# above) I can exucute C++ sources, but cant compile it.
Installed Visual Studio Community 2017. Nothing changed, same error. VS provide different own parts for installation. Should I install any specific?
Found also many threads about OpenFL workaround for C++ compilation. But I needn't OpenFL and want to use default Haxe API and tools.
Also OpenFL and C++ always mentioned with Lime. Do I need it too? Installed Lime via command line. But seems nothing changed.
3) Am I right that HaxeDevelop not yet support HashLink?
And if possible couple words about why HashLink appeared if there is Neko affiliated with Haxe?
As a result here an additional question: is it right that Haxe during compilation to target platform only "convert" .hx source to target one and then using third party (target platform) compile?
1) C# project. Pressing F8 gives me error.
This appears to be a known Haxe issue. Since it's been fixed on the dev branch, you could try a nightly build from build.haxe.org. Alternatively, you could also try manually creating the bin directory, since that seems to be what the error is about.
2) C++ project. Pressing F8 gives me error:
The latest Haxelib release of hxcpp (3.4.64) does not support Visual Studio 2017 yet. You could use a development version by installing hxcpp from GitHub, since again, it should be fixed there:
haxelib git hxcpp https://github.com/HaxeFoundation/hxcpp
The alternative is to downgrade Visual Studio.
Also OpenFL and C++ always mentioned with Lime. Do I need it too?
Yes, if you want to use OpenFL, you also need Lime, as OpenFL depends on it.
3) Am I right that HaxeDevelop not yet support HashLink?
Actually, a HashLink project template was added. But to follow the general theme of this answer, it seems it hasn't made it into an official relase yet. You can get a nightly build from here.
And if possible couple words about why HashLink appeared if there is Neko affilated with Haxe?
There is a two-part blog series on haxe.org by HashLink's author: part 1, part 2. The first part has a paragraph talking about this exact topic. Here's an excerpt:
First, let me explain the reasons for writing another virtual machine in replacement of Neko.
[...]
Back then, the Neko virtual machine was not especially designed to run Haxe and suffered from some limitations, the main one being performance.
[...]
And to your final question:
is it right that Haxe during compilation to target platform only "convert" .hx source to target one and then using third party (target platform) compile?
That is true for some targets, but it depends. For C++, C# and Java, Haxe indeeds generates source code for the target language and then invokes the target-native compiler after doing its own compilation (this step is usually called "native compilation").
However, some targets produce byte code directly (SWF and Neko), so there is no native compilation step there. Other target languages are interpreted (JS, PHP, Python and Lua), so there's no native compilation step there either. For HL it actually depends, there is HL/Jit (byte code) and HL/C, which is compiled to native C code.
You can find a comprehensive list of Haxe targets an their characteristics here.
Phew, that was a lot of questions in one. ;)
I send a Racket executable(in a distribution package) to a few friends and they get the error:"Failure: can not load the DLL". On my computer it runs without problems. It's using the rsound package.
Yes, good point. Currently, rsound is hard-coded to look in the collection path for the DLL. That won't work for programs compiled into executables. I've just updated rsound to tell it to look in "standard locations" as well for Windows and Mac.
Try this: Using the DrRacket package manager, update your copy of portaudio. When you're done, it should be at version "b9403a6dfbfb5eadf824ed91731ec141bf363677".
After this, it should be possible to pass along the executable file and run it, as long as the two required dll's are in the same directory as the executable. These two dll's are:
portaudio.dll
callbacks.dll
For windows, you'll find both of these in a subdirectory of the portaudio package. Finding these is going to be a teensy bit of a hassle on Windows; I believe these get installed in your user directory\RoamingData\\portaudio\lib\win32\x86_84\3m\ . If the target computer is a 32-bit machine, you'd substitute 'i386' for 'x86_64' in that path.
I know that Windows can make it quite hard to find the files you're looking for; let me know if you have any trouble.
Whew!