Can I include libraries in an mli file?
For example, say I make the following mli file
include Base
val bluh : int -> int
I get an unbound module Base error.
But, If I change the file to a .ml file, and change the contents to
include Base
module type bluh1 = sig
val bluh : int -> int end
it compiles. So the Base library is clearly around, I just can't use it in an .mli file for some reason.
Thank you!
I get an unbound module Base error.
This is actually not the error that you are getting. The compiler is actually saying,
Unbound module type Base
Emphasis on module type.
When you define an interface in the mli file you're defining types and signatures not values and module implementations. So you can, but don't do this, include the signature of the module Base using the following syntax,
include module type of Base (* a very bad idea, but works *)
But don't do this. There is absolutely no reason to take the whole Base library (which is huge) and include all its implementation and interface into your own module. In order to use a library, you don't need to do anything in the source code, i.e., you don't need to include or open or otherwise require or import it. Libraries in OCaml, as well as in most compiled languages, are managed on the toolchain (aka compiler) level. So if you need a library you shall instruct your build system to link with it (e.g., add it to the libraries stanza in dune or to BuildDepends in oasis, etc).
As far as I can see, you have already done this. Now if you want to use a function (or a module or any other definition) from the Base module of the base library, you just need to prefix it with Base. e.g.,
let empty = Base.Map.empty (module Base.String)
If you don't want to prefix every name, you can use open Base in the beginning of your module, this will allow you to reference any definition in Base without explicitly prefixing it, e.g.,
(* the recommended way *)
open Base
let empty = Map.empty (module String)
While in general it is not recommended to open a module, some modules are designed to be opened, and try not to pollute your namespace with definitions. The Base module is an example of such a module, especially since it acts like an overhaul of the standard library.
Related
To make available some useful function in CINT (C++ interpreter of ROOT), I configured my rootrc config file to execute a rootlogon.C file each time I run root to launch the interpreter.
In rootlogon.C, this piece of code is present:
{
gROOT->ProcessLine("#include \"GenericToolbox.h\"");
}
This line is kind of working as intented since I'm then able to access most of the defined function in the header file. However the functions involving template can't be accessed. I understand that because this is a header-only library, the interpreter can't predict which object types will be used as template definition.
So do you know if I could make a kind of shared library that could be loaded in the rootlogon, which would define specific template functions?
I've seen some examples suggesting to utilize a LinkDef.h file which contains #pragma link C++ function lines to specialize templates, but I don't understand how to use it...
Any idea?
We are mocking our code but we are having difficulties eliminating the dependency of other files the mocked file includes due to the mocked header including the original header which includes several other files.
The error we are getting below:
In file included from ../nRF5_SDK_11.0.0_89a8197/components/softdevice/s130/headers/ble_gap.h:48:0,
from ../nRF5_SDK_11.0.0_89a8197/components/softdevice/s130/headers/ble.h:52,
from ../infrastructure/microcontroller_abstraction/ble/include/ble_service.h:4,
from ../infrastructure/system_abstraction/pressure/include/pressure_service.h:15,
from ./mocks/pressure_service_mock.h:5,
from ./mocks/pressure_service_mock.c:7:
../nRF5_SDK_11.0.0_89a8197/components/softdevice/s130/headers/ble_gap.h: In function 'sd_ble_gap_address_set':
../nRF5_SDK_11.0.0_89a8197/components/softdevice/s130/headers/nrf_svc.h:66:5: error: unknown register name 'r0' in 'asm'
__asm( \
^
It is due to the following sample scenario:
lets take a sample file pressure service mock.c for example
the mock.c ---- includes ---> mock.h
the thing is, since mock.h is generated, it is including the the pressure_service.h
and since we are including the pressure_service.h , it is trying to include the ble_service.h
and then up the hierarchy of includes
the c files of the original SDK is NOT compiled
but the header files have to be included
how would we stop Cmock from including the pressure_service.h?
Please assist i believe this is a generic problem and it is the whole purpose of why one would utilize CMOCK, but we cannot seem to find the solution.
Short answer:
AFAIK there is no option for CMOCK to dismiss any of the includes of the mocked C module. It is only possible to specify additional includes.
Depending on your structure of include directories you can try to replace the obstructive header (pressure_service.h in your example) by a strip-down copy of the original header, which reduces any additional dependencies to the minimum.
Long answer:
IMHO you are not facing a generic problem of CMOCK here but a design problem of the module your are trying to mock. It is a tried and tested practice that the header of a C module should only include further header files, which are needed by the public interface of this module. Typical dependencies are type definitions, that are used for arguments and/or return values of interface functions. Since mocking a module means to provide a fake implementations of the specified interface, CMOCK needs to copy all of the original includes over to the mock implementation, in order to make it compile.
This problem can usually be solved reducing the dependencies of original header (the one to be mocked), which usually leads to a better software architecture in general. If the module to be mocked comes from a third party library, this is usually beyond reach, though. In this case, a workaround is making a copy of the original header and stripping it down to the minimum functionality required for the unit test. Of course this implies, that any change to the original interface needs to be manually transfered to strip-down copy later. In case of a stable third party module that should not be a big problem, though.
I'm trying to use a third party C++ library that isn't using namespaces and is causing symbol conflicts. The conflicting symbols are for classes my code isn't utilizing, so I was considering creating custom header files for the third party library where the class declarations only include the public members my code is using, leaving out any members that use the conflicting classes. Basically creating an interface.
I have three questions:
If the compilation to .obj files works, will this technique still cause symbol conflicts when I get to linking?
If that isn't a problem, will the varying class declarations cause problems when linking? For example, does the linker verify that the declaration of a class used by each .obj file has the same number of members?
If neither of those are a problem and I'm able to link the .obj files, will it cause problems when invoking methods? I don't know exactly how C++ works under the hood, but if it uses indexes to point to class methods, and those indexes were different from one .obj file to another, I'm guessing this approach would blow up at runtime.
In theory, you need identical declarations for this to work.
In practice, you will definitely need to make sure your declarations contain:
All the methods you use
All the virtual methods, used or not.
All the data members
You need all these in the right order of declaration too.
You might get away with faking the data members, but would need to make sure you put in stubs that had the same size.
If you do not do all this, you will not get the same object layout and even if a link works it will fail badly and quickly at run-time.
If you do this, it still seems risky to me and as a worst case may appear to work but have odd run time failures.
"if it uses indexes ": To some extent exactly how virtual functions work is implementation defined, but typically it does use an index into a virtual function table.
What you might be able to do is to:
Take the original headers
Keep the full declarations for the classes you use
Stub out the classes and declarations you do not use but are referenced by the ones you do.
Remove all the types not referenced at all.
For explanatory purposes a simplified explaination follows.
c++ allows you to use functions you declare. what you do is putting multiple definitions to a single declaration across multiple translation units. if you expose the class declaration in a header file your compiler sees this in each translation unit, that includes the header file.
Therefore your own class functions have to be defined exactly as they have been declared (same function names same arguments).
if the function is not called you are allowed not to define it, because the compiler doesn't know whether it might be defined in another translation unit.
Compilation causes label creation for each defined function(symbol) in the object code. On the other hand a unresolved label is created for each symbol that is referenced to (a call site, a variable use).
So if you follow this rules you should get to the point where your code compiles but fails to link. The linker is the tool that maps defined symbols from each translation-unit to symbol references.
If the object files that are linked together have multiple definitions to the same functions the linker is unable to create an exact match and therefore fails to link.
In practice you most likely want to provide a library and enjoy using your own classes without bothering what your user might define. In spite of the programmer taking extra care to put things into a namespace two users might still choose the same name for a namespace. This will lead to link failures, because the compiler exposed the symbols and is supposed to link them.
gcc has added an attribute to explicitly mark symbols, that should not be exposed to the linker. (called attribute hidden (see this SO question))
This makes it possible to have multiple definitions of a class with the same name.
In order for this to work across compilation units, you have to make sure class declarations are not exposed in an interface header as it could cause multiple unmatching declarations.
I recommend using a wrapper to encapsulate the third party library.
Wrapper.h
#ifndef WRAPPER_H_
#define WRAPPER_H_
#include <memory>
class third_party;
class Wrapper
{
public:
void wrappedFunction();
Wrapper();
private:
// A better choice would be a unique_ptr but g++ and clang++ failed to
// compile due to "incomplete type" which is the whole point
std::shared_ptr<third_party> wrapped;
};
#endif
Wrapper.cpp
#include "Wrapper.h"
#include <third_party.h>
void Wrapper::wrappedFunction()
{
wrapped->command();
}
Wrapper::Wrapper():wrapped{std::make_shared<third_party>()}
{
}
The reason why a unique_ptr doesn't work is explained here: std::unique_ptr with an incomplete type won't compile
You can move the entire library into a namespace by using a clever trick to do with imports. All the import directive does is copy the relevant code into the current "translation unit" (a fancy name for the current code). You can take advantage of this as so
I've borrowed heavily from another answer by user JohnB which was later deleted by him.
// my_thirdparty.h
namespace ThirdParty {
#include "thirdparty.h"
//... Include all the headers here that you need to use for thirdparty.
}
// my_thirdparty.cpp / .cc
namespace ThirdParty {
#include "thirdparty.cpp"
//... Put all .cpp files in here that are currently in your project
}
Finally, remove all the .cpp files in the third party library from your project. Only compile my_thirdparty.cpp.
Warning: If you include many library files from the single my_thirdparty.cpp this might introduce compiler issues due to interaction between the individual .cpp files. Things such as include namespace or bad define / include directives can cause this. Either resolve or create multiple my_thirdparty.cpp files, splitting the library between them.
The question is obvious I think, although I googled it, I could not find any solutions. I want to split my source code to keep it more maintainable. How can I reference a module in another file?
I think that you are looking for the use statement. You might, for example, have one source file containing the definition of a module, outline:
module abstract_types
implicit none
! declarations
contains
! procedure definitions
end module abstract_types
and then, in another source file, a program which uses the module, outline:
program hello_there
use abstract_types
implicit none
! declarations
! executable statements
end program hello_there
Note:
Any use statements precede the implicit statement.
The use statement refers to the module by name.
When it comes to compilation, make sure that you compile the module source file before the program source file; at compilation time (not at link time) the compiler will look for a module file (often called a mod file) to satisfy the reference to the module in the use statement. The mod file is a bit like a header file, but it's created by the compiler.
Later, when you link your program you'll need the object files for both module and program.
I have a Fortran module that contains some variables that have the attribute parameter and some have the attribute save. The parameter ones are not included in the compiled object, which becomes a problem when trying to assemble a library. For example, consider a file testModule.f90:
module testMOD
integer, save :: thisIsSaved = 1
integer, parameter :: thisIsParametered = 2
end module testMOD
I compile this with: ifort -c testModule.f90. When I check what's inside it:
>$ nm testModule.o
0000000000000000 T testmod._
0000000000000000 D testmod_mp_thisissaved_
only the thisIsSaved variable is there. I know that I can just change thisIsParametered to save rather than parameter but, ideally, I'd like to prevent a linking user from changing this value. Is there a way to do this?
Edit: I'd like this library to be accessible to C codes, as well, not just Fortran.
That should actually be stored in the .mod file. All of the data types and function prototypes are stored there which is why you need to include it when you send someone a .lib file. Try linking in the module after using it in something else and it should work just fine.
Essentially the .mod file serves the same purpose as the .h file in c, so of course you are going to have to include it with your library.
[update:]
If you are attempting to use this in C, then as you said, there is no means for you to easily maintain the named constant. As an alternative, you can use the protected attribute on the entity. At least with Fortran, anything outside of the module is restricted from writing to the variable. I don't know if the C compiler and the linker will respect this behavior, but I think this is probably your best shot.
module testMOD
INTEGER, PROTECTED, BIND(C) :: globalvar = 1
end module testMOD
Unfortunately I don't really do much with interoperability with C, so I can't really guarantee that C will respect the protected attribute and not allow the variable to be changed.
As others have noted, a parameter is a named constant and implementations may not set aside storage for that constant in the object code (particularly for scalars).
Your library should provide a header file for your C clients. You can define the value of the Fortran parameter in that header file, either by #define or const.
This requires maintenance of the value of the parameter in two places, but you already have that maintenance burden with other aspects of the library's interface.