Compile unreferenced package with exported functions - ada

In a project mixing Ada and C, I define and export Ada functions to be called in the C program. The compile chain is complex and I don't have a possibility to make any change to it but when I compile the project, the package containing the exported function and thus not called by any Ada code is completely left out by the compiler. This mean that the linker can't do its work as it missing external function.
For example this simple three files project :
Main.adb
with Ada.Text_IO;
procedure Main is
begin
Ada.Text_IO.Put_Line ("Hello ada community");
end Main;
test.ads
package Test is
procedure Hello
with Export => True,
Convention => C,
Link_Name => "test_hello";
end Test;
test.adb
with Ada.Text_IO;
package body Test is
procedure Hello is
begin
Ada.Text_IO.Put_Line ("Hello world");
end Hello;
end Test;
When I compile my project, the package Test is ignored by the compiler. Is there a pragma to force the compiler to export the symbols and compile the package?

Found the solution which was quite obvious. I just have to include the package in the main.adb file.

Related

How to Compile the two procedure inside of package?

I have created three procedure inside of the package. Now want to compile the only two procedure inside of the package.
Is it Possible, If yes means How?
It's not possible. You compile can compile the package body separate from it's header, but not the individual methods in the package body, only the thing as a whole.
You can recompile it using the alter package statement. In its simplest form:
ALTER PACKAGE YourPackage COMPILE PACKAGE; -- Whole package
ALTER PACKAGE YourPackage COMPILE SPECIFICATION; -- Spec/header only
ALTER PACKAGE YourPackage COMPILE BODY; -- Body only

Combine R, C++ and Fortran

