Say I have a target A that depends on the libraries B and C. But B and C have no mutual dependence. The linking with CMake could look like
target_link_libraries( A B C )
but
target_link_libraries( A B )
target_link_libraries( A C )
also seems to work (and might be more easy to maintain). Are there disadvantages of splitting the target_link_libraries command into multiple commands? Or should one always put it into a single command in case one eventually does encounter a mutual dependence of the libraries?
Those are exactly equivalent. Both say that A depends on B and A depends on C. Neither says anything about any dependency between B and C, so there is none.
I'm not sure what you mean by "mutual dependence" -- when considering B and C, there are 4 possibilities: (1) neither depends on the other, (2) B depends on C, (3) C depends on B, or (4) they both depend on each other.
(1) is what you have. (2) and (3) would mean you should add another target_link_libraries command with either "B C" as the args or "C B" respectively. (4) means you have a circular dependency and they really shouldn't be separate libraries at all, but combined into a single logical entity. You should avoid (4) because it makes it impossible to load as shared libraries on some (all?) platforms.
There is negligible performance penalty for having two separate target_link_libraries calls. I doubt you could measure the performance and show any significant timing differences.
To clarify, this call:
target_link_libraries(A B C)
means target A requires libraries B and C.
If, instead, you consider case (2) above, where B depends on C, you would instead write:
target_link_libraries(B C)
target_link_libraries(A B)
which means target B requires library C, and target A requires library B (and CMake automatically transitively propagates B's dependencies to A so that you do not have to know about any A -> C dependence unless you have explicit code that calls functionality in library C).
You should always express the minimum dependency information necessary to link things together.
Both ways are valid and equivalent. Basically target_link_libraries command just appends specified libraries to the LINK_INTERFACE_LIBRARIES property of the passed target (A in your sample).
Related
I tried to generate C code starting from a scheme function and I do not manage to find any translator from scheme to C. I tried to convert this function to C.
(define f
(lambda(n)
(if (= n 0) 1
(* n (f (- n 1))))))
(display (f 10))
(newline)
I tried to use gambit (gsc) and it generates a C file that looks merely like a file to load in some interpreter, not a file containing a main function that can be executed.
Is there some application that generates C code that can be directly executed? The functions from standard scheme library like display should be linked with some object file.
EDIT:
My purpose is to understand the algorithms used by professional translators.
There are many such translators, dating back at least to the 1980s I think CHICKEN is a good current one.
If you want to use that:
get CHICKEN;
build & install it with the appropriate make incantation (this was painless for me on OSX, it should be very painless indeed on Linux therefore, although it may be harder on Windows);
stash your code in a file I'll call f.scm.
if you want to see the C code, compile with chicken f.scm which will produce a few hundred lines of incomprehensible C;
if you want just the executable, use csc to create it.
There is an extensive manual which you will need to read if you want to do anything nontrivial, such as linking in C libraries or talking to Scheme code from C.
Without knowing what you are after, this smells as if it may be an XY problem. In particular:
if you want a Scheme system which will allow you talk to code written in C, then you probably want a system with an FFI, not one that compiles to C;
if you want a Scheme system which will create native executables, then you probably want, well, a Scheme system which will create native executables, not one which compiles to C.
There are many examples of each of these. Some of these systems may also compile to, or via, C, but one does not depend on the other.
Finally, if you want to understand how Scheme compilers which target C work (or how Scheme compilers which target any language, including assembler), then the traditional approach probably still works best: find a well-written one for which source is available, and read & tinker with its source code.
Basically no scheme to C translators will do what you want. They create hideous code not meant to be read and they rely on the underlying C compiler to do much of the optimization. Chicken and Gambit make use of header files while I have Stalin, which does not but it is based on R4RS instead of R5RS and later.
You are probably better off reading Abdulaziz Ghuloum's paper An Incremental Approach to Compiler Construction (PDF) or perhaps Matt Mights articles on parsing, continuations and compilations. Longer down he actually has a Scheme to C and Scheme to Java with different approaches to closure conventions. In the end nothing beats doing it yourself so have a go!
The standard library function abs() is declared in stdlib.h, while fabs() is in math.h.
Why are they reside in different headers?
math.h first appears in 7th Research Unix. It is hard to tell how it got there. For example, [1] claims that bits of C library were merged from "PWB/Unix" which included troff and C compiler pcc, but I cannot prove it.
Another interesting piece of information is library manual from V7 Unix:
intro.3:
(3) These functions, together with those of section 2 and those marked (3S),
constitute library libc, which is automatically loaded by the C compiler
cc(1) and the Fortran compiler f77(1). The link editor ld(1) searches
this library under the `-lc' option. Declarations for some of these
functions may be obtained from include files indicated on the appropri-
ate pages.
<...>
(3M) These functions constitute the math library, libm. They are automati-
cally loaded as needed by the Fortran compiler f77(1). The link editor
searches this library under the `-lm' option. Declarations for these
functions may be obtained from the include file <math.h>.
If you look into V7 commands makefiles, only few C programs are linked with -lm flag. So my conclusion is speculative:
libm.a (and math.h) was primarily needed for FORTRAN programs mostly, so it was separated into library to reduce binary footprint (note that it was linked statically).
Not many machines had floating point support. For example, you would need to buy an optional FPP for PDP-11 [2], there is also libfpsim simulation library in Unix to mitigate that, so floating point can be hardly used in early C programs.
1. A History of UNIX before Berkeley: UNIX Evolution: 1975-1984
2. PDP-11 architecture
Most operators like + - / * are also math operators yet these are also readily available. When programming you use so much math, that developers have started to differentiate between math that is needed for everyday stuff and math that is more specialized that you only use some of the time. Abs is one of those functions that are just used to often. Like with pointer arithmetic when you just want to know the difference to calculate the size of a memory block. But you are not interested in knowing which is higher in memory and which is lower.
So to sum up: abs is used often because it calculates the difference of two integers. The difference between two pointers for instance is also an integer. And so it is in stdlib.h. fabs how ever is not something you will need much unless you are doing math specific stuff. Thus it is in math.h.
I am writing some R simulation code, but want to leverage Fortran's swift Linear Algebra libraries to replace the core iteration loops. So far I was looking primarily at the obvious option of using .Fortran to call linked F95 subroutines; I figured I should optimize memory use (I am passing very large arrays) and set DUP=FALSE but then I read the warning in manual about the dangers of this approach and of its depreciation in R 3.1.0 and disablement in R 3.2.0. Now the manual recommends switching to .Call, but this function offers no Fortran support natively.
My googling has yielded a stackoverflow question which explores an approach of linking the Fortran subroutine through C code and the calling it using .Call. This seems to me the kind of thing that could either work like a charm or a curse. Hence, my questions:
Aiming for speed and robustness, what are the risks and benefits of calling Fortran via .Fortran and via .Call?
Is there a more elegant/efficient way of using .Call to call Fortran subroutines?
Is there another option altogether?
Here's my thoughts on the situation:
.Call is the generally preferred interface. It provides you a pointer to the underlying R data object (a SEXP) directly, and so all of the memory management is then your decision to make. You can respect the NAMED field and duplicate the data if you want, or ignore it (if you know that you won't be modifying the data in place, or feel comfortable doing that for some other reason)
.Fortran tries to automagically provide the appropriate data types from an R SEXP object to a Fortran subroutine; however, its use is generally discouraged (for reasons not entirely clear to me, to be honest)
You should have some luck calling compiled Fortran code from C / C++ routines. Given a Fortran subroutine called fortran_subroutine, you should be able to provide a forward declaration in your C / C++ code as e.g. (note: you'll need a leading extern "C" for C++ code):
void fortran_subroutine_(<args>);
Note the trailing underscore on the function name -- this is just how Fortran compilers (that I am familiar with, e.g. gfortran) 'mangle' symbol names by default, and so the symbol that's made available will have that trailing underscore.
In addition, you'll need to make sure the <args> you choose map to from the corresponding C types to the corresponding Fortran types. Fortunately, R-exts provides such a table.
In the end, R's R CMD build would automatically facilitate the compilation + linking process for an R package. Because I am evidently a glutton for punishment, I've produced an example package which should provide enough information for you to get a sense of how the bindings work there.
3. Is there another option altogether? YES
The R package dotCall64 could be an interesting alternative. It provides .C64() which is an enhanced version of the Foreign Function Interface, i.e., .C() and .Fortran().
The interface .C64() can be used to interface both Fortran and C/C++ code. It
has a similar usage as .C() and .Fortran()
provides a mechanism to avoid unnecessary copies of read-only and write-only arguments
supports long vectors (vectors with more then 2^31-1 elements)
supports 64-bit integer type arguments
Hence, one can avoid unnecessary copies of read-only arguments while avoiding the .Call() interface in combination with a C wrapper function.
Some links:
The R package dotCall64: https://CRAN.R-project.org/package=dotCall64
Description of dotCall64 with examples: https://doi.org/10.1016/j.softx.2018.06.002
An illustration where dotCall64 is used to make the sparse matrix algebra R package spam compatible with huge sparse matrices (more than 2^31-1 non-zero elements): https://doi.org/10.1016/j.cageo.2016.11.015
I am one of the authors of dotCall64 and spam.
Is it possible somehow using C macros to make prefix notation and/or Lisp syntax? For example, I want to write (f a b) instead of f(a, b); for C compiler.
Just for fun!
In the Lisp language, especially in the ANSI-Specified Common Lisp dialect, the manner in which processing of code occurs is much different from that of a C/C++ compiler, and this allows for Common Lisp macros to do -- and furthermore, to be -- something completely different from macros in other, non-Lisp languages.
Lisp interpretation has three stages. First is the read phase, during which code is read and certain defined characters are expanded into Common Lisp code.
1) Read Time -- during this stage, all defined, dispatched, etcetera, macro characters are expanded into common lisp forms/code to be evaluated later.
2) Compile Time -- during this stage, all definitions take place and procedures are stored into memory in a (perhaps) specified namespace with given names by which to reference them during:
3) Run Time -- during this time, the program is essentially running, and all that is left is to call the procedures constructed in phases 1 & 2 inside the Lisp REPL.
Interpreted languages are much more likely to support the insane customization options Common Lisp's macro definition system affords us. For example, I can quite easily change my REPL such that if I feed it the following form:
CL_USER> (progn (sleep 10) (format *standard-output* "~%~%10 seconds have passed and the universal timestamp is now ~a~%~%" (get-universal-time))&
...I may have defined the character #\& as to take the expression it closes, write it into a lambda function, and put that function into a threaded process, giving the REPL/prompt back to the user immediately and 10 seconds later (allowing interpretation the entire time) format a short message to the standard output.
Unfortunately, C & C++ just aren't really built for this sort of customization.
Whatever it is that you're doing, I imagine the answer to be "do the entire thing in Common Lisp" quite honestly, and I don't say that out of bias or elitism, but out of simple experience and the benefit of years of observation.
While I'm close to it, let me just call it what it is and end on absolute subjective opinion: I've observed that all programmers I respect and who are doing work that is worthy of respect in the hacker community eventually end up using Common Lisp as their primary mode of operation.
Is it possible somehow using C macros to make prefix notation and/or
Lisp syntax?
Probably.
For example, I want to write (f a b) instead of f(a, b); for C
compiler
No, you do not want to do that.
Just for fun!
Enjoy The International Obfuscated C Code Contest
I am translating 3rd party library API written in C to D. That library exports a lot of functions named like libname_foofunc, libname_barfunc etc., which is expectable for C library to prevent bloating global namespace. As D is more modular than C, I want to provide more D'ish interface and get rid of function prefix, so functions will look like libname.c.foofunc and libname.c.barfunc.
As library is unaware of my "improvements", I have to somehow translate libname.c.foofunc into libname_foofunc and preserve correct extern-linkage, destination name mangling and calling convention at the same time.
Assuming there is way (which I don't know either) to tell linker that external unresolved symbol __imp__D1c7foofuncFZi corresponds to _libname_foofunc or libname_foofunc#0 (despite the fact I have to do name mangling by hands), there is still problem telling D what calling convention is.
In case I explicitly specify extern(C) int foofunc() in libname/c.di, there is no longer calling convention problem, but name gets translated to _foofunc, which also differs from expected.
So, is there way in D to import foreign function under different name than it was exported?
I've though about importing functions "as is" under their original names and then alias-ing them to prefixless analogues, but this seems to be quite clumsy.
you can use
alias libname_foofunc foofunc;
this will keep the libname_foofunc visible but allows you to use foofunc and it will be transformed by the compiler into libname_foofunc
As far as linking goes, symbols are really a C thing, since we're talking about the C linker. D's situation with linking and exported symbols is basically the same as it is in C++, which is why there are mangled names and the like. You're going to have to create declarations for them in D using their original names, because that's what the linker is going to expect. D doesn't do anything different or magical which would change that. There are only two ways that you're going to be able to use different names.
alias the functions in your D code. You can just put the aliases in whatever module lists the symbols (since you have to declare them in D anyway). Then your code could use either the original names or the aliases. I don't see anything clumsy about that.
Create wrapper functions - either in C or D - and have your D code use those.
The aliases would definitely be better IMHO. They don't introduce any overhead and are less complicated.
But regardless, the normal thing to do when using C libraries from D is just to use the C function names. You're calling C functions, and that fact shouldn't be hidden. They're not D functions and don't act the same (even if they're similar) - especially when it comes to stuff like who owns the memory of what you're passing to functions. The gain in renaming them is debatable. It's usually when a D wrapper is written to give an API a cleaner, more D-like API (and not just changing the names) that the C functions aren't used directly anymore. A good example of this in Phobos would be etc.c.curl vs std.net.curl. etc.c.curl is purely the C API and doesn't attempt to rename anything. It doesn't create any aliases to make the symbols match Phobos' naming conventions or make them more D-like. It's essentially just the D version of the curl's header files. std.net.curl, on the other hand, builds on top of it to provide a more D-like API and abstraction. It does far more than rename the C functions.
Considering the last paragraph of the OT, the answer is NO. No other language can do it either, the way you described, and it should not. If API designers wanted to have function names in the way you like, they would expose them that way...
Now imagine group A of developers who prefer some_function(), then group B who prefer someFunction(), and group C who prefer SomeFunction()...
Aliasing is a must, no matter whether you use D or something else. And it should be that way. API should be simple, and concise, and easy to understand.
If you don't want to put the functions into modules you can keep them inside structs and simulate some sort of namespaces. E.g. you can do this:
struct libname
{
struct C
{
static int libname_foofunc();
alias libname_foofunc foofunc;
}
static C c;
}
void main()
{
libname.c.foofunc();
}