"R.h" and "Rmath.h" are header files for an interface between R.app and C. But, they seems to be readable only through a R command 'R CMD SHLIB something.c'
I wish to compile my native C program to include them using gcc. I'm using Snow Leopard where I'm not able to locate those header files!
Any help?
Please see the 'Writing R Extensions' manual about details, you can easily compile and link against Rmath.h and the standalone R Math library -- but not R.h. (Which you can use via Rcpp / RInside but that is a different story.)
There are a number of examples floating around for use of libRmath, one is in the manual itself. Here is one I ship in the Debian package r-mathlib containing this standalone math library:
/* copyright header omitted here for brevity */
#define MATHLIB_STANDALONE 1
#include <Rmath.h>
#include <stdio.h>
typedef enum {
BUGGY_KINDERMAN_RAMAGE,
AHRENS_DIETER,
BOX_MULLER,
USER_NORM,
INVERSION,
KINDERMAN_RAMAGE
} N01type;
int
main(int argc, char** argv)
{
/* something to force the library to be included */
qnorm(0.7, 0.0, 1.0, 0, 0);
printf("*** loaded '%s'\n", argv[0]);
set_seed(123, 456);
N01_kind = AHRENS_DIETER;
printf("one normal %f\n", norm_rand());
set_seed(123, 456);
N01_kind = BOX_MULLER;
printf("normal via BM %f\n", norm_rand());
return 0;
}
and on Linux you simply build like this (as I place the library and header in standard locations in the package; add -I and -L as needed on OS X)
/tmp $ cp -vax /usr/share/doc/r-mathlib/examples/test.c mathlibtest.c
`/usr/share/doc/r-mathlib/examples/test.c' -> `mathlibtest.c'
/tmp $ gcc -o mathlibtest mathlibtest.c -lRmath -lm
/tmp $ ./mathlibtest
*** loaded '/tmp/mathlibtest'
one normal 1.119638
normal via BM -1.734578
/tmp $
Related
So everyone probably knows that glibc's /lib/libc.so.6 can be executed in the shell like a normal executable in which cases it prints its version information and exits. This is done via defining an entry point in the .so. For some cases it could be interesting to use this for other projects too. Unfortunately, the low-level entry point you can set by ld's -e option is a bit too low-level: the dynamic loader is not available so you cannot call any proper library functions. glibc for this reason implements the write() system call via a naked system call in this entry point.
My question now is, can anyone think of a nice way how one could bootstrap a full dynamic linker from that entry point so that one could access functions from other .so's?
Update 2: see Andrew G Morgan's slightly more complicated solution which does work for any GLIBC (that solution is also used in libc.so.6 itself (since forever), which is why you can run it as ./libc.so.6 (it prints version info when invoked that way)).
Update 1: this no longer works with newer GLIBC versions:
./a.out: error while loading shared libraries: ./pie.so: cannot dynamically load position-independent executable
Original answer from 2009:
Building your shared library with -pie option appears to give you everything you want:
/* pie.c */
#include <stdio.h>
int foo()
{
printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
return 42;
}
int main()
{
printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
return foo();
}
/* main.c */
#include <stdio.h>
extern int foo(void);
int main()
{
printf("in %s %s:%d\n", __func__, __FILE__, __LINE__);
return foo();
}
$ gcc -fPIC -pie -o pie.so pie.c -Wl,-E
$ gcc main.c ./pie.so
$ ./pie.so
in main pie.c:9
in foo pie.c:4
$ ./a.out
in main main.c:6
in foo pie.c:4
$
P.S. glibc implements write(3) via system call because it doesn't have anywhere else to call (it is the lowest level already). This has nothing to do with being able to execute libc.so.6.
I have been looking to add support for this to pam_cap.so, and found this question. As #EmployedRussian notes in a follow-up to their own post, the accepted answer stopped working at some point. It took a while to figure out how to make this work again, so here is a worked example.
This worked example involves 5 files to show how things work with some corresponding tests.
First, consider this trivial program (call it empty.c):
int main(int argc, char **argv) { return 0; }
Compiling it, we can see how it resolves the dynamic symbols on my system as follows:
$ gcc -o empty empty.c
$ objcopy --dump-section .interp=/dev/stdout empty ; echo
/lib64/ld-linux-x86-64.so.2
$ DL_LOADER=/lib64/ld-linux-x86-64.so.2
That last line sets a shell variable for use later.
Here are the two files that build my example shared library:
/* multi.h */
void multi_main(void);
void multi(const char *caller);
and
/* multi.c */
#include <stdio.h>
#include <stdlib.h>
#include "multi.h"
void multi(const char *caller) {
printf("called from %s\n", caller);
}
__attribute__((force_align_arg_pointer))
void multi_main(void) {
multi(__FILE__);
exit(42);
}
const char dl_loader[] __attribute__((section(".interp"))) =
DL_LOADER ;
(Update 2021-11-13: The forced alignment is to help __i386__ code be SSE compatible - without it we get hard to debug glibc SIGSEGV crashes.)
We can compile and run it as follows:
$ gcc -fPIC -shared -o multi.so -DDL_LOADER="\"${DL_LOADER}\"" multi.c -Wl,-e,multi_main
$ ./multi.so
called from multi.c
$ echo $?
42
So, this is a .so that can be executed as a stand alone binary. Next, we validate that it can be loaded as shared object.
/* opener.c */
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
void *handle = dlopen("./multi.so", RTLD_NOW);
if (handle == NULL) {
perror("no multi.so load");
exit(1);
}
void (*multi)(const char *) = dlsym(handle, "multi");
multi(__FILE__);
}
That is we dynamically load the shared-object and run a function from it:
$ gcc -o opener opener.c -ldl
$ ./opener
called from opener.c
Finally, we link against this shared object:
/* main.c */
#include "multi.h"
int main(int argc, char **argv) {
multi(__FILE__);
}
Where we compile and run it as follows:
$ gcc main.c -o main multi.so
$ LD_LIBRARY_PATH=./ ./main
called from main.c
(Note, because multi.so isn't in a standard system library location, we need to override where the runtime looks for the shared object file with the LD_LIBRARY_PATH environment variable.)
I suppose you'd have your ld -e point to an entry point which would then use the dlopen() family of functions to find and bootstrap the rest of the dynamic linker. Of course you'd have to ensure that dlopen() itself was either statically linked or you might have to implement enough of your own linker stub to get at it (using system call interfaces such as mmap() just as libc itself is doing.
None of that sounds "nice" to me. In fact just the thought of reading the glibc sources (and the ld-linux source code, as one example) enough to assess the size of the job sounds pretty hoary to me. It might also be a portability nightmare. There may be major differences between how Linux implements ld-linux and how the linkages are done under OpenSolaris, FreeBSD, and so on. (I don't know).
I just started with c development and I need to compile and link a program which uses the Accelerate Framework from Apple:
Simple example accelerate.c:
#include <stdio.h>
#include <Accelerate/Accelerate.h>
double vectorvector_product(double * a, double * b, int dim){
// This function returns in res the elementwiseproduct between a and b,
// a and b must have the same dimension dim.
return cblas_ddot(dim,a,1,b,1);
}
int main(){
double a[4] = {1.0,2.0,3.0,4.0};
double b[4] = {1.0,2.0,3.0,4.0};
double res = vectorvector_product(a,b,4);
printf("Res: %f",res);
}
I compiled it with clang:
>>> cc -Wall -g -c accelerate.c
And obtained a new file accelerate.o
What would I do now in order to properly link it?
All I know is that this Accelerate framework is located at /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework
>>> ls /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework
Accelerate.tbd Frameworks Headers Modules Versions
p.s.: If I Run this program with Xcode it magically works, but I need to do it from the command line and I would like to know what I'm doing.
Apparently the correct way to link Accelerate.h is by passing -framework Accelerate as argument e.g.
>>> cc -framework Accelerate accelerate.c
will compile and link accelerate.c by generating an executable a.out.
I wish to call OCaml code through C++ by compiling OCaml to a static or shared library that contains a C interface. This page seems to explain how to create a C interface for OCaml. But how do I do it and compile it? And how do I obtain the .h file to load in my C++ code?
Also, could someone explain to be this part:
The OCaml runtime system comprises three main parts: the bytecode
interpreter, the memory manager, and a set of C functions that
implement the primitive operations. Some bytecode instructions are
provided to call these C functions, designated by their offset in a
table of functions (the table of primitives).
I thougth OCaml could be compiled to native machine language. Why it is compiled to bytecode and interpreted at runtime? Is it always like that, or only for OCaml libraries compiled with C interface?
Most of that page describes how to call C from OCaml. You want to do the reverse, which is described in Advanced Topics: callbacks from C to OCaml, closer to the bottom of the page.
When you do native compilation there is no bytecode involved, just as you say. The native compiler (ocamlopt) produces ordinary object (.o in Unix) files and extra files containing OCaml metadata.
If you look at Advanced Example with callbacks, you'll see an example where the main program is in C, with calls to two functions defined in OCaml. Things should work similarly in C++. (I have only done this in C myself, however.)
Update
Here is the worked-out example using the code from Advanced example with callbacks. I am running this code on Ubuntu 18.04.4 (x86_64).
The OCaml code looks like this:
$ cat mod.ml
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 1)
let format_result n = Printf.sprintf "Result is: %d\n" n
let () = Callback.register "fib" fib
let () = Callback.register "format_result" format_result
Compile this code and ask for a complete object file:
$ ocamlopt -output-obj -o bigmod.o mod.ml
Rename the C code to modwrap.cc. (The code is given in the OCaml manual section.)
$ head -6 modwrap.cc
#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
int fib(int n)
Note that the OCaml include files are conditionalized as to whether they're being included from C or C++ (as are almost all header files these days).
The main function from the OCaml manual section is also valid C++; rename it to main.cc:
$ head -7 main.cc
#include <stdio.h>
#include <caml/callback.h>
extern int fib(int n);
extern char * format_result(int n);
int main(int argc, char ** argv)
Now compile and link everything:
$ g++ -c modwrap.cc
$ g++ -o myprog -I $(ocamlopt -where) \
main.cc modwrap.o bigmod.o $(ocamlopt -where)/libasmrun.a -ldl
$
Now run the program
$ ./myprog
fib(10) = Result is: 89
There is no automatic generation of header files. In this example the extern lines of main.cc are the header file in essence. If you want a header file you'll have to write something like this yourself.
Update 2
Here are the commands for creating an actual static library containing the OCaml functions and their wrappers. This assumes that you have done the compiles above to create bigmod.o and modwrap.o:
$ cp $(ocamlopt -where)/libasmrun.a libmyoc.a
$ ar r libmyoc.a bigmod.o modwrap.o
Now you can use this library in your C++ code (represented by main.cc):
$ g++ -o myprog -I $(ocamlopt -where) main.cc -L . -lmyoc -ldl
$ ./myprog
fib(10) = Result is: 89
Update 3
(I updated the above commands to work on Unbuntu.)
I have installed gsl library using sudo apt install libgsl2 command.However when I run the following program using gcc,
#include<stdio.h>
#include<math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
double x;
double nu;
int main(){
x=4;
nu=2;
double chi;
chi=gsl_cdf_chisq_P (double x, double nu);
printf("%lf",chi);
}
The following message is displayed when I compile using gcc -o file filename.c
gsl/gsl_rng.h: No such file or directory
compilation terminated.
Have I missed any step during installation?Or is it required to use any flag during compilation?
You need to install the libgsl-dev package.
This package contains the include files necessary for your development.
If in doubt checkout the list of files in the package
$ dpkg -L libgsl2
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libgsl.so.19.0.0
/usr/lib/x86_64-linux-gnu/libgslcblas.so.0.0.0
/usr/lib/x86_64-linux-gnu/libgslcblas.so.0
/usr/lib/x86_64-linux-gnu/libgsl.so.19
/usr/share/doc
/usr/share/doc/libgsl2
...
just doc files and nothing more
And with the dev package you get
$ dpkg -L libgsl-dev
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libgsl.a
/usr/lib/x86_64-linux-gnu/libgslcblas.a
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/gsl.pc
/usr/include
/usr/include/gsl
...
and all the header files here
That is the dev package gives you all the necessary headers and the static import libraries useful in case of a static build.
P.S. Do not be put off by the lack of 2 in the name of libgsl-dev package compared to libgsl2. Both would be of the same 2.x version on your Ubuntu system or a derivative thereof.
P.P.S. There are a few more issues with your code.
The function that you are using gsl_cdf_chisq_P() belongs to the collection of CDF functions so you need to include <gsl/gsl_cdf.h>. And you need to call the function correctly as gsl_cdf_chisq_P (x, nu) instead of gsl_cdf_chisq_P (double x, double nu).
The resulting code could look like this:
#include<stdio.h>
#include<math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_cdf.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
int main(){
double x=0.05;
double nu=9;
double chicdf, chi;
chi=gsl_cdf_chisq_Pinv (1-x, nu);
chicdf=gsl_cdf_chisq_P (chi, nu);
printf("ICDF[Chisquared<%d>](1 - %lf) = %lf\n"
"CDF[Chisquared<%d>](%f) = %lf\n",
(int)nu,x,chi,(int)nu,chi,chicdf);
return 0;
}
To compile it run
gcc -Wall -O2 testchisq.c -o testchisq -lgsl -lgslcblas -lm
It should print
ICDF[Chisquared<9>](1 - 0.050000) = 16.918978
CDF[Chisquared<9>](16.918978) = 0.950000
I'm trying to get the ADC running on beaglebone black. The OS is Debian GNU/Linux 7.7. I'm using C language. When I try to compile the following code:
#include <stdio.h>
#include <unistd.h>
#include "pruio_c_wrapper.h"
#include "pruio_pins.h"
int main(int argc, const char *argv[]) {
PruIo *io = pruio_new(0, 0x98, 0, 1);
if (io->Errr) {
printf("Initialisation failed (%s)\n", io->Errr);
return 1;
}
if(pruio_config(io, 0, 0x1FE, 0, 4, 0)){
printf("Config failed (%s)\n", io->Errr);
return 1;
}
int a = 0;
int i;
while(1){
printf("\r%12o %12o %12o %12o %4X %4X %4X %4X %4X %4X %4X %4X\n", io->Gpio[0].Stat, io->Gpio[1].Stat, io->Gpio[2].Stat, io->Gpio[3].Stat, io->Value[1], io->Value[2], io->Value[3], io->Value[4], io->Value[5], io->Value[6], io->Value[7], io->Value[8]);
fflush(STDIN_FILENO);
usleep(1000);
}
pruio_destroy(io);
return 0;
}
But I get the following error:
undefined reference to 'pruio_new'
undefined reference to 'pruio_config'
I installed everything like FreeBasic compiler and pruss driver kit for freebasic and BBB and libpruio. I also copied all the header files in the same directory as the .c file, including "pruio_c_wrapper.h", "pruio-pins.h", "pruio.h" and all the other files in the src directory of libpruio. But it doesn't work.
Could you please tell me what to do?
Thanks
libfb is the FreeBASIC run-time library. When you want to compile against the old libpruio-0.0.x versions, you'll need an old FreeBASIC installation from
www{dot}freebasic-portal.de/dlfiles/452/bbb_fbc-0.0.2.tar.xz
Which installs /usr/local/lib/freebasic/libfb.so.
See the libpruio-0.0.x C example codes for compiler command line arguments (ie. header section of io_input.c).
But I recommend to use the new version libpruio-0.2 from (the last post links to the documentation of this new version)
http://www.freebasic-portal.de/dlfiles/592/libpruio-0.2.tar.bz2
which doesn't have this pitfalls, gcc compiles without FB installation, and provides new features like pinmuxing, PWM, CAP. There're small bugs in this versions C header, which is now named pruio.h: a missing enum and a copy / paste bug regarding a function name. See this thread for details:
http://www.freebasic.net/forum/viewtopic.php?f=14&t=22501
BR
Ok, I downloaded it, the binaries are in libpruio-0.0.2/libpruio/src/c_wrapper and so are the include files, copy the headers and libpruio.so to the same directory where the test.c file resides, and then
For the includes, you need to to append libpruio's include directory to the compiler command using -I. then you can do
#include <pruio_c_wrapper.h>
#include <pruio_pins.h>
You need to append the library to the linker command, with
-L. -lpruio
your complete compilation command will be then
gcc -o test -I. -L. -lpruio test.c