I am trying to reimplement an R function using C++ and RCpp to speed up the computation. And in the C++ implementation, I need to use a Fortran function mvtdst found in link.
#include <Rcpp.h>
#include "mvtnorm.h"
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector pmvnorm_rcpp(NumericVector upper, NumericMatrix corr)
{
double error;
double mvnP = pmvnorm_P(2, upper, corr, &error) ;
return mvnP ;
}
/*** R
pmvnorm_rcpp(c(1.5,1.5),c(0.0))
*/
Here, pmvnorm_P is defined in the mvtnorm.cpp file.
All the files found in link are kept in the working directory along with the RcppWrapper.cpp file.
When I compile my RcppWrapper.cpp file using sourceCpp() function in RCpp package, it gives the following error.
mvtnorm.o:mvtnorm.cpp:(.text+0x7c): undefined reference to `mvtdst_'
collect2.exe: error: ld returned 1 exit status
Error in Rcpp::sourceCpp("RcppWrapper.cpp") :
Error occurred building shared library.
Does anyone know how to resolve this error?
When you have code in two sources files
mvtnorm.cpp calling your backend function pmvnorm_P()
another file providing it
then you also must provide link instructions. Simply put, sourceCpp() is only intentended and working for one-file solutions (unless you give link instructions).
Simplest fix: just create a package assembling all your files in src/.
Fortran and C++ mangle the names of functions differently. It looks like mvtdst is the name of your Fotran function. (Right?) You need to "mangle" that by hand when called from C++. So instead of calling mvtdst, call mvtdst_ with the trailing underscore.
Unfortunately, compilers are not consistent in the mangling, so this will not be portable. (To make it portable, you'll need some sort of preprocessing that matched the mangling to the compiler.)

Add existing function to Package PLSQL

I am quite new to PLSQL programming so I am still facing general problems like this one.
I have developed some standalone functions (Oracle PLSQL functions) and I want to group them under the same package.
So I created a new package, but I have few questions about what to do next:
Is there any possible way to link directly functions to my package? I don't think so, but maybe...
Am I allowed to name functions within the package in the same way as the external functions or I will cause a scope problem?
Thank you for your help.
Marcello
You can't link stand-alone function to a package, you simply have to copy the code of the function into the package body, and the function specification into the package specification.
For example if you have:
create or replace function my_function
return number
is
begin
return 42;
end;
... then you could copy it into the package like this:
create or replace package my_package is
function my_function
return number;
end;
and
create or replace package body my_package is
function my_function
return number
is
begin
return 42;
end;
end;
You can give them the same name as the stand-alone functions without any issues. If you call one of these functions from within the package unqualified (just my_function) then you will be calling the package version; if you really wanted to call the stand-alone function from the package then you'd need to add the schema prefix: my_schmea.my_function. But hopefully you wouldn't really want to do that!

Build shared object from Fortran source with package(e.g. LAPACK) for R

I am new to create shared objects for R from Fortran sources. Perhaps some of my questions do not make sense. However, I have searched a lot about my questions but still get no clear answer. So, I would like to figure out what the big picture to create these shared objects(.dll files)in R is.
According some tutorials and manuals, I need to prepare a Fortran file mymodf.f, which contains only subroutines, similarly as below:
c file mymodf.f
subroutine initmod(odeparms)
external odeparms
double precision parms(3)
common /myparms/parms
call odeparms(3, parms)
return
end
subroutine derivs (neq, t, y, ydot, yout, ip)
....
return
end
subroutine jac (neq, t, y, ml, mu, pd, nrowpd, yout, ip)
....
return
end
c end of file mymodf.f
In order to create the shared object, it requires the following code:
system("R CMD SHLIB mymodf.f")
I want to use the subroutines in LAPACK to solve some linear equations or inverse matrices. What should I do so that I can call the subroutines in LAPACK? I ask this question because one needs to install packages in R to call some extra functions or one needs to add #include <xxxx.h> as header in C to call some extra functions in xxxx.h. Just the same situation.
Also, I have downloaded lapack-3.5.0.tgz from http://www.netlib.org/lapack. Where should I put package to? Do I need to install this .tgz file?
This is not a normal case to code, compile and run a Fortran program. I have some Fortran codes which is not a complete program and I want to complie it as .dll file for R.
Thanks very much for helping!
(FYI, I am working on a Windows 7 PC)
For a guy who has no experience about generating shared object from Fortran source for R, it is time-consuming to search the answer of the questions I asked above because there are really few tutorials which mention about these. It seems those who have experience about this do not see this thread.
If you want to call subroutines in LAPACK or BLAS, you need to create a file called Makevars with no file type which contains:
PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
Remark: you do not need to install libraries LAPACK and BLAS manually, R has already included them. All you need to do is to tell the compiler how to link them by creating the Makevars file under same directory of your Fortran source file. For other Fortran libraries, I don't know how to link them. Hope someone can provide a guide.
Then, you need to have a Fortran source, say name it my.f90 and it contains something like below:
subroutine LIN(a,b)
implicit none
integer, parameter :: n=2, nrhs=1
integer, parameter :: lda=n, ldb=n
double precision :: a(lda,n), b(ldb,nrhs)
integer :: info
call DPOSV('U',n,nrhs,a,lda,b,ldb,info)
end subroutine LIN
The next step is to compile the Fortran code as .dll file in Windows/.so file in Mac (this is so-called creating shared object for R). In order to compile the code in Windows, you need to have Rtools and R installed. Also, the path of your R should be added into "Path" of system variables. (Steps: Right click Computer icon->Properties->Advanced system settings->Environment Variables->Find and select "Path" in System variables->click "Edit" and add the path of your R, for example, C:\Program Files\R\R-3.0.2\bin;). Now, you are ready to compile the code. You need to open your R as run as administrator, change to the directory containing the Fortran file and then execute a command in R console:
system('R CMD SHLIB my.f90')
You will see that the shared object my.dll is created under the directory.
The final step is to load the shared object into R and run it. Following my example,
dyn.load('my.dll') #load the shared object
a<-diag(c(1,2)) #prepare arguments *a* and *b* for the Fortran subroutine
b<-c(3,4)
.Fortran("LIN",a=as.double(a),b=as.double(b)) #call the Fortran subroutine
Remark: you need to unload the shared object from R so that you can delete or compile over it when R is still running:
dyn.unload('my.dll')

Undefined package in Ada

I am really confused when the GNAT keeps telling me that I have an undefined error when I try to import a package.
This is the where the error occurs in the source code:
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure WordCount is
package ASU renames Ada.Strings.Unbounded;
use ASU;
package StringStack is new ProtectedStack(100, ASU.Unbounded_String);
It keeps telling me that the ProtectedStack is undefined.
Since the ProtectedStack is provided, so I have to assume that this error is caused by mine...
I just start to work with Ada. Could anyone please tell me how to solve this problem?
You probably need to add with ProtectedStack;.

Resources