Using external library in D - external

I have a DMD + Tango bundle on linux. Please give me the step by step information, how can I use an external library in D, for example zlib. I have compiled zlib.
I have a file tree like this:
myzlib
├── include
│   ├── zconf.h
│   └── zlib.h
└── lib
└── libz.a
I've got the import tango.io.compress.ZlibStream; call in my myfile.d source.
And these are my questions:
Do I need to copy these files to the dmd/lib directory?
Do I need to modify dmd/bin/dmd.conf file?
How should I call dmd compiler (dmd myfile.d -Llibz.a) or something else (maybe, with absolute paths)?
I've never tried to use external libraries in any other language. Please help me.

The -L flag tells the linker to add a particular directory to its search path.
-l tells it to link in a particular library, and it searches on its search path to find that library.
With DMD, you have to pass flags to the linker with the -L flag.
It can take either absolute or relative paths, but the paths need to be relative to where the compiler is run from. So if you use relative paths, then you always have to run the compiler from the same directory (which generally isn't a problem, since you'd typically have the build command in a Makefile which you always run from the same directory).
The most common thing is to use absolute paths for libraries installed on the system and relative paths for libraries specific to your project.
So, if you have the library myzlib/lib/libz.a, you would pass -L-Lmyzlib/lib -L-lz to dmd.
It would then add myzlib/lib to the linker's search path, and then look for libz.a in its search path (the linker knows to take the part following -l, add lib to the front of it and add .a suffix to the end to get the library that you're looking for).
You can add the linker flags to dmd.conf, but I really wouldn't advise it. The flags in dmd.conf are what dmd always uses for every program. So, you should really only have the flags there that are used in all of your programs.
Rather, feed them to dmd directly (be it on the command line or as part of a Makefile).
As for the header files, you're going to need to duplicate any of their declarations that you need in a .d file.
Header files are used by the C or C++ compiler, not the linker. D shares the same linker as you'd use for C or C++, but its compiler is dmd, not gcc.
So, you need to duplicate the C declarations in a D file. The simplest way to do that is with htod utility, but it only works in Windows or Wine.
Regardless, you'll need to declare the C declarations that you'd be using in a .d file and mark them with extern(C).

If you set up your build to do the compile and link steps separately (like it is common to do with c), it is essentially identical to doing the same with C. First, get your build working without the extra lib (to make sure you are passing all the needed flags to the linker) and then add the libs in as normal. To use a C library from D requires a bindings file, they are effectively just a D file consisting only of prototypes.

Related

How to make an Octave path root folder for all subfolders

I have a folder for Octave M-files in C:\\Users\Dropbox\Octave, under which are various subfolders by function categories (normal distribution, chisq...). I just started making those subfolders and they will keep changing (adding, removing, reshuffling) as time goes on.
I would just like to set that folder as root and have Octave search for functions recursively there, just like you set a classpath in Java and JVM searches all folders there.
I used addpath(genpath('C:\\Users\Dropbox\Octave')), but the paths generated are then fixed, not reflecting subsequent subfolder changes.
Shall I add addpath(genpath('C:\\Users\Dropbox\Octave')) to the .octaverc file?
I think there is some confusion here. There are several ways to interact with the path, but for the most part these do not result in permanent changes, unless you save this somehow.
Simply adding a path for an existing octave session will not result in any permanent changes to the usual path that octave initialises at startup. Therefore when you say:
I used addpath(genpath('C:\Users\Dropbox\Octave')), but the paths generated are then fixed, not reflecting subsequent subfolder changes.
this makes no sense, because as soon as you exit your octave session, those added paths should have been gone altogether, and not appear in later octave sessions.
It is more likely that at some point you added these paths, and then used the savepath command, which resulted in your custom paths being added to your .octaverc file.
If that is the case, then yes, you can expect that octave will not "update" what was written in your .octaverc file, unless you call savepath again with an updated path definition.
If you would like the addpath(genpath('C:\Users\Dropbox\Octave')) command you mentioned to be called every time octave starts, so that the current/updated directory structure is loaded, then yes, the best way to do it would be to add that command to your .octaverc file. Make sure you remove the lines in your .octaverc that refer to the previous changes made by savepath. Note that there may be several levels of octaverc files that you need to check (see the relevant page in the manual)
Alternatively, you could simply make sure that this line appears in every script you want to call which intends to make use of those files.
While you may consider this last approach tedious, programmatically it is the most recommended one, since it makes dependencies clear in your code. This is especially important if you ever plan to share your code (and doubly so if you'd like it to be matlab compatible).
PS. All the above mostly applies to matlab too, with the exception that a) matlab's savepath saves path information in a file called pathdef.m, rather than directly in your startup files, and b) matlab uses startup.m instead of .octaverc as startup files. Also, if you don't care about doing this programmatically, matlab provides pathtool, which is a graphical interface for adding / saving directories to the matlab path.

