News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Problem with GoLink and import library LIB files

Started by Ben321, October 03, 2015, 07:27:59 PM

Previous topic - Next topic

Ben321

I noticed it says in the manual that "GoLink does not need LIB (library) files" but I'm finding that not only does it not need them, it refuses to use them even when explicitly specified in the command line. This may be fine if you are using just one or 2 DLL files, but what if you are (like me) trying to use multiple DLL files, and there's one nice import library file that imports all the functions from all the DLLs? Then the lack of ability to use any import libraries at all becomes a major inconvenience. You see, I'm using an import library file called WIN32.LIB which is supposed to make available all the functions in the various Windows API DLL files, so that I don't need to manually type in each separate DLL file that's part of the Windows API (such as gdi32.dll, kernel32.dll, user32.dll, etc) into the command line for the linker. This is supposed to make it much easier to use the Windows API if you are using functions from multiple Windows API DLL files (so you don't have to specify each one). Unfortunately I'm finding that GoLink.exe is refusing to use any import libraries, meaning that WIN32.LIB is 100% useless, until this bug is fixed. Can you please correct this bug in your next version of GoLink? Thanks in advance.

Yuri

These libraries are used by GoAsm, not GoLink. Therefore their usage is described in the GoAsm help. See "Merging: using static code libraries" there.

wjr

There are 2 types of LIB files. As Yuri mentioned, for static library files, these are supplied to GoAsm (instead of GoLink). As for LIB files in support of dynamic libraries, GoLink does not use these, and I do not foresee this changing.

If you are using donkey's header files, you can define the symbol LINKFILES in your source before the include(s), and this will (see GoAsm #DYNAMICLINKFILE) add the various required Windows API DLL names to a .drectve section in the OBJ file which GoLink uses for further import processing.

Ben321

Quote from: wjr on October 04, 2015, 03:56:56 AM
There are 2 types of LIB files. As Yuri mentioned, for static library files, these are supplied to GoAsm (instead of GoLink). As for LIB files in support of dynamic libraries, GoLink does not use these, and I do not foresee this changing.

If you are using donkey's header files, you can define the symbol LINKFILES in your source before the include(s), and this will (see GoAsm #DYNAMICLINKFILE) add the various required Windows API DLL names to a .drectve section in the OBJ file which GoLink uses for further import processing.

Well I need a way to bulk-include all of the Windows API DLLs. And I'm using NASM as the assembler, with GoLink as the linker. I prefer the way NASM does things as an assembler over the way GoAsm does things. So I'm not going to switch to GoAsm. So any special perks I could get out of using GoAsm with GoLink are not going to be available to me. That's why I was hoping to get support added for LIB files in GoLink.

wjr

The Win32.lib files that I just looked at would appear to be using an older file format (OMF?), so again, I don't see a change to GoLink for this.

My suggestion in this case would be to use a command file on the GoLink command line, for example @Win32.txt where Win32.txt is a text file listing just the DLL file names. If you list the common ones first (ex. Kernel32.dll User32.dll Gdi32.dll COMCTL32.dll comdlg32.dll ...) then GoLink will build quicker. A bit of work to get this file set-up, but once done it could be used as above with GoLink, with the end result similar to what you were trying to do with Win32.lib (the text file will be much smaller).

Ben321

So how would I format that text file? Can you paste a sample on here? And how do I tell GoLink to look at the text file?


Another related question I have, is how do I use static-library files (for embedding certain functionality in an EXE file without DLL dependencies)? You say GoAsm takes static LIB files, and GoLink doesn't. GoLink expects the assembler to import any LIB files. Yet at the same time, NASM is not capable of taking static LIB files as input. NASM expects the linker to import LIB files. So using NASM + GoLink, I don't see any way of using static LIB files at all. Is there some workaround for this?


wjr

Formatting would be one or more DLL names per line, with comments possible after a semi-colon as follows:


