"flutter run -d windows --release" works but executable doesn't - windows

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...

Related

Linker error building Adobe DNG SDK on MacOS 11

I am working on a project that uses Adobe's DNG SDK 1.6 library, and it is supposed to work on Windows and MacOS.
The library has instructions on how to build it for both platforms, but I had to figure out an error that came up on Windows with Visual Studio. I am not very experienced with big C++ projects so it was not trivial but I got it working. Most of my own code will be done in C# .Net Core, calling the native libraries using a wrapper class with P/Invoke.
Now for Mac that's a different story, I have a MacOS 11 VM, installed Xcode 12.5.1 and followed the steps provided, as expected, it does not work. Bare in mind this is my first time touching Xcode and MacOS.
The project I am trying to build is dng_validate, and it depends on two libraries built by these projects: XMPFiles64 and XMPCore64.
The library projects build without any hiccups, each one of them creating a ".a" file in the folder: dng_sdk_1_6/xmp/toolkit/public/libraries/macintosh/intel_64_libcpp/Debug, they are named libXMPFilesStaticDebug.a and libXMPCoreStaticDebug.a respectively.
When I try to build the dng_validate project, I get the following error:
Library not found for -lXMPFilesStaticDebug
Because of the the error starting with an "l" instead of "lib", under both libraries project settings, I changed the "Executable Prefix" setting to "l" instead of "lib". Rebuilt both of them and made sure the file names changed as expected. But the error persists when trying to build the main project.
Under dng_validate's project settings, there is a setting called "Library Search Paths" and it does point to the proper aforementioned folder using a relative path. I even changed it to an absolute path to see if that would make it work.
I am really lost here, does anyone have an idea of what might be causing it?
Well... After asking on other forums and almost hiring a freelancer to fix this for me, I tried another shot in the dark of renaming the library files and it worked.
I changed the extensions of libXMPFilesStaticDebug.a and libXMPCoreStaticDebug.a from ".a" to ".dylib" and it just compiled and blew my mind with it.

Racket/Scheme compile to single binary, no dependencies? FFI and static linking

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.

wxwidgets platform.h error: no such file or directory wx/setup.h

I am using Code::Blocks with wxwidgets and I have include and lib folders under Document\wxwidgets. I am very new to c++ libraries. In Code::Blocks project initialization, I entered the location for wxwidgets. Then in setting/global enviornment variables I entered in base the Document\wxwidgets again. Still, I am not able to run the app. It shows the error in the include/wx/platform.h file where it says
C:\Users\Programming coder\Documents\wxwidgets\include\wx\platform.h|148|fatal error: wx/setup.h: No such file or directory|
I am not able to solve this and would appreciate some help. Also I checked and the wx folder does not seem to be there in the location. I don't know if that is normal.
Also, I downloaded the headers(include) from the wxwidgets github repo download page, wxWidgets-3.1.1-headers.7z. Any help appreciated.
Also, I am aware some questions exist already, but their problems are in different because most are using linux. Also I am using Code::Blocks IDE.
You need to build wxWidgets itself before building the applications using it. Its build process will create the setup.h file which is currently missing.
Note that, in principle, you could also use precompiled binaries, but in this case you must use exactly the same compiler as was used for compiling them, i.e. TDM gcc.

Cross compiler default include path setup

