lingua-franca icon indicating copy to clipboard operation
lingua-franca copied to clipboard

Specifying libraries to link is too difficult

Open edwardalee opened this issue 2 years ago • 10 comments

A common use case is that an imported LF reactor requires an external library, such as the math library in C. Unfortunately, we currently have no good way for the imported file to be self contained and specify this requirement. Moreover, the preferred way we have currently requires that the user of the imported file create a math-include.cmake file with this:

target_link_libraries( ${LF_MAIN_TARGET} m )

and then specify a target property:

   cmake-include: "math-include.cmake”

Alternatively, if the user is using gcc or clang, then just the following target property will work:

   flags: "-lm"

This falls pretty low on the usability scale.

I suggest a new target property, something like:

   link-libraries: ["m"]

This could be a list of required libraries. This would be put in the imported file and would need to be translated into the appropriate lines in the generated cmake file or into compiler flags if not. If multiple imported files specify the same libraries, these would be consolidated.

Other (better) ideas?

edwardalee avatar Apr 28 '22 14:04 edwardalee

link-libraries: ["m"] sounds like a good solution to me.

However, we would still have the issue of imported .lf files not being self-contained because link-libraries of imported files could potentially conflict with each other. As @cmnrd pointed out, I think we would still need the ability to separately compile imported .lf files into libraries and linking them together in order to have properly self-contained imported .lf files.

Soroosh129 avatar Apr 28 '22 15:04 Soroosh129

The proposed solution oversimplifies the problem and only works for C standard libraries (like math). Linking to libraries in C/C++ is complicated and messy, and there is no way around it (unfortunately).

Let's say we have a library foo and want to link to it. It is not as simple as adding -lfoo to the flags. We need to know: Where is foo located? Are there dependent libraries? Do we need to add headers to the include path? Are there any macros that need to be defined? These are just the most important questions. Cmake provides various mechanisms to answer these questions specifically for the host system and to adjusts compiler flags accordingly. However, cmake still does not provide us with a standardized way for importing a library. How to find and link to libraries completely depends on the tools used and design decisions made by the library developer. In most cases, the cmake code for importing the library needs to be written specifically for this library and cannot (easily) be auto generated.

The cmake-include property is the most general solution that I can think of. And it shouldn't be difficult to use for C/C++ programmers. I completely understand the drive to provide a simpler mechanism, but this mechanism will either be very limited in functionality or overly complicated (i.e. a self-written C/C++ package manager).

If you ant to go with this property, I would suggest to rename it to link-standard-libraries to reflect that it only works for standard libraries. Otherwise, we will have users wondering why they get weird compile errors when they try link-libraries: foo.

cmnrd avatar Apr 29 '22 08:04 cmnrd

If we are to go with a cmake solution instead, then we need to find a way to safely integrate cmake-include files specified in imported reactors.

edwardalee avatar Apr 29 '22 14:04 edwardalee

I agree. A cheap but effective solution would be to just collect all cmake-includes specified in all imported lf files and merge the list. This will not work correctly in all corner case, but it should work for most examples that we are currently considering.

As I outlined in my e-Mail, the "full" solution would be to compile each *.lf file as a library. Then we would only need to consider the build properties given for this specific *.lf file, and cmake could take care of all the rest for us when linking the resulting binary. For C++ this should be a relatively minor change, but for C it is a longer way, as we would first need to redesign the code generator to produce individual source and header files.

cmnrd avatar Apr 29 '22 15:04 cmnrd

Actually, since the C generator puts all reactors in a single file, merging all the cmake-include files is precisely the behavior we want. The resulting C file needs to be compiled with all the flags and libraries specified for any of the used reactors. If there are any problems resulting from merging these merged properties (for instance because of name conflicts between libraries), then we currently don't have a mechanism to work around this in C anyway.

cmnrd avatar Apr 29 '22 15:04 cmnrd

Note that this technique will likely not work for extended reactors. This may be an issue when Cpp implements extends.

edwardalee avatar Apr 29 '22 22:04 edwardalee

I agree with @cmnrd that if we have this feature it's scope should be limited to standard libraries. Maybe link-standard-libraries is a bit long; I'd also be fine with link-std-libs, but link-libraries is too broad and will cause confusion.

lhstrh avatar Apr 30 '22 22:04 lhstrh

I don't really understand this objection. When used with nonstandard libraries, it probably will not be in a context of something that is likely to be widely reused on multiple platforms, unlike the math library.

edwardalee avatar May 01 '22 08:05 edwardalee

You might be right. But even if we call it link-libraries, I'd like to make sure we can properly handle all standard libraries on all platforms before adding this feature just to handle math.h.

lhstrh avatar May 01 '22 17:05 lhstrh

@edwardalee Could you elaborate why you think there might be problems with extended reactors? As far as I can see, there should be no problems. A class defined in one library can easily extend a class defined in another one.

I don't really understand this objection. When used with nonstandard libraries, it probably will not be in a context of something that is likely to be widely reused on multiple platforms, unlike the math library.

There are many non-standarad libraries (as in: not part of the C standard) that are used cross-platform. However, even if an LF program is written specifically for Linux and uses Linux-only libraries, the name suggests that link-libraries could just import and use those libraries, which will not work in many cases.

cmnrd avatar May 02 '22 07:05 cmnrd