How to use a relative program path in a PhpStorm file watcher

In PhpStorm (as well as other JetBrains IDEs, I'm sure), I'm setting up a File Watcher. In the Watcher Settings section, it asks me to specify the path to the program to be executed.
I want to use the executable file within the node_modules/.bin directory of my project. I don't want it installed globally because I may have other projects that use the same program, but may require a different version.
I could simply specify the absolute path to my project's node_modules/.bin directory, but then if I move the project, the file watcher will break.
In the Arguments and Output paths to refresh fields just below the Program field, it allows you to insert a macro, like $Projectpath$. This is exactly what I need, but it doesn't look like the Program field allows that.
Is there a way to specify a relative path for the Program field?
Here is a screenshot of the File Watcher setup window:
I could simply specify the absolute path to my project's node_modules/.bin directory, but then if I move the project, the file watcher will break.
That's not true -- at very least it does not break anything here -- got 3 projects that use local stuff.
Is there a way to specify a relative path for the Program field?
Sure. Use full path to the program :)
Internally (in config file) it will be stored using $PROJECT_DIR$ (AFAIK) special macro/variable but in actual field (in that dialog window) you will always see full path. Such conversion is done automatically.
You can read a bit more here (in comments): https://youtrack.jetbrains.com/issue/WEB-24376
If you are using the same project on different computers ... where path to the same program will be different but outside of the project (e.g. stored inside user-specific folder and user logins/names are different on such computers) ... you could use Path Variables functionality (Settings/Preferences | Appearance & Behavior | Path Variables) and specify the same variable on all of such computers that would point to correct path on that computer. IDE will automatically use that path variable to store the path.
So .. on one computer MY_TOOL_PATH will be pointing to /Users/Joe/MyTool and on another it could be /Users/Sam/AnotherTool.

How to use ceylon js (also with google closure compiler)

Calling a file resulting from the concatenation (bash: cat ... >> app.js) of the following three files:
/usr/share/ceylon/1.2.0/repo/ceylon/language/1.2.0/ceylon.language-1.2.0.js
modules/com/example/helloworld/1.0.0/com.example.helloworld-1.0.0-model.js
modules/com/example/helloworld/1.0.0/com.example.helloworld-1.0.0.js
with the command nodejs app.js does nothing. The same when used in a web page. How do have I to call that javascript program so that it runs without using require.js ?
Please give the rules how ceylon modules and the run function and other functions contained within translate to javascript and are to be called.
How can I get one javascript file from compilation of several ceylon modules without concatenating them manually or with require.js?
The above is without using google closure compiler.
Given the size of 1.6 MB of the language module, it makes no sense to run ceylon-js without using google closure compiler.
Compiling "ceylon.language-1.2.0.js" alone with google closure compiler results in a lot of warnings.
java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js /usr/share/ceylon/1.2.0/repo/ceylon/language/1.2.0/ceylon.language-1.2.0.js --js_output_file lib-compiled.js
How can I get rid of those warnings?
In what order do I have to chain together files resulting from ceylon-js with the model file and the language file to compile them in advanced mode with google closure compiler for dead code elimination.
These are 3 questions, really.
A Ceylon module is compiled to a CommonJS module. Concatenating the resulting files won't work because each file is on CommonJS format, which is a big function that returns an object with the exported declarations.
You can compile the modules with the --no-module option to get just the generated code, without it being wrapped in CommonJS format. For the language module, you can copy the file and just delete the first line and the last 5 lines.
I do not yet know how to get rid of the warnings you mention in the second question.
And as for the third question, I would recommend putting the language module first, then the rest of the files. If you have any toplevel declarations with the same name in different modules, you'll have conflicts (only the last declaration will remain), even if they're not shared, since they're all in the same module/unit.
Well, I think require.js can run the compilation of the modules to one file and then run the google-closure-compiler, see: http://www.requirejs.org/docs/optimization.html