;GoLink command file for Win32 DLL imports

Kernel32.dll ;list common DLLs first
User32.dll
Gdi32.dll

COMCTL32.dll comdlg32.dll

OLEAUT32.dll
Hhctrl.ocx
winspool.drv
shell32.dll


Usage of one or more command files would be like:


GoLink MyFile.obj @Win32.txt


Correct, no direct static LIB usage with NASM + GoLink. A static LIB file is a collection of one or more OBJ files. There could be some workaround potential using LIB.EXE to extract an OBJ library member:


LIB library /EXTRACT:member /OUT:objectfile


and then using the OBJ file(s) with GoLink.

dedndave

if it's an older 16-bit static library, you will need a compatible LIB.EXE program

http://dedndave.x10.mx/files/Lib16.zip

Arguments are passed to lib via:

    the command line
    a response file (similar to the linker response file)
    interactively from the command prompt

lib commands have the following format:

lib lib-file [switches][action-files],[list-file][;]

lib-file is the name of the library file to create or change. Its default file extension is .lib.

The switches are:
Switches Switch Description
/?, /H Print help information
/B Run lib in batch mode
/C Create a new library lib-file if one does not exist. Use to create a new library without being prompted to do so
/I Ignore case in public symbols (default)
/N Do not back up the original library. The default behavior is to save a backup of the original library file with the extension .bak
/NOE lib ignores this switch
/NOI Treat uppercase and lowercase letters as distinct, and mark the library as case-sensitive. This applies only to public symbols. The default is /I
/NOL Do not display copyright message
/P:num Set page size to num (a power of 2)

The action-files specify the objects on which to act and what to do with them. The action-files must be one or more object files in the current directory. The default extension for object files is .obj. When lib puts an object file into a library, it gives the object's module the name of the object file in uppercase and without an extension.

To specify what to do with each object file, put one of the following switches before the name(s) of the action-files:
Switches Switch Description
- Removes the object from the library
+ Adds the object to the library If the library already contains an object of the same name, lib prints an error message and doesn't add the object
* Copies the object into a separate object file, leaving the object in the library
+-, -+ Replaces an existing object in the library with a new version
*-, -* Extracts the object module into an object file and deletes it from the library

The list-file produces a file listing the contents of the library. The file first lists all the public symbols in alphabetical order with the name of the modules to which they belong. Next, it lists the modules alphabetically with the public symbols in them. The default list-file extension is .lst. If there is a list-file but no action-files, lib produces a list file without modifying the library.
Concatenating libraries

To concatenate two libraries, specify one as the lib-file and the other as an action-file. lib adds the modules from the action-file library to the other library without changing the names of the modules.

Note: lib doesn't allow two modules to contain the same public symbol.
Using lib interactively

If lib is run with no arguments, it prompts for the required arguments. Use the ampersand (&) character to continue input on a new line.
Response files

You can use lib with a response file, which contains the responses that the compiler would ask for if used interactively. For example, the response file below adds several objects to the library mywindow.lib and produces a listing file:

\dm\lib\mywindow.lib /c
+winopen+winblank+winmove+winhide&
+winshow+winputs+wingets+winprint
\dm\mywin.lst;

If the response file is makewin.rsp, use lib like this:

lib @makewin.rsp

Don't use filenames beginning with @ because lib mistakes it for a response file.

Ben321

Quote from: wjr on October 04, 2015, 10:44:55 AM
Formatting would be one or more DLL names per line, with comments possible after a semi-colon as follows:


;GoLink command file for Win32 DLL imports

Kernel32.dll ;list common DLLs first
User32.dll
Gdi32.dll

COMCTL32.dll comdlg32.dll

OLEAUT32.dll
Hhctrl.ocx
winspool.drv
shell32.dll


Usage of one or more command files would be like:


GoLink MyFile.obj @Win32.txt