First, some background: I'm attempting to write drivers and applications for Android on the Beagleboard-xM.
I've downloaded their android development kit, installed it, and can succesfully build everything in it using the directions at http://processors.wiki.ti.com/index.php/TI-Android-ICS-4.0.3-DevKit-3.0.0_DevelopersGuide
I've been able to make my own skeleton kernel module following the steps in http://tldp.org/LDP/lkmpg/2.6/lkmpg.pdf without issues. I can copy the .ko file to the android device, insmod, rmmod, etc.
I got tired of the basic shell given by the default build and thought I'd add busybox. I tried following the directions at http://omappedia.org/wiki/Android_Installing_Busybox_Command_Line_Tools, but I get a compile error on standard libc header files.
After digging around quite a bit, I've determined that the pre-built cross compiler provided in the TI android development kit wasn't searching the right paths.
I confirmed this by creating my own .c file that included and tried to compile it with
arm-eabi-gcc blah.c -o blah
and was met with the same results (unable to find the header file in question)
'arm-eabi-gcc -print-prog-name=cc1' -v gives me this:
ignoring nonexistent directory
"/usr/local/google/home/android/cupcake_rel_root/usr/local/include"
ignoring nonexistent directory "/usr/local/lib/gcc/arm-eabi/4.4.3/include"
ignoring nonexistent directory "/usr/local/lib/gcc/arm-eabi/4.4.3/include-fixed"
ignoring nonexistent directory "/usr/local/lib/../arm-eabi/include"
ignoring nonexistent directory "/usr/local/google/home/android/cupcake_rel_root/usr/include"
None of these paths ever existed on my fresh install of ubuntu 10.04. My cross compiler I used is at /usr/TI-Android/prebuilt/linux-86/toolchain/arm-eabi-4.4.3/. I didn't do anything except run the bit .bin file that was the android development kit (which seemed more like simply extracting itself from the .bin file; I don't remember it doing anything else)
So, a few questions:
how the heck did everything else (i.e. android, x-loader, u-boot, the kernel) build by just putting the bin of the cross compile tool into $PATH (like the how-to documents say). I assume it (make menuconfig?) does some magic in fixing up the include paths based on the location of the executable, but...
Why doesn't busybox work the same way since it seems to be built with a similar looking infrastructure?
How do I make it so I can cross compile my own applications?
I assume I've missed a step and should have done some sort of install/configure on the pre-built cross compiler, but information is horribly scant. I appeal to you, open source gods, to point my way across this dark and stormy sea.
For posterity, it seems that the prebuilt tools included with the android development kit are only enough to build the kernel and don't include libc or other library header files. (The NDK tools are 'different' and the build environment is even more different because it has its own version of libc--bionic. That build environment might have been able to build what I wanted, but I would have had to muck with Androidy makefiles, etc.)
I ended up having to get Code Sourcery arm-none-linux-gnueabi (must get the linux-gnueabi one to have the linux system header files needed), and everything worked reasonably smoothly after that.

Qt4 Program Crashing Unless SDK Installed

I've written a Open Source program that I've released as GPL built using the Qt4 LGPL SDK. This program has the ability to search an optional Sqlite3 database for data.
Here is what is making me lose my mind. I compile the program on the development machine. When I try to run it, I can errors about missing DLLs. I copy those dlls into the same directory as the executable and it now works fine ( mingwm10.dll, libgcc_s_dw2-1.dll, QtCore4.dll, QtSql4.dll, QtGui4.dll ), including the database search.
Now, if I copy that folder with the executable and the DLLs to a new machine that has not had the SDK installed on it, it runs fine until I try to search. As soon as I hit the search button, I can the following error:
Title: Microsoft Visual C++ Runtime Library
Runtime Error!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I then download and install the SDK, doing nothing else, I can now run the program and search the sqlite3 file just fine!
What magic am I missing?
P.S. Both machines are freshly installed Windows XP systems.
You may have some libs or Qt plugins that are not deployed to the target machine. It most likely is the SQL driver plugin. Here's some info about it: http://doc.trolltech.com/latest/deployment-windows.html#qt-plugins
You'll need to copy the needed Qt plugins to a directory next to your executable. And add something like this in your main():
QApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/plugins");
(Edited link and added code)
I found the problem.
Stephen Chu was correct in that I was missing the sqlite driver. However, I can into more complications along the way.
The SDK comes with two sets of dlls. One set resides in $BASEDIR/bin and the other in $BASEDIR/qt/bin. The former contains the dlls used by Qt Creator, while the latter are the dlls that you want to ship with your executable.
I needed to take the sqlite plugin ( qsqlite4.dll ) and copy it to APP_DIR/sqlplugins. My problem was I was using the wrong qsqlite4.dll file.
A big thanks to everyone who contributed to this question.
For future reference, this issue was also discussed here: http://www.qtforum.org/article/34639/qt4-program-crashing-unless-sdk-installed.html

Categories

Resources