www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Import paths do not work

reply "tcak" <tcak gmail.com> writes:
I have a library that has many folders and D files in them. I do 
not want to list name of all module files one by one while 
compiling projects. So, I thought I could use "-I" flag while 
compiling. It says:

-Ipath
     where to look for imports

So, I made a test as follows:


./test.d
==================================
import inc.blah;

void main(){
	inc.blah.a = 5;
}


./inc/blah.d
==================================
module inc.blah;

public int a;


./makefile
==================================
all:
	dmd -I"./inc/" test.d


When I do "make", result is as follows:

dmd -I"./inc/" test.d
test.o: In function `_Dmain':
test.d:(.text._Dmain+0x10): undefined reference to 
`_D3inc4blah1ai'


Do I understand wrong how that "-I" flag works?
Jan 28 2015
next sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 29/01/2015 8:08 p.m., tcak wrote:
 I have a library that has many folders and D files in them. I do not
 want to list name of all module files one by one while compiling
 projects. So, I thought I could use "-I" flag while compiling. It says:

 -Ipath
      where to look for imports

 So, I made a test as follows:


 ./test.d
 ==================================
 import inc.blah;

 void main(){
      inc.blah.a = 5;
 }


 ./inc/blah.d
 ==================================
 module inc.blah;

 public int a;


 ./makefile
 ==================================
 all:
      dmd -I"./inc/" test.d


 When I do "make", result is as follows:

 dmd -I"./inc/" test.d
 test.o: In function `_Dmain':
 test.d:(.text._Dmain+0x10): undefined reference to `_D3inc4blah1ai'


 Do I understand wrong how that "-I" flag works?
Basically during linking not all symbols used is passed in. You are doing a single compile + link. So what -I does is tell the compiler to look for definitions in files on the paths specified. But does not compile them into the binary output. I would suggest instead of using make, use dub[0] build manager instead. It'll handle grabbing all the files and compiling them correctly. [0] http://code.dlang.org/package-format
Jan 28 2015
parent reply "Atila Neves" <atila.neves gmail.com> writes:
 I would suggest instead of using make, use dub[0] build manager 
 instead.
 It'll handle grabbing all the files and compiling them 
 correctly.

 [0] http://code.dlang.org/package-format
Or for simple projects such as this one seems to be, just use rdmd. Atila
Jan 29 2015
parent "tcak" <tcak gmail.com> writes:
On Thursday, 29 January 2015 at 10:26:56 UTC, Atila Neves wrote:
 I would suggest instead of using make, use dub[0] build 
 manager instead.
 It'll handle grabbing all the files and compiling them 
 correctly.

 [0] http://code.dlang.org/package-format
Or for simple projects such as this one seems to be, just use rdmd. Atila
I am using Mono-D on MonoDevelop. I was normally keeping all library files in the same project. But copying same library codes between different projects didn't seem like a good idea. Then I copied library files as "symbolic link" to project, but this time, if I put a new module in library folder, Mono-D doesn't see it automatically. Then I saw "Include" part in project properties which uses "-I" flag while compiling the project. I removed all symbolic links from project, and added full folder paths of libraries to that "Include" list. As you can guess, as I asked in the question, it doesn't see library files now. I still have a solution as linking to library modules, but I wondered whether it was possible in another "easier" way.
Jan 29 2015
prev sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
Let me try to explain the compilation process which may help you 
to understand where your problem lies.

* Build system
	* Maintain program/library dependencies
	* Execute commands resulting in a usable program/library
* Compiler
	* Lexical Analysis
	* Parsing
	* Language translation
	* Optimizations
* Linker
	* Combine machine code from multiple locations
	* Optimizations

Each stage is feeding into the next and interacting with one may 
not require explicit interaction for the next.

=== Linker
The linker is at the bottom of our list because it will be the 
final step in creating an executable/library. There is not one 
single linker, there are many for different operating systems and 
programming languages. The 'ld' linker is common on Linux, 
Windows has a linker called link, and DMD makes use of optlink 
for its 32-bit build.

At the time the linker is called the source code has already been 
translated into machine code by the compiler. So the linker has a 
simple task of packaging up the machine code which makes up your 
program. This means locating the machine code for libraries being 
used and combining it with the instructions you've specified. One 
of the most common errors you'll receive from a linker is that it 
can't find the corresponding machine code.

Consider yourself the linker and, as the compiler, I will request 
that you do some work for me. The programmer has asked me to 
compile decentApp.d for them and makes a call to spiral(). If I 
give you the machine code for decentApp could you please include 
the machine code for famous.awesome.spiral() too? Are you able to 
locate machine code for famous.awesome.spiral?

The answer is that you can't, not with out being told where to 
look, what to look for, or searching every location for any 
machine code matching that symbol (when you make function calls 
the linker doesn't care it is a function, it considers it a 
symbol or reference for some chunk of machine code).

The solution, tell the linker where it will find the code, it is 
just a polite thing to do.

Once the linker has all the code it can perform optimizations, 
one of the most common is throwing out code which isn't being 
used.

=== Compiler
The compiler is a translation tool, making conversion from one 
language to another.

When it translates a chunk of code, there can be references to 
other chunks some of which may have already been compiled, and 
some that may still need compiled. What is important to the 
compiler is making sure that the call out to that chuck of code 
is formed in the agreed upon structure. It does this by examining 
the function signature, in C/C++ we see this information provided 
through a header file.

Since the compiler doesn't have to build every chunk of code that 
the program is being run, as long as it has the function 
signature it can translate code that call into some unknown 
location. And this is where the -I flag comes in play. When you 
provide the -I with a location, it signals to the compiler that 
it should look for the function signatures of this code chunk in 
the locations specified.

However, the compiler does not build the code that it finds, it 
expects you have already done that because you're not telling it 
to build that code. It will then pass off the translated code to 
the linker and request an executable be built.

The linker however only knows about the code the compiler has 
told it about (and some default search locations). If it can find 
it in the code provided by the compiler, or the places it was 
told to search then it will fail.

This is where the -l linker flag comes in (assuming Linux), when 
passed on the compiler it would be -L-l (pass to the linker the 
flag -l). Using -l specifies what libraries to find reference 
code in, and -L is used to specify what directories to look in 
for the requested library.

----

When you tell the compiler to build your code and it will find 
some of the code over here in -I"foo" it is probably wrong if you 
don't also include a -L-l and possibly -L-L in that same command.

Most likely you want a build system that handles dependencies for 
you, check out DUB.
Jan 29 2015