Say I'm building an app in Racket.
And say eventually I want to compile that app as a single binary file that could be distributed to users, without them having Racket or any other software libs installed. I believe this is possible, yes?
Say in that app I want to use the snappy package https://docs.racket-lang.org/snappy/ which is some FFI wrappers around a C++ lib.
I already ran into a minor problem. I did (require snappy) inside DrRacket and followed the prompts and got the package installed but I get the error:
../../Applications/Racket v7.7/collects/racket/private/kw.rkt:1349:57:
ffi-lib: couldn't open "libsnappy.1.dylib" (dlopen(libsnappy.1.dylib, 6): image not found)
I can assume from this that racket-snappy expects the files for libsnappy to be on the usual unix path, but I'm on macos and mine is installed via Homebrew somewhere else. I believe the answer to that problem is here https://stackoverflow.com/a/24287418/202168
My concern is: I do not want users of my app to have to install these libs via Homebrew and fiddle with paths etc.
I am a Racket noob and know basically nothing about the compiler toolchain or C/C++ for that matter either. But I believe what I need is when I compile my Racket project to be able to have raco exe(?) "statically link" the libsnappy that's on my system and roll everything into a single binary with no dependencies.
So my question is: is this possible? If so, is it straightforward (i.e. managed via raco tools)?
I'm imagining in the worst case I have to download all the dependencies and build them from source and build my Racket project also as a library and then have some kind of skeleton C project that pulls them all in into one thing. I hope not.
I will add also... if this is easier in other Schemes (Chicken? Chez? Gambit? Guile?) then I'd be interested to know too.
Update: I found this article with some year-old anecdata of someone attempting the same thing https://taoofmac.com/space/blog/2019/06/20/2310
Based on that, and Ryan's answer below, raco distribute looks promising and I really need to try this out for myself to confirm what works.
Update again: Here is another article again confirming raco distribute should put everything into a folder with no external deps https://defn.io/2020/06/28/racket-deployment/ and here is a pointer to the docs for how to build a .dmg image for MacOS: https://docs.racket-lang.org/raco/exe-dist.html#(part._.A.P.I_for_.Bundling_.Distributions)
There is a partial solution using a combination of raco distribute and define-runtime-path.
Suppose you have a program that uses libzmq, which you know is installed on your build system at /usr/lib/x86_64-linux-gnu/libzmq.so.5. You can use define-runtime-path to create a reference to that file and tell raco distribute to copy it to the distribution directory. For example, suppose that "my-app.rkt" is the following:
#lang racket/base
(require racket/runtime-path)
(define-runtime-path zmq "/usr/lib/x86_64-linux-gnu/libzmq.so.5")
(printf "zmq = ~e\n" zmq)
When you run the program using racket my-app.rkt, it prints
zmq = <path:/usr/lib/x86_64-linux-gnu/libzmq.so.5>
But when you run raco exe my-app.rkt and then raco distribute MyApp my-app, then the MyApp directory will contain a copy of libzmq.so.5:
$ find MyApp/ -type f
MyApp/lib/plt/my-app/exts/ert/r0/libzmq.so.5
MyApp/lib/plt/racket3m-7.7
MyApp/bin/my-app
and if you run ./MyApp/bin/my-app, it prints
zmq = #<path:/PATH/TO/HERE/./MyApp/bin/../lib/plt/my-app/exts/ert/r0/libzmq.so.5>
You can use (ffi-lib zmq) to load the shared library. Unfortunately, that directory is not in the search path that the application will use for loading shared libraries, so existing Racket libraries that just try to load (ffi-lib "libzmq" '("5")) won't find the application's copy.
There is another way of using define-runtime-path specifically for shared libraries, and I thought it would solve that problem, but it doesn't seem to. That seems like a bug to me, so I'll file a bug report.
Update: I have filed a bug report about the fact that define-runtime-path's shared library ('so) mode causes raco distribute to copy the shared library outside of the application's library search path.
Related
I do have a strange behavior with a flutter package I am building. It uses FFI to integrate a custom-made c++ library.
When I run flutter run -d windows --release the code starts and I do have the window with the code running.
However, when I go to the directory where the executable is stored and I run it, the program starts but the library is not loaded. I do see also that when I run flutter test, it complains that it cannot load the library. I have checked that the dll's needed are there using dependenciesGUI.exe and it seems that everything is fine, at least on my side. I do see however that within kernel32.dll I am missing ext-ms-win-oobe-query-l1-1-0.dll.
I am using Visual Studio 2022 with the x64 configuration.
Any idea on what could be the issue? For me it is VERY puzzling to be able to run the software through flutter but not with the executable directly.
Thanks!
Yours,
Pi-r
EDIT:
I compared my package with a fresh package built with flutter. With a fresh package, the behavior is the one expected: I can have the program run normally or with flutter run.
I compared the libraries of the clean package with the ones linked in my package. They are the same (with the same missing dlls which do not seem to pose an issue).
I also checked that the exported functions I needed where present -> It is the case.
The only difference I can see is that using flutter run adds a series of libraries to the path. Has I am a Linux person, I do not know of a tool that could be used to detect what is the missing library. I am open to write a separated c++ code that would load the library if it could help me identify what is the issue... ANY tips/tricks would be greatly appreciated :)
I finally found the issue I had and it is related to a different behavior under Linux and under Windows (as you will guess, I am a Linux person).
When compiled under Linux, I can force the compiler to link multiple libraries relatively to my main library. I discovered that this is not the case under Windows. Either the dlls are in the executable folder or in the Path.
For the sake of code clarity, my package uses two different libraries. Library A, which is compiled from flutter with the ffi package, called library B. First the second library was in the asset folder and with the relative linking of Linux, it was working perfectly. But it did not work under Windows until I explicitly copied the two in the same directory of the executable.
The solution was then to ensure that both libraries are copied correctly in the directory of the flutter executable. This can be done easily if you add the dependent libraries to the bundle variable in the CMakeLists.txt of the package.
However, this doesn't work when you do the testing (flutter test). As the bundle mechanism seems to be not propagated to the test function. Therefore here, the only solution is to copy the dependent libraries to the root directory of the source code :vomiting_face:
I must point out that this is only the case under Windows, for Linux, it works out of the box...
I'm learning Common Lisp (Clozure CL) on the Mac and would like to create a simple GUI. I have downloaded the "ltk" library from CLiki and put it into the project directory at the root level (I assumed I had to do this as I couldn't find instructions for a beginner).
Page 4 of the "LTK - a Lisp binding to the Tk toolkit" documentation says that the library should be compiled using (compile-file "ltk") before loading the library using (load "ltk"). However, I get this error message:
Error: File #P"/Users/myName/Desktop/lisp_experiments/GUI_EXAMPLE/ltk" not found
While executing: CCL::FCOMP-FIND-FILE, in process Listener(4).
Type cmd-. to abort, cmd-\ for a list of available restarts.
Type :? for other options.
I also used the full file pathname and got the same error.
What am I doing wrong?
Thanks for your help.
Marc
ps - there are almost no noob tutorials about this sort of thing online that takes the user through the process step by step.
I have downloaded the "ltk" library from CLiki and put it into the project directory at the root level.
Nowadays, this is a step that is seldom required, because libraries are easily accessible using Quicklisp (see also this gif).
Basically, you should be able to install Quicklisp and run the following:
(ql:quickload "ltk")
The above downloads, compiles and install Lisp libraries, but not necessarily the required C libraries, which you might need to install separately. If the above works without problem, then the following should work too:
(ltk:ltktest)
Quicklisp relies on Lisp systems being described with ASDF (Another System Definition Facility). The best practices document is also interesting to read.
In the case of LTK, you can see that ltk.asd only specifies one component, ltk.lisp. When you install the system named "LTK", quicklisp will do all the necessary work to install its dependencies, then compile and load ltk.lisp, as described in the manual.
What is unclear is why your explicit compile-file failed.
I found the ltk.lisp file on my machine; its pathname looks like:
#P"/home/user/quicklisp/dists/quicklisp/software/ltk-20150113-http/ltk.lisp"
Sure enough, calling compile-file with that pathname works and returns another pathname which ends in .fasl (the object format). Loading the returned pathname loads the library. Please provide more information about the error so that we can help you debug this problem.
I have a Cocoa application that uses OpenCV, TBB, boost and some other libraries which are installed in my system. How do I create a package that has all this inside so that customer doesn't have to install anything besides just copy/paste my package?
At the building stage they are referenced via .dylib .
Is it possible?
Where I choose in xCode Product\Archive it will only export the app itself.
well, after a lot of reading I could not find an easy solution. Maybe is there, but I didn't have more time to search for it.
So instead I wrote a small application in C++ that uses otool and install_name_tool utilities to analyze needed required libraries and copy them into the bundle. Is located here https://github.com/integral-llc/libb . Keep in mind, it was made for personal use, but can be easily changed for anything else.
It worked perfectly for my case. It found all needed dependencies for OpenCV, boost, TBB.
if you have better tools or ideas to improve current one, you are more than welcome to say.
I'd like to use open source library on Windows. (ex:Aquila, following http://aquila-dsp.org/articles/iteration-over-wave-file-data-revisited/) But I can't understand anything about "Build System"... Everyone just say like, "Unzip the tar, do configure, make, make file" at Linux, but I want to use them for Windows. There are some several questions.
i) Why do I have to "Install" for just source code? Why can't I use these header files by copying them to the working directory and throw #include ".\aquila\global.h" ??
ii) What are Configuration and Make/Make Install? I can't understand them. I just know that configuration open source with Windows need "CMake", and it is configuration tool... But what it actually does??
iii) Though I've done : cmake, mingw32-make, mingw32-make install... My compiler said "undefined references to ...". What this means and what should I do with them?
You don't need to install for sources. You do need to install for the libraries that get built from that source code and that your code is going to use.
configure is the standard name for the script that does build configuration for the software about to be built. The usual way it is run (and how you will see it mentioned) is ./configure.
make is a build management tool (as the tag here on SO will tell you). One of the most common mechanisms for building code on linux (etc.) is to use the autotools suite which uses the aforementioned configure script to generate build configuration information for use by generated makefiles which make then uses to build the software. make is also the way to run the default build target defined in a makefile (which is often the all target and which usually builds the appropriate library/binary/etc.).
make install is a specific, secondary, invocation of the make tool on the install target which (generally) installs the (in this case previously) built code into an appropriate location (in the autotools/configure universe the default location is generally under /usr/local).
cmake is, again as the SO tag says, a build system that generates configuration files for other build tools (make, VS, etc.). This allows the developers to create the build configuration once and build on multiple platforms/etc. (at least in theory).
If running cmake worked correctly then it should have generated the correct information for whatever target system you told it to use (make or VS or whatever). Assuming that was make that should have allowed mingw32-make to build the software correctly (assuming additionally that mingw32-make is not a distinct cmake target than make). If that is not working correctly then something is still missing from your system (and cmake probably should have caught that).
But to give any more detail you will need to give more detail about what errors you are actually getting and from what command.
(Oh, and on Windows, and especially if you plan on building your software with VS (or some other non-mingw32-make tool) the chances of you needing to run mingw32-make install are incredibly small).
For Windows use cmake or latest ninja.
The process is not simple or straight, but achievable. You need to write CMake configuration.
Building process is not simple and straight, that's why there exists language like Java(that's another thing though)
Rely on CMake build the library, and you will get the Open-Source library for Windows.
You can distribute this as library for Windows systems, distribute and integrate with your own software, include the Open Source library, in either cases, you would have to build it for Windows.
Writing CMake helps, it would be helpful to build for other platforms as well.
Now Question comes: Is there any other way except CMake for Windows Build
Would you love the flavor of writing directly Assembly?
If obviously answer is no, you would have to write CMake and generate sln for MSVC and other compilers.
Just fix some of the errors comes, read the FAQ, Documentation before building an Open Source library. And fix the errors as they lurk through.
It is like handling burning iron, but it pays if you're working on something meaningful. Most of the server libraries are Open Source(e.g. age old Apache httpd). So, think before what you're doing.
There are also not many useful Open Source libraries which you could use in your project, but it's the way to Use the Open Source libraries.
I want to develop a programm in Go with a multi-OS GUI in wxWidgets, my dev environment is WinXP x86.
I wanted to use the wxWidgets Go wrapper wxGo, but the documentation is very succint and the project seems dead since 2 years.
I encountered some errors with the go get github.com/JeroenD/wxGo and go install github.com/JeroenD/wxGo
Result of go get github.com/JeroenD/wxGo:
package github.com/JeroenD/wxGo
imports github.com/JeroenD/wxGo
imports github.com/JeroenD/wxGo: no Go source files in C:\Documents and Settings\dell\Mes documents\gopath\src\github.com\JeroenD\wxGo
Result of go install github.com/JeroenD/wxGo:
can't load package: package github.com/JeroenD/wxGo: no Go source files in C:\Documents and Settings\dell\Mes documents\gopath\src\github.com\JeroenD\wxGo
I tried to follow the Building.txt doc from JeroenD's github. First time, I downloaded and installed wxWidgets, the sample codes were able to compile (with MinGW), but I was not able to compile the wxWidgets library from source. The second time, I downloaded and installed wxPack, with libs/dll already compiled. Here, the problem is I can't compile the wxWidgets samples.
As stated in the Buiding.txt doc from JeroenD's github, I installed SWIGWIN, but did not compile it from source as SWIG now supports Go (from SWIG's documentation). But now, I don't know what to do with a wrapper (wxGo), wxWidgets dll/libs, and SWIG. I think I read that SWIG needs *.i files to make bindings from language to another, but I can't find any in my wxWidgets folder, perhaps I have to take these files from another wxWidgets binding (wxLua and wxPython have these in their repos).
My goal is just to get the wxWidgets lib working with Go to be able to write a multi OS GUI in wxWidgets, I'm a bit surprised that nobody had posted problems with JeroenD's package nor wanted to get wxWidgets working with Go.
As you may ask, building a gtk GUI with go-gtk is not a solution, as it is needed in my project to have a multi-OS GUI looking OS native (if you have a multi-OS GUI lib which looks native and is simpler to use, please tell me).
According to the Building.txt file:
To build the wxGo library:
cd wx
make install
So, despite this being a Go package, it doesn't seem to use any actual Go code (if you look in github.com/JeroenD/wxGo you won't see any .go files).
I think, in cases like this, you need to use git (instead of go get) and make install instead of go install.
On windows you may want to get the Git for Windows installer to make this process a bit simpler.
Once it's built it looks like you can use
import "wx"
as usual in your go code (minimal example at https://github.com/JeroenD/wxGo/blob/master/example/minimal/minimal.go)
wxGO wxWidgets wrapper for GO is live here wxGO MultiOS
QML may be a better choice, it helps deal with wxWidget or QT underwear.