News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How to build a library

Started by jj2007, July 10, 2008, 08:48:02 AM

Previous topic - Next topic

jj2007

Is there any "hands on" tutorial (for newbies without C background) showing how to build a library from own functions, preferably with polib/polink?

I have tried my luck, the library works but it bloats the exe, i.e. it includes all procs in each exe even if they are not needed.

My source is a single file with plenty of macros, procedures and partially shared variables in the .data? and .data sections. So one question is how the linker knows when to use/include a variable into the exe. The EXPORTS list in *.def takes variable names, but it doesn't work because the exe finds a fake proc address rather than a variable...

I am aware of the xp libraries for masm32 post but didn't manage to translate it in an own working example.

It would be great to have a working example - \masm32\examples\exampl07\hlldemo\smalled\lib\tstlib looks like a start but it does not really tell me anything.

hutch--

JJ,

The basics are ALWAYS put a single procedure into a single module unless you can garrantee they must be used together. This way you avoid the granularity problem and only ever get the code you need. Have a look at the method of how the masm32 lbrary is constructed, you never get more than you need.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: hutch-- on July 10, 2008, 09:06:03 AM
JJ,

The basics are ALWAYS put a single procedure into a single module unless you can garrantee they must be used together. This way you avoid the granularity problem and only ever get the code you need. Have a look at the method of how the masm32 lbrary is constructed, you never get more than you need.

Desperately trying to read your thoughts ma non ci riesco. Mi sono spiegato tanto male? "Hands on" non si capisce in OZ?

jj2007

OK, knowing that you are basically a nice person, and should feel some empathy for people who don't come from C, here is an another attempt:

\masm32\bin\ml /c /coff @ml.rsp

The rsp contains the names of all asm modules. Is that the mechanism telling ml+link that these are distinct modules? (I assume with "modules" you mean asm sources)

\masm32\bin\link -lib *.obj /out:masm32.lib

So that links the whole stuff together. But what about common variables?
masm32.inc has plenty of PROTOS but only one variable declaration:
RUN_SYNCH_PROCESS_EX STRUC
Does it imply that RUN_SYNCH_PROCESS_EX is in all my executables regardless of whether I need it or not, or does the linker know when to use it and when not to use it?

For example, I have...
LastPathBuf   dd MAX_PATH/4 dup (?)   ; remember last file name
... a global string needed in quite a number of procedures, e.g.
MyFileOpen
MyFileRead
MyFileWrite
MyFileShowName
... etc.; I don't want to put all 4 into one module, so how can I keep the procs distinct while keeping a common pool of initialised or uninitialised variables?

japheth


Hi,

> So that links the whole stuff together. But what about common variables?
> masm32.inc has plenty of PROTOS but only one variable declaration:
> RUN_SYNCH_PROCESS_EX STRUC
> Does it imply that RUN_SYNCH_PROCESS_EX is in all my executables regardless of whether I need it or not, or
> does the linker know when to use it and when not to use it?

You should make yourself familiar with the difference between a variable and a structure definition: the first defines something which HAS a type, the latter defines something which IS a type. That's a tiny, but still important difference  :toothy.

jj2007

#5
Danke, as usual, you are incredibly helpful, dear German colleague!

Attached a sample lib (EDIT: Obsolete - see later post below).
Run makeMyLib.bat, then assemble TestLib.asm

Everything works surprisingly fine, except this bit:

   invoke ShowBoxA, addr MyTxt
   ; mov eax, SharedVar
   ; chokes with error A2006: undefined symbol : SharedVar
   invoke ShowBoxB, addr MyTxt

So how one use a shared set of variables? Put it into the include file?? I have seen confused uses and explanations of PUBLIC, EXTERN, EXTERNDEF in various places...

[attachment deleted by admin]

japheth

> So how one use a shared set of variables? Put it into the include file?? I have seen confused uses and explanations
> of PUBLIC, EXTERN, EXTERNDEF in various places...

This is pretty well described in the Masm docs. For example, see

http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_08.htm

As a general rule - with minor exceptions - avoid the older PUBLIC and EXTERN directives and use PROTO and EXTERNDEF [and COMM, if needed] only.

hutch--

JJ,

In the masm32 library I have used PUBLIC for things like a table that is remote from the procedure that uses it.


    PUBLIC bintable

    .data
      align 16
      bintable \ etc ....