Erlang: How to include libraries

I'm writing a simple Erlang program that requests an URL and parses the response as JSON.
To do that, I need to use a Library called Jiffy. I downloaded and compiled it, and now i have a .beam file along with a .app file. My question is: How do I use it? How do I include this library in my program?. I cannot understand why I can't find an answer on the web for something that must be very crucial.
Erlang has an include syntax, but receives a .hrl file.
Thanks!
You don't need to include the file in your project. In Erlang, it is at run time that the code will try to find any function. So the module you are using must be in the search path of the VM which run your code at the point you need it, that's all.
For this you can add files to your path when you start erlang: erl -pa your/path/to/beam (it exists also -pz see erlang doc)
Note that it is also possible to modify the path from the application itself using code:add_path(Dir).
You should have a look to the OTP way to build applications in erlang documentation or Learn You Some Erlang, and also look at Rebar a tool that helps you to manage erlang application (for example starting with rebar or rebar wiki)
To add to Pascal's answer, yes Erlang will search for your files at runtime and you can add extra paths as command line arguments.
However, when you build a project of a scale that you are including other libraries, you should be building an Erlang application. This normally entails using rebar.
When using rebar, your app should have a deps/ directory. To include jiffy in your project, it is easiest to simply clone the repo into deps/jiffy. That is all that needs to be done for you to do something like jiffy:decode(Data) in your project.
Additionally, you can specify additional include files in your rebar.config file by adding extra lines {erl_opts, [{i, "./Some/path/to/file"}]}.. rebar will then look for file.so using that path.

SWIG TCL Static Linking

I am trying to use SWIG to generate wrappers for some of my C++ function calls.
Also, I am trying to do build my own TCL shell so I need to static link the generated SWIG libraries. I have my own main function with a Tcl_AppInit call where I do some prior setup.
To do this what function should I include in my program's Tcl_AppInit call? I found that SWIG_init is not the right function. I even tried Cell_Init where cell is the name of the class in my code, but that doesn't help either.
How do I static link SWIG object files with my own main function and Tcl_Appinit call?
Currently when I use the following command to link my executabel I get the following error:
g++ -o bin/icde src/core/*.o src/read/*.o src/swig/*.o src/icde/*.o -ltk -ltcl
I get the following error:
src/icde/main.o: In function `AppInit(Tcl_Interp*)':
main.cpp:(.text+0xa9): undefined reference to `Cell_Init(Tcl_Interp*)'
collect2: ld returned 1 exit status
I checked the src/swig/cell.o file which has the Cell_Init function or not using objdump:
~> objdump -d src/swig/cell.o | grep Cell_Init
00006461 <Cell_Init>:
646c: 75 0a jne 6478 <Cell_Init+0x17>
I am not sure if I am doing something wrong while linking.
------------------- UPDATE ----------------------------
I found that including the swig/swig.cxx file directly in the main file which calls the Tcl_AppInit function resolves the linking issue. Is there a reason for this.
Isn't it possible to create and seprately link the swig file and the file with the main function?
In general, with SWIG you'll end up with a bunch of generated source files that you compile. The normal thing you do then is package them up into a shared library (with appropriate bound dependencies on other shared libraries) that can be imported into a Tcl runtime with the load command.
But you don't want that this time. Instead, you want the object files that you would use to make that shared lib, and you want to include them in the instructions to build an executable along with the object file that holds your main and Tcl_AppInit. You also need to make sure that when linking your main executable that you make it dependent on those external shared libraries; executable building requires that you satisfy all dependencies and make all symbols be bound to their definitions. (You can use a static library to make this easier: it combines a bunch of object files into one file. There's very little difference to just using the object files from it though; in particular, static libraries aren't bound to their dependencies.)
Finally, you do want to include a call to Cell_Init in your Tcl_AppInit. That's the right place to put it (well, as long as you're not arranging for the package to be loaded into sub-interpreters). If it was failing before, that was because you'd got your linking wrong. (Tip: linkers work best when objects and libraries on the link line only depend on things later on the link line. Getting the link order right is a bit of a black art when you've got a complex build!)