There is a lib-sys for libvips on crates.io, however it uses pkg-config which searches the system for the library to link to dynamically, not statically.
I want to provide libvips with the final binary of my software in .dll or .exe along with it since the user should only install one executable with everything in it, C and Rust code.
Looking at the Rust book's FFI linking section, we can link lib.a files easily, but libvips is a huge complex C library that has releases for Windows in .dll and .exe format. I do not know how to link these Windows binaries of libvips to a Rust program statically.
Potentially, I could build it from source manually and link it manually, but the build process seems very complex and it uses scripts and Docker. I would have to replace those scripts with a build.rs of my own that did the same but that seems very hard to me since I'm a beginner at this. I know I would have to set rustc-link-search in build.rs, but I don't know how to compile the .a files for libvips. Rust book on this
My goal is to FFI into libvips from Rust. I am using Windows 10 and want to cargo build the project and have the Rust code and libvips in one distributable binary with no other dependencies.
edit-1:
the vips-dev-w64-web-x.y.z.zip contains libvips.lib , libvips.dll.a files, pkgconfig .pc files, as well as the normal .dll and vips.exe. Can i use these .lib and .a files and if so exactly how? Will it link statically? Are these .pc files useful for my situation?
Just ship the libvips bin area in your tree somewhere, add it to PATH on startup, and link dynamically. This is how electron apps and node.js packages that use libvips work. Static linking for complex libraries died a while ago, it's not worth trying.
As much as anything, it would be a potential licence violation. libvips is LGPL, so you MUST link dynamically (or include enough of your code to allow relinking), or your whole application becomes open source.
Related
I just compiled a SDL2 program in MSYS2 and would like to distribute a binary copy of the program in a ZIP file.
But to run the program in "Normal" Windows I have to copy a long list of DLLs from /mingw64/bin.
Is there a better way of doing this? maybe linking statically?
How would the license work either way?
My own program is BSD 3 clause.
I'm using SDL2, SDL2_image, SDL2_ttf and all their dependencies.
You can build statically. The licensing situation in your case makes no difference between static/dynamic linkage.
I'm not sure how you build but here is an example with CMake: CMake - Compile in Linux, Execute in Windows
(In the example the binary is cross-compiled but the static stuff is the same for native compilation as well).
I just found out that all library licenses are located in /mingw64/share/licenses
So it's pretty easy to copy the needed licenses to the ZIP file.
I recently made a small library in C, and I wanted to put it together with the standard libraries so I don't have to always copy the files for each new project.
Where do I have to put it so I can import it like the standard libraries?
Compiler : MinGW
OS: Windows
You need to create a library, but you don't necessarily need to put it in the same place as MinGW's standard libraries (in fact I think that's a bad idea).
It is better to put your own library/libraries in specific place and then use the -I compiler flag to tell the compiler where to find the header files (.h, .hpp, .hh) and the -L linker flag to tell the linker where to find the library archives (.a, .dll.a). If you have .dll files you should make sure they are in your PATH environment variable when you run your .exe or make sure the .dll files are copied in the same folder as your .exe.
If you use an IDE (e.g. Code::Blocks or Visual Studio Code) you can set these flags in the global IDE compiler/linker settings so you won't have to add the flags for each new project.
Then when building a project that uses your library you will need to add the -l flag with the library name to your linker flags, but without the lib prefix and without the extension (e.g. to use libmystuff.a/libmystuff.dll.a specify linker flag -lmystuff). The use of the -static flag will tell the linker to use the static library instead of the shared library if both are available.
I have created a minimal example library at https://github.com/brechtsanders/ci-test to illustrate on how to create a library that can be build both as static and shared (DLL) library on Windows, but the same code also compiles on
macOS and Linux.
If you don't use build tools like Make or CMake and want do the steps manually they would look like this for a static library:
gcc -c -o mystuff.o mystuff.c
ar cr libmystuff.a mystuff.c
To distribute the library in binary form you should distribute your header files (.h) and the library archive files (.a).
I've written a little C program which uses libusb. Now I want to distribute this program to "normal" (not dev) Mac OS X computers. But when I ported the compiled file to a test machine I got the following error:
dyld: Library not loaded: /opt/local/lib/libusb-0.1.4.dylib
Referenced from: /Users/kitty/myprogram
Reason: image not found
Trace/BPT trap: 5
When I copy the files (works only with all the files)
/opt/local/lib/libusb-0.1.4.dylib /opt/local/lib/libusb-1.0.a
/opt/local/lib/libusb.a
/opt/local/lib/libusb-1.0.0.dylib /opt/local/lib/libusb-1.0.dylib
/opt/local/lib/libusb.dylib
from my machine to the target machine the program works flawlessly.
But I really want to create or compile everything into a single executable. How is this possible?
Using -static while compiling does not work since not all libraries can be compiled into the final app statically (see this SO question here).
So how can I make a single neat little application file?
You can convert a static library to a dynamic library, but I'm not aware of a way to do the reverse as you want it.
If you're building an app with a bundle, you need to put the library you want to distribute inside your bundle, in the Frameworks directory, and link against that.
If you are not building a bundle-based app, just a single binary, you may need to provide instructions for your users on how to install the library on their system (e.g. via Homebrew).
Here's how you do it for bundle-based apps:
Apple has a document about run-path dependent libraries but doesn't actually explain how to set this up for a newbie.
Here's how it should work:
Add the libusb.dylib you want to use to your project.
It should automatically get added to your "Link Binary with Libraries" phase in your project's "Build Phases". If not, add it here.
Add a new "Copy Files" build phase.
In the "Destination" drop-down box, select "Frameworks". This is the
Frameworks directory in your app's final bundle.
Then press the "+" icon in that copy build phase and add your library.
If you had any manual linking options like -L/usr/local/lib and -lusb, remove them.
Clean and build.
When you now look into your app bundle, you'll see that the library is copied to <bundle_path>/Contents/Frameworks/. You can now start the app from wherever you want, the dynamic link loader knows it needs to look at <path_to_binary>/../Frameworks/ to find your library.
But: you may need to rebuild your libusb to have the install_name set to #rpath/../Frameworks/libusb.dylib or use the install_name_tool CLI tool fix that path for your copy of libusb.dylib that you added to your project.
it is awkward, but until now i always copy the *.h and the *.c files to my projekts location. this is a mess and i want to change it!
i want to build my own c library and have a few questions about it.
where should i locate the *.h files?
should i copy them in the global /usr/include/ folder or should i create my own folder in $HOME (or anywhere else)?
where should i locate the *.a files and the *.o files and where the *.c files.
i am using debian and gcc. my c projects are in $HOME/dev/c/.
i would keep my lib-sources in $HOME/dev/c/lib (if this is the way you could recommend) and copy the *.o, *.a and *.h files to the location i am asking for.
how would you introduce the lib-location to the compiler? should i add it to the $PATH or should i introduce it in the makefiles of my projekt (like -L PATH/TO/LIBRARY -l LIBRARY).
do you have anny further tips and tricks for building a own library?
I would recommend putting the files somewhere in your $HOME directory. Let's say you've created a library called linluk and you want to keep that library under $HOME/dev/c/linluk. That would be your project root.
You'll want a sensible directory structure. My suggestion is to have a lib directory containing your library and an include directory with the header files.
$PROJECT_ROOT/
lib/
liblinluk.so
include/
linluk.h
src/
linluk.c
Makefile
Compiling: When you want to use this library in another project, you'd then add -I$PROJECT_ROOT/include to the compile line so that you could write #include <linluk.h> in the source files.
Linking: You would add -L$PROJECT_ROOT/lib -llinluk to the linker command line to pull in the compiled library at link time. Make sure your .so file has that lib prefix: it should be liblinluk.so, not linluk.so.
A src directory and Makefile are optional. The source code wouldn't be needed by users of the library, though it might be helpful to have it there in case someone wants to remake the .so file.
As I commented, you should try first to build and install from its source code several free software libraries, e.g. like libonion or gdbm or GNU readline etc (don't use any distribution package, but compile and install these from source code). This will teach you some good practice.
You probably want to install these libraries system-wide, not for your particular user. Then, assuming that your library is called foo (you need to give it some name!),
the header files *.h go into /usr/local/include/foo/
the shared objects (dynamic libraries) go into /usr/local/lib/libfoo.so (with perhaps some version numbering)
if relevant, static library go into /usr/local/lib/libfoo.a
You need to add once /usr/local/lib/ into /etc/ld.so.conf and run ldconfig(8)
and you usually don't want to copy any source file *.c or object file *.o
(except for homoiconic programs, bootstrapped compilers, Quine programs, generated C code, etc... See RefPerSys or Jacques Pitrat systems as an incomplete example of self generated C or C++). In some weird cases, you may want to copy such "source" or "generated C" code under /usr/src/.
Read Program Library HowTo (and later, Drepper's paper: How To Write Shared Libraries)
You could consider making your library known by pkg-config. Then install some foo.pc under /usr/local/lib/pkgconfig/
BTW, I strongly suggest you to publish your library as free software, perhaps on github or elsewhere. You'll get useful feedback and could get some help and some bug reports or enhancements.
You probably should use some builder like make and have an install target in your Makefile (hint: make it use the DESTDIR convention).
I have to use LU decompostion to fit a simple model to some data (simulated) in C. An example of what I need to do is here:
However, I'm stuck with a more basic problem: how do I install packages in C and call them in my code?
I'm new in C and I'm used to R. But I have this assingment to do some tests about Matrix inversion, LU decomposision and the professor suggested using Lapack to easy things (thus, I don't need to code myself the LU decomposition etc.). But I don't know how to install the package and call it in my code, in order to use the functions of LAPACK.
I have a windows 7 64 bits and I'm using compiler Code Blocks 8.02
Thanks for any help.
Normally you don't "install" C libraries in that sense. Normally, in Windows you have three types of files. The header files, typically ending in .h, the dynamic library, .dll, and most likely some linker files (typically, .lib, .a or something). The linker and compiler will need to be able to find these files somewhere. Normally you set the include directory paths, and library directory paths.
E.g. Let's say you downloaded a library called foo, and you extract it to C:\foo.
In that folder, libfoo.a, foo.dll and foo.h reside. In Code::Blocks you will have to point include directory path to C:\foo and library path to C:\foo so that the linker and compiler know where to look for these files. Since you're linking against the foo library, you will also have to set -lfoo or something similiar in linker command line. This is GCC syntax, but I think Code::Blocks uses GCC compiler behind the scenes anyways.
In the C code you can just #include <foo.h> and the compiler will find it for you.
You need to install that library and it might actually supply a tool for that. Check their documentation (e.g. a file INSTALL or README in their distributed sources). If the library uses only headers you might only need to copy it's headers to some directory on your system, but their buildsystem might be able to do that for you.
Once that is done you would tell your IDE on where to look for the sources and if the library uses not just headers to link against the actual library file. See the documentation in the Code::Blocks Wiki on how this is done for some example cases and adapt for your library.
The simplest thing to do in your situation is to install Cygwin. You can use the setup.exe installer to install the GCC and the LAPACK libraries. When you want to use the LAPACK library, you will add the -llapack option to your GCC command line.