How to Statically Link External Libraries when Compiling a Ruby C Extension - ruby

I am building a Ruby C Extension on Windows which requires some external C libraries, specifically libcurl and its dependancies. I have the curllib dll's and .a files. However when I build with extconf.rb it always links the libraries dynamically which requires someone to have curl installed and in their windows path to use the compiled extension. Instead I want extconf.rb to link curl and its dependancies statically so that anyone can use the extension on windows without having to add curllib to their path first.
This is my extconf.rb
require 'mkmf'
# Name the extension.
extension_name = 'ConnectionManager'
dir_config("curl")
# Make sure the cURL library is installed.
have_library("curl")
# Create the Makefile.
create_makefile(extension_name)
This is the command I am generating my makefile with
ruby extconf.rb --with-curl-dir=C:/Knapsack/x86-windows
Is there something that I can add to my extconf.rb file or command to force ruby to link the external libraries to my c extension statically? Any help would be appreciated and please let me know if you need any more information.

I had a similar problem writing a native extension using gif_lib on linux.
Try adding the following to your extconf.rb:
unless find_library("curl", "curl_version")
abort "curl is not installed, please install and try again"
end
The find_library function returns true if the library and entry point are present and has the side effect of adding it to the -l option to gcc.
I found these links useful:
http://tenderlovemaking.com/2010/12/11/writing-ruby-c-extensions-part-2.html
Here is the C extension (a working example):
https://github.com/e-g-r-ellis/ruby-giflib

When I built my Ruby C Extension using nmake from Visual Studio Express I had to change compiler flag from -MD to -MT in order to avoid dependency on MSVCRT.
I set the $CFLAGS variable in my extconf.rb file.
$CFLAGS = '-MT -Ot -Ox -W4' Not sure if it's the correct way to modify these flags, but it worked.
https://bitbucket.org/thomthom/sketchup-ruby-c-extension/commits/3e87351be87f177b8ed43798587f6e798064492d

Related

Linking against static Lua libraries on macOS

I'm trying to compile and link a program (using CMake) that uses Lua 5.3's C interface on Mac OS X 10.15.7. However I have these problems:
brew install lua#5.3 only installs dynamic libraries
I cannot copy static libraries built from source to /usr/local due to System Integrity Protection (?)
I don't know how to make CMake find the libraries if I put them anywhere else (using find_package(Lua 5.3 REQUIRED)
What's the easiest way to solve this?
If I correctly understand your question, you are trying to use Lua's C API, which means that you need access to the principal header files lua.h, lualib.h, and lauxlib.h, as well the static library liblua.a that is created when the interpreter is built.
I would recommend downloading lua-5.3.5.tar.gz from lua.org and then building from source.
This can be done easily from the Terminal:
$ wget http://www.lua.org/ftp/lua-5.3.5.tar.gz
$ tar xzf lua-5.3.5.tar.gz
$ cd lua-5.3.5
$ make macosx
After that you should be able to do make install as well, which copies the Lua interpreter to /usr/local/bin, I believe.
If you do not want the key Lua header files put into your include path, build your program with -I and -L flags. Also, don't forget the -llua -ldl -lm flags when linking your program.

Is there a way to reference a library in Automake?

I'm trying to use LDADD to reference a prebuilt library and Automake insists that the library has to be built. The Automake manual says:
"If you need to link against libraries that are not found by configure, you can use LDADD to do so. This variable is used to specify additional objects or libraries to link with; it is inappropriate for specifying specific linker flags, you should use AM_LDFLAGS for this purpose."
In my code I have used both
LDADD = ../lib/library.a
and
prog_LDADD = ../lib/librarya.
In both cases make outputs
*** No rule to make target 'library.a', needed by 'SlipTest.exe'. Stop.
It's got me stumped.
art
check whether the file ../lib/library.a actually exists.
when building libraries with automake you should use libtool, and libtool-libraries use the (platform independent) .la extension:
prog_LDADD = ../lib/library.la

g++: link to non-standard /usr/local