Correct, no direct static LIB usage with NASM + GoLink. A static LIB file is a collection of one or more OBJ files. There could be some workaround potential using LIB.EXE to extract an OBJ library member:


LIB library /EXTRACT:member /OUT:objectfile


and then using the OBJ file(s) with GoLink.

Ok, thanks.

What about a LIB file where its source originally compiled into a huge number of OBJ files (like a complex program written in C++)? If I then split the LIB file, it will then be once again a huge number of separate OBJ files, which is very inconvenient. There should really be a feature in GoLink, to take a static LIB file as input, for those who are using NASM as the assembler, so that if they need to use a static LIB file for some of the functions in their program, they won't have to do something like having a bunch of extra OBJ files sitting around cluttering things up in their project folder.

I get that with GoLink, you are trying to move away from requiring LIB files, but at the same time refusing to let GoLink even use LIB files can be quite inconvenient in some situations. So refusing to let GoLink import static LIB files can actually create additional problems for programmers like me.

wjr

Yes, the workaround potential does get less promising in that case.

Another workaround would be a NASM + GoAsm + GoLink solution, using GoAsm to convert the LIB to an OBJ for use with GoLink. The GoAsm source would look like:


CODE
jmp Static.lib:Function1
jmp Static.lib:Function2
jmp Static.lib:Function3
        ;
        ;


...where the functions listed are those that you need to use from the Static LIB. You wouldn't actually use this jump table, but building this with GoAsm would include those functions in the OBJ which would then, when passed to GoLink, make them available for use with your NASM source.

Ben321

Quote from: wjr on October 04, 2015, 03:51:09 PM
Yes, the workaround potential does get less promising in that case.

Another workaround would be a NASM + GoAsm + GoLink solution, using GoAsm to convert the LIB to an OBJ for use with GoLink. The GoAsm source would look like:


CODE
jmp Static.lib:Function1
jmp Static.lib:Function2
jmp Static.lib:Function3
        ;
        ;


...where the functions listed are those that you need to use from the Static LIB. You wouldn't actually use this jump table, but building this with GoAsm would include those functions in the OBJ which would then, when passed to GoLink, make them available for use with your NASM source.

This still overcomplicates the issue. The simplest solution would be to add static LIB functionality to GoLink, with the express idea that this functionality would be used when GoLink was the linker being used with NASM, and could be ignored and left unused when using GoLink with GoAsm. Do you have access to the sourcecode for GoLink? If so, could you add this functionality to a separate (not main) branch of the development "tree" of the software? Then maybe you could post the download link for a compiled copy of this GoLink mod here in this forum. I am using both NASM and GoLink as components in my own project, which is to create a GUI for NASM. I've been trying a number of linkers for my project, to link the files output by NASM and GoLink seems to be the most promising of the ones I've tried, but it is lacking the functionality of supporting LIB files for input, which is a major defect from my point of view. I liked ALink because of this, but ALink had another problem. ALink requires import LIB files to be used with DLL files, so if you have a DLL file that was not shipped with a LIB file, ALink can't use it. GoLink can use it, but GoLink can't use LIB files. What if I need to compile a program that uses a static LIB file for some code, and a DLL file for another piece of code, but that DLL file didn't come with an import LIB file?  Which linker do I use then? Neither linker will work entirely, because some of the required functionality is found in one of the linkers, but the rest of the functionality is in the other linker. To use an old expression, that's called "being up a creek without a paddle". In other words, there appears to be no solution to my problem. That's why I'm asking you to create a solution to my problem, by adding static LIB functionality to GoLink (even if only as a mod, and not the main fork of the development of GoLink).

wjr

You can certainly ask, however, LIB files were not part of GoLink's development which made some of the coding easier with the resulting program flow not really open to your proposed solution as just an "add" on the "simplest" side. Sorry, most likely not going to happen, and even if so, not soon with my current focus mainly on GoAsm.

Although not as smooth sailing, you have several paddles with mixed solution potential...