Linking C library to R - c

I recently found this C library (http://libxlsxwriter.github.io/), and attempted to use it with R.
Getting the C library to work by itself was not difficult. I downloaded zlib and libxlsxwriter using msys2, and ran make in the libxlsxwriter folder.
Now I can run this Hello-World example, lets call it test.c:
#include "xlsxwriter.h"
void main() {
lxw_workbook *workbook = workbook_new("myexcel.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
int row = 0;
int col = 0;
worksheet_write_string(worksheet, row, col, "Hello me!", NULL);
workbook_close(workbook);
}
Now I can compile test.c by running:
cc test.c -o test -lxlsxwriter -lz
And then run the executable:
./test
And now I have a Hello-World excel document.
Getting it to work with R has been much trickier. If I simply run:
R CMD SHLIB test.c
I get this error: ibxlsxwriter/include/xlsxwriter/common.h:19:42: fatal error: xlsxwriter/third_party/queue.h: No such file or directory
#include "xlsxwriter/third_party/queue.h"
Yet the file is clearly there when I check.
Any advice on how to connect this C library with R? At this point I am just trying to get the hello-world example to run from R.
Would it be a better approach to start out building a package, with xlsxwriter in the inst folder, and then try to write a makevars that will get xlsxwriter to compile correctly? I know I would have to include PKG_CPPFLAGS = -I../inst/libxlsxwriter but I am guessing I would need more than that.

You may want to try Continuum's Anaconda R packages. They use MSYS2 packages fairly directly. The toolchain package is called m2w64-toolchain and the posix package is sometimes useful for building R packages too.
conda install -c r r-essentials m2w64-toolchain posix
Disclaimer: I work for Continuum, but I also work on MSYS2.

Related

Header not found error when adding stdint.h to my C code when compiling with Clang on Raspberry Pi

Here's the error that I am getting and none of the online solutions are effectively fixing the issues that I am having. Just adding #include <stdint.h> breaks the compilation of my code. I tried installing multilib but the library seems to have no support on Ubuntu. I also tried some of the compatibility libraries but to no avail.
clang -O2 -target bpf -c hello.c -o hello.o
In file included from hello.c:2:
In file included from /usr/lib/llvm-11/lib/clang/11.0.0/include/stdint.h:52:
/usr/include/stdint.h:26:10: fatal error: 'bits/libc-header-start.h' file not found
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
The code for reference. I am trying to run a compiled version of uBPF on an ARM device
#include <stdint.h>
static int idouble(int a)
{
return (a * 2);
}
int bpf_prog(void *ctx)
{
int a = 1;
a = idouble(a);
return (a);
}
This question is based on this Klyr's tutorial on how to setup user input with uBPF.
I was able to have my issue fixed actually. ARM does not have a gcc-multilib equivalent so you must install gcc-multilib-arm-linux-gnueabihf for this to work. When trying to compile and target with Clang, you must first
cd /usr/include/aarch64-linux-gnu
then
sudo cp -r . ..
It's a hacky solution but it will let you import libraries as you see fit

Building library issue libudns

First of all thanks for your attention and help.
I have been trying to ./configure and build a program that use a lot of libraries, and specifically libudns. I have been installing several libraries that were needed or by apt-get or by compile, and all of them works, but libudns (which is freaking me out).
This program make use of a configure script that include the following lines of code that add the flag -ludns to the Makefile:
if [ "x$WITH_UDNS" == "xy" ]; then
mkl_lib_check "udns" HAVE_UDNS fail CC "-ludns" \
"#include <udns.h>
void *f();void *f(){return dns_init;}"
fi
When I type ./configure the script checks if all libraries are presents on the system by pkg-config and by compile, as you can see in the following snap:
As you can see, configure cannot see this library.
What I have done is try to install this package by the two different ways:
By pkg-config: sudo apt-get install libudns-dev
By compile:
git clone https://github.com/shadowsocks/libudns
cd libudns
./autogen.sh
./configure && make
sudo make install
With this two ways, I have both:
/usr/lib/x86_64-linux-gnu/libudns.so
/usr/local/include/udns.h
These paths are the same where others libraries are installed, for example PostgreSQL, which you can that is detected:
/usr/lib/x86_64-linux-gnu/libpq.so
/usr/include/postgresql/libpq-fe.h
But the result is always the same:
Does anybody knows how to link this library?
Also, I have try these other things:
Copy udns.h to /usr/include: sudo cp /usr/local/include/udns.h /usr/include/udns.h
Make a sample program only to emulate this check:
#include <stdio.h>
#include <udns.h>
struct dns_ctx* ctx;
void *f();
void * f(){return dns_init;}
int main(int argc, char** argv){
int do_open = 0;
printf("Hola, mundo\n");
f(ctx, do_open);
}
And when I try to build this program with:
gcc main.c -o hello_world -ludns
it WORKS!?!
I have also try to build this program without the -ludns flag, and it gives me the same error as before:
So, I do not understand where is the fail, considering that as you can see in the second image, the -ludns flag is present.
Thanks a lot for your time. Any advise will be welcomed.

Cross-compiled library not found by toolchain

I'm new to developing for embedded systems, but I have installed arm-linux-gnueabi-gcc via the Linux Mint package manager and managed to build a few programs successfully.
I'm currently struggling with getting a program to compile using libusb. I've done the following:
Downloaded and unpacked the libusb 1.0.20 sources from https://sourceforge.net/projects/libusb/.
Compiled and installed them using the following commands:
~/Downloads/libusb-1.0.20 $ ./configure --host=arm-linux-gnueabi --prefix=/opt/ --disable-udev
~/Downloads/libusb-1.0.20 $ sudo make
~/Downloads/libusb-1.0.20 $ sudo make install
(The reason for sudo-ing the make commands was because I encountered permission problems related to removing old files.)
Copied a small sample file from somewhere on the internet:
#include <libusb-1.0/libusb.h>
#include <stdio.h>
int main()
{
int i=0;
libusb_context **c = NULL;
i = libusb_init(c);
printf("\nusing libusb.h\n");
return 0;
}
Tried to build it and run it with gcc:
~/Desktop/libtest $ gcc libtest1.c -o libtest1 -lusb-1.0
~/Desktop/libtest $ ./libtest1
using libusb.h
However, when I try to do the same with arm-linux-gnueabi-gcc, it can't find the library:
~/Desktop/libtest $ arm-linux-gnueabi-gcc libtest1.c -o libtest1 -lusb-1.0
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/ld: cannot find -lusb-1.0
collect2: error: ld returned 1 exit status
Where did I go wrong? Is there something else I need to do in order to use the library? Did I fail at compiling the library for the arm compiler? I didn't include the compiler output here since it's quite long, but there are no obvious errors. This might be a very stupid question, but I'm completely clueless.

Using SQLite3 in a C program - Simple setup issue

I am new to programming and have just started to learn C. I would like to use SQLite3 in a c program but am having a hard time setting up the library. I am using old fashion command line interface to compile and run my programs. I am using gcc. I also tried using CodeBlocks and have spent alot of time researching on how to get this to work but no success!
I found a C and SQLite3 tutorial but it doesn't explain this simple concept of setting up the SQLite library with the GCC compliler. I also found another tutorial but it too doesn't explain how to set up the libary with the GCC compiler.
So far I have a simple program called "testsql.c" and this is all I would like to get working:
#include <sqlite3.h>
#include <stdio.h>
int main() {
printf("%s\n", sqlite3_libversion());
return 0;
}
I am using the following gcc command to compile the program:
C:\Users\qwa\Desktop\testsql>gcc testsql.c -o testsql -lsqlite3
The output is always this error:
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lsqlite3
collect2.exe: error: ld returned 1 exit status
Now I have been on SQLite's download webpage and have downloaded the following files and have tried placing them under the MinGW\bin and MinGW\include:
The Amalgamation zip file:
shell.c
sqlite3.c
sqlite3.h
sqlite3ext.h
I also downloaded the dll zip file hoping I could figure out how to link it with CodeBlocks but was unsuccessful. That zip file came with these files:
sqlite3.def
sqlite3.dll
I think my problem is that I just don't know how to make a connection between the SQLite3 libraries and the gcc compiler. I feel like this is such a noob question but I have been struggling :(
Any help would be extremely appreciated!!! To summarize, I just want a SQLite database connection setup with a simple C program.
EDIT: based on the first comment, I just used the following command:
gcc testsql.c -o testsql -LC:\sqlite3\sqlite3.dll
and the result I got was:
C:\Users\qwa\AppData\Local\Temp\ccMjAu3h.o:testsql.c:(.text+0xf):undefined reference to `sqlite3_libversion'
collect2.exe: error: ld returned 1 exit status
any ideas?
The easiest way of using SQLite is to compile it directly into your application:
gcc testsql.c sqlite3.c -o testsql

"loading shared libraries" error using VLFeat in C

I am trying to use VLFeat library in C, as given on the website
http://www.vlfeat.org/gcc.html.
I downloaded and installed the library. I use the glnxa64 architecture. The library is located at /A/B/C/vlfeat-0.9.18
My code is as follows:
extern "C" {
#include <vl/generic.h>
#include <vl/sift.h>
}
int main (int argc, const char * argv[])
{
VL_PRINT ("Hello world!") ;
return 0;
}
I compile my code using the following statement,
g++ main.cpp -o vlfeat-test -I/A/B/C/vlfeat-0.9.18 -L/A/B/C/vlfeat-0.9.18/bin/glnxa64/ -lvl
But when I run it, I get the following error
./vlfeat-test: error while loading shared libraries: libvl.so: cannot open shared object file: No such file or directory
When your program is loaded, linux loads the necessary libraries.
You need to create a symbolic link in /usr/lib/ to your libvl.so file
sudo ln -s /home/[YourPATH]/vlfeat-0.9.20/bin/[YourArchitecture]/libvl.so /usr/lib/libvl.so
Before running your test, in the same console:
export LD_LIBRARY_PATH=/A/B/C/vlfeat-0.9.18/bin/glnxa64:$LD_LIBRARY_PATH
then
./vlfeat-test
I think the problem is when your program load. Linux doesn't know where your vl library is.
copy libvl.so to /usr/lib
sudo cp [VLFEAT_PATH]/bin/[YOUR_ARCHITECTURE]/libvl.so /usr/lib
[This worked for same problem when using the .mex files through MATLAB in Ubuntu].
You may need to update the links and cache to the recent shared libraries by running
sudo ldconfig
You can permanently add the library path /A/B/C/vlfeat-0.9.18/bin/glnxa64 or a custom directory with your (links to) shared libraries, e.g., /home/username/lib in the ldconfig files:
sudo vim /etc/ld.so.conf
to add the line(s)
/A/B/C/vlfeat-0.9.18/bin/glnxa64
Verify by running
ldconfig -v | grep libvl.so

Resources