I have an OSX 10.7 computer with a non-administrator account, and was attempting to install the pre-compiled versions of gcc and g++ found here. I've attempted to use the answers presented in these questions (three different links) to compile some code with g++, to confusing avail. I have a folder structure like this:
~/code/:
usr/:
local/:
bin/ (3.6MB)
include/ (8.6MB)
lib/ (51MB)
libexec/ (49MB)
share/ (16MB)
c++/:
source/ (contains .cpp files)
g++ -v returns this:
code USER$ usr/local/bin/g++ -v
Using built-in specs.
COLLECT_GCC=usr/local/bin/g++
COLLECT_LTO_WRAPPER=/Users/USERNAME/code/usr/local/bin/../libexec/gcc/ x86_64-apple-darwin11.4.0/4.7.1/lto-wrapper
Target: x86_64-apple-darwin11.4.0
Configured with: ../gcc-4.7.1/configure --enable-languages=fortran
Thread model: posix
gcc version 4.7.1 (GCC)
An attempt at compiling a file that "#include"s only iostream:
$ usr/local/bin/g++ c++/source/test.cpp -o ex6
In file included from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/bits/postypes.h:42:0,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iosfwd:42,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ios:39,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ostream:40,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iostream:40,
from c++/source/ex6.cpp:1:
/Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cwchar:46:19: fatal error: wchar.h: No such file or directory
compilation terminated.
I tried compiling with some flags recommended in one of the links mentioned, like this: (with all combinations of "usr/" to "usr/local/include/" and "usr/" to "/usr/local/lib" giving the same result (which is also the same as using no flags).
$ /Users/USERNAME/code/usr/local/bin/g++ source/ex6.cpp -I/Users/USERNAME/code/usr/local/include/ -L/Users/USERNAME/code/usr/local/lib/In file included from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/bits/postypes.h:42:0,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iosfwd:42,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ios:39,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ostream:40,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iostream:40,
from source/ex6.cpp:1:
/Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cwchar:46:19: fatal error: wchar.h: No such file or directory
compilation terminated.
In short, I'm having trouble understanding what the answers in the links provided are saying to do. I saw reference to a specs file, which I could find no specific information for, and "-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)", for which I couldn't figure out what I was supposed to substitute for "DEFAULT_LIB_INSTALL_PATH".
What should I do to point the downloaded g++ compiler to its own files without placing them in their default location, as I do not have administrative capabilities on this account?
I will provide any information as necessary.
It looks like you don't have required header files. You need to install Command Line Tools from Apple Developers site (free registration needed). The problem is that you don't have administrator account. I suggest that you ask the administrator to install the tools for you. If it is not possible you could try to extract the contents of downloaded package (DevSDK.pkg) to your local directory (Pacifist can do that) and pass the path with the missing headers to your compiler. I haven't tried that though.

make: f77: No such file or directory

Whilst attempting to make/compile the grafic package, I'm seeing this error after calling the make command within the grafic directory:
f77 -O2 -c grafic1.f
make: f77: No such file or directory
make: *** [grafic1.o] Error 1
I have XCode and all associated command line tools installed, what could be causing this error?
This error is make telling you that you have no binary in your path called f77. There are two things you need to look at the fix this:
Do you have a Fortran compiler installed? MacOS X/Xcode does not come pre-installed with one by default. The easiest options to install one are via third-party tools like macports or homebrew where you can install gfortran which may be a standalone package or may be part of the gcc package.
Once you have a compiler installed, your makefile needs to know about it. Without seeing the makefile this is only an assumption, but if autotools are not used the fortran compiler is usually hardcoded in a variable called FC, e.g. you might see a line
FC=f77
and you would change this to
FC=gfortran
assuming gfortran is in your path.
Once you have a Fortran compiler installed and the makefile knows about it, you should be able to execute make successfully.

boost library gives errors on ubuntu

I am trying to compile a package on ubuntu 8.1
when executing this command: ./configure I get the follwoing error:
checking for Boost headers version >= 103700... no
configure: error: cannot find Boost headers version >= 103700
knowing that I installed needed boost packages using these command:
$ apt-get install libboost-dev libboost-graph-dev libboost-iostreams-dev
Can anybody help please?
thank you. Now it works but i get another error when running ./configure: checking boost/iostreams/device/file_descriptor.hpp usability... yes checking boost/iostreams/device/file_descriptor.hpp presence... yes checking for boost/iostreams/device/file_descriptor.hpp... yes checking for the Boost iostreams library... no configure: error: cannot not find the flags to link with Boost iostreams any ideas please?
It could be that the version of boost that you're getting from the Ubuntu repository is too old (it's suggested here that the highest version for 8.10 is 1.35; it looks like your configure script is asking for 1.37). You might need to build from source; there's some more info in the answers to the question I linked to which will hopefully help.
UPDATE:
From your new error, it sounds like configure now can't find the boost_iostreams library. On my system it's /usr/lib/libboost_iostreams-mt.[a|so] - do you have those files (possibly in a different directory depending on where you installed boost)?
You can also try running ldconfig in case there's a missing symlink (from, say,
libboost_iostreams-mt.so.1.37.0 to libboost_iostreams-mt.so).
Is this configure one generated by GNU autoconf? If it is, there should be a file called config.log in the same directory which contains a list of all the commands configure tried to run when looking for things. If there's anything in there about boost_iostreams could you post it?
One totally random guess: some examples I've found on the web link to boost_iostreams without the multi-threading suffix -mt - but I don't have those on my machine at all. Maybe your configure script is running into the same problem?
UPDATE 2
The configure script seems to be looking for a single-threaded debug build of the boost iostreams library, which won't be produced by default when building from source on linux. Also, the default on linux is not to name the libraries based on the build configuration (so the libs you found in /usr/lib might not be the ones you installed from source unless you overrode this). This stuff isn't really explained on the boost website, I only found out by looking in the Jamroot file (bjam --help works too)! Anyway, to get a library with the right build configuration, and named correctly, I need to go into the root of the boost source tree and run:
sudo bjam --with-iostreams --layout=tagged variant=debug threading=single install
For me this puts the libraries (libboost_iostreams-d.a and the shared versions) into /usr/local/lib where ld will find them by default, so this should be fine. If you need them to go somewhere else you can use the --prefix=... option to bjam eg. if you want them in /usr/lib you can do --prefix=/usr. If the package you're building needs more boost libraries you can remove the --with-iostreams and then they'll all be built (or replace iostream with the name of each other library you need).
A side note: I had to install the libbz2-dev package to get boost iostreams to build - it's easy to miss the error here if you build all of boost as there's so much output!

Resources