Allow me summarise.
1) The following is the test code you have provided. I have only changed VARs to CONST in both M1.mod to easier check in the assembly file which module is actually imported. But importantly, both M1.mod have a different public interface.
Structure:
Code: Select all
+ Test2
+ P1.mod
+ prog
+ M1.mod
+ lib
+ M0.mod
+ M1.mod
Code:
Code: Select all
MODULE P;
IMPORT Main, M0, M1;
VAR p: INTEGER;
BEGIN
p := M1.prog
END P.
MODULE M0;
IMPORT M1;
END M0.
MODULE M1; (* in 'lib' *)
CONST lib* = 42;
END M1.
MODULE M1; (* in 'prog' *)
CONST prog* = 13;
END M1.
MODULE Main;
END Main.
Search path:
Code: Select all
C:\Astrobe\Test2\prog
C:\Astrobe\Test2\lib
2) You said that "the following code results in the error: 'Module M1 - wrong version".
3) I have demonstrated that this is not necessarily the case, but that the program compiles and links without problems, if we start building P.mod from directories void of any symbol and object files.
Code: Select all
Astrobe for RP2350 Builder v10.0.1
Builder Phase 1: Checking P.mod and imported modules...
Checking Module Main
Imports:
Folder: C:\Astrobe\Test2\lib
Status: Missing Main.arm file
Checking Module M1
Imports:
Folder: C:\Astrobe\Test2\prog
Status: Missing M1.arm file
Checking Module M0
Imports:
M1
Folder: C:\Astrobe\Test2\lib
Status: Missing M0.arm file
Checking Module P
Imports:
Main
M0
M1
Folder: C:\Astrobe\Test2
Status: Missing P.arm file
------------------
Builder Phase 2: Compiling missing / outdated modules...
compiling Main
new symbol file; code generated = 8 bytes, data = 0 bytes, entries = 0, lines = 2, msecs = 2
------------------
compiling M1
new symbol file; code generated = 8 bytes, data = 0 bytes, entries = 0, lines = 3, msecs = 3
------------------
compiling M0
Line Col
3 4 Warning: M1 is not used
new symbol file; code generated = 8 bytes, data = 0 bytes, entries = 0, lines = 3, msecs = 2
------------------
compiling P
Line Col
6 4 Warning: M0 is not used
new symbol file; code generated = 20 bytes, data = 4 bytes, entries = 0, lines = 6, msecs = 15
------------------
4 modules compiled, lines = 14, msecs = 22
------------------
Builder Phase 3: Linking all modules...
linking Main 8 bytes
linking M1 8 bytes
linking M0 8 bytes
linking P 20 bytes
Stack: 2002FFF8H, Entry: 1000036DH
Created P.uf2
Max Extension Level: 4
Total Code Size: 620 bytes
Total Resource Size: 216 bytes
Total ROM Used: 836 bytes
Total Data Size: 4 bytes
Configuration: RP2350 test
Configuration ID: 0
Data Range: 20000000H 20030000H
Code Range: 10000100H 10200000H
Heap Start: 20000200H
Heap Limit: 00000000H
Linking completed
4) As I understand, the build system
a) performs separate compilations for all modules,
b) looking for imports first in the directory of each module being compiled, then following the library search path,
c) performing the separate compilations in the correct order so that each module being compiled finds all its imports already compiled.
If that is true, the above successful build should not be possible. I believe it points to a flaw in the build system. Namely, for compiling M0.mod, M1.mod in 'lib' should have been recognised as correct import and compiled. Then the linker would point out the module version clash between M1.mod in 'prog' as imported by P.mod, and M1.mod in 'lib' as imported by M0.mod. In the test case, M1.mod in 'lib' is not detected by the build system.
5) If we simulate the relevant part of the (IMO) correct build process, and directly first compile M1.mod in 'lib' and then M0.mod, and then build P.mod we get the expected module version error message.
This is an admittedly convoluted test case, but then again, good test cases often are. :)
***
Regarding not allowing several modules with the same name in the same search path (including the implicit current module directories): please do
not change the current concept! While each compiled and linked program must only contain one module with a specific name, the search path can allow for more -- as long as only one is picked in the build process (static vs. dynamic set of modules).
In fact, allowing this set-up is a feature, not a defect. All library modules that are not imported by any other library module can be easily replaced by a program-specific one. The main example is -- no pun intended -- module Main.mod. I place my Main.mod in the program directory, and voila, my module takes precedence, without any need to remove it from the library. Maybe I need a different clock frequency, or a different UART baudrate, or additional initialisations. I use this feature for quite a few example programs. In Oberon RTK there are also other modules of equivalent nature as Main.mod. We can selectively be "unwise". :)
The above counter test example notwithstanding, Astrobe provides suffient protection against "double" modules already.