and for the calling module,


    EXTERNDEF bintable:DWORD


PUBLIC makes the data "visible" to external modules, EXTERNDEF tells the calling module that the item is defined elsewhere.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Attached a complete example how to build a library in Masm.

QuoteJapheth: avoid the older PUBLIC and EXTERN directives and use PROTO and EXTERNDEF

I used EXTERNDEF, which is case-insensitive; however, to facilitate the understanding,
I have put it in all UPPERCASE where a common variable is being created and EXported,
and mixed case (ExternDef) where the variable is being used and IMported.

The package contains the following files:

TestMyLib.asm   = what it says :bg
makeMyLib.bat   = batch file that builds the library from its components/modules
LibModA.asm   = first module, contains the ShowBoxA procedure
LibModB.asm   = second module, contains the ShowBoxB procedure
LibModC.asm   = third module, contains the ShowBoxC procedure
MyLib.inc   = include file, contains info for the linker as shown below

Included but not needed because you should create them yourself:

mylib.lib   = the library itself, as built by makeMyLib.bat
TestMyLib.exe   = the executable created with TestMyLib.asm.

[attachment deleted by admin]

sinsi

You can replace the lines
Quote
dir /b libm*.asm > ml.rsp          : create a response file for ML.EXE
\masm32\bin\ml /c /coff @ml.rsp
with 1 line
Quote
\masm32\bin\ml /c /coff libm*.asm
[nitpick]It would be nice to delete the ml.rsp file as well.[/nitpick]

I tend to use one inc file with all external vars/procs and include it in each asm file that references anything external, but I'm not sure if this increases the size of a lib.
Light travels faster than sound, that's why some people seem bright until you hear them.

RuiLoureiro

Hi all,
         Here is my example where i use include files .glb to declare external variables and procedures


[attachment deleted by admin]

jj2007

Quote from: sinsi on July 11, 2008, 10:40:40 AM
You can replace the lines

dir /b libm*.asm > ml.rsp          : create a response file for ML.EXE
\masm32\bin\ml /c /coff @ml.rsp

with 1 line

\masm32\bin\ml /c /coff libm*.asm

Thanks, absolutely correct.
Quote
[nitpick]It would be nice to delete the ml.rsp file as well.[/nitpick]
I kept that one deliberately, so that newbies can view it.
Quote
I tend to use one inc file with all external vars/procs and include it in each asm file that references anything external, but I'm not sure if this increases the size of a lib.

jj2007

\masm32\bin\link -lib *.obj /out:mylib.lib
if errorlevel 0 echo FANTASTIC, YOU GOT IT
if exist mylib.lib goto oklink

The library I am building has plenty of fatal errors, but I see the FANTASTIC. And the bloody linker builds a non-working mylib.lib, so the exist switch also works in the wrong direction... what's wrong with link and/or the errorlevel?

jdoe


jj2007,

Look at the batch below. This is how I build my library.



@ECHO OFF


SET BINPATH=\AZIMUT\BIN

COPY /Y AZMT32.INC \AZIMUT\INC32\AZMT32.INC
CALL :DEL_TEMP


FOR %%A IN (*.asm) DO (
    %BINPATH%\ML.EXE /c /coff /nologo %%~nxA
    IF ERRORLEVEL 1 GOTO ERROR & IF NOT EXIST %%~nA.obj GOTO ERROR
)

%BINPATH%\LINK.EXE -lib /NOLOGO /OUT:AZMT32.LIB *.obj
IF ERRORLEVEL 1 GOTO ERROR & IF NOT EXIST AZMT32.LIB GOTO ERROR


COPY /Y AZMT32.LIB \AZIMUT\LIB32\AZMT32.LIB
CALL :DEL_TEMP
EXIT


:ERROR
CALL :DEL_TEMP
PAUSE
EXIT


:DEL_TEMP
IF EXIST *.lib DEL *.lib
IF EXIST *.obj DEL *.obj



jj2007

Quote from: jdoe on July 11, 2008, 08:57:30 PM

Look at the batch below. This is how I build my library.


Interesting. Batch files have an awful lot of not-so-well-understood options - thanks for teaching me some new ones  :U
I am currently working on a way to put the whole library in one fat source, and then press a button to build and test it. It works already but it's still in a beta state.