[clean-list] htoclean sorrows
Matthew Bromberg
mattcbro at earthlink.net
Tue May 30 19:16:30 MEST 2006
I got things to link and to work correctly using the little C program
that you kindly provided that uses microsofts linker. I made some minor
adjustments to it, in particular the /NODEFAULTLIB:libc option was added
and I forced it to actually print out the linker command to a logfile
for debugging purposes. The final step to success was to include a
static link library for the dll as an external object file. Including
it as a static library in Projects options does not appear to add any
library names to the link caller, thus forcing me to use this hack.
Have you gotten the 64 bit version to work? (not that I need this
trouble just yet.)
I think the old linker still has some issues though. It does not like
my .dll, whether or not I use the P prefix.
Regards,
P.S. Here is the modified source file
/* call_ms_linker.c : */
#include <windows.h>
#include <stdio.h>
struct line {
struct line *next;
char chars[0];
};
static char *string_copy (char *d,char *s)
{
char c;
while (c=*s++,c!='\0')
*d++=c;
*d=c;
return d;
}
int skip_to_next_line (int c,FILE *input_file)
{
while (c!='\n' && c!='\r' && c!=EOF)
c=getc (input_file);
if (c!=EOF)
c=getc (input_file);
return c;
}
void main (int argc,char *argv[])
{
char *command_line,*command_line_p,*command_line_begin;
char *input_file_name,*output_file_name;
FILE *input_file,*error_file;
static char application_name[257];
int application_name_i;
struct line *first_line,**next_line_p;
int n,c,n_lines,n_chars_in_lines,n_arg_chars;
input_file_name=NULL;
output_file_name=NULL;
if (argc>=5){
if (!strcmp (argv[argc-4],"-I"))
input_file_name=argv[argc-3];
else if (!strcmp (argv[argc-2],"-I"))
input_file_name=argv[argc-1];
if (!strcmp (argv[argc-4],"-O"))
output_file_name=argv[argc-3];
else if (!strcmp (argv[argc-2],"-O"))
output_file_name=argv[argc-1];
}
if (input_file_name==NULL)
printf ("-I input_file_name missing\n");
if (output_file_name==NULL)
printf ("-I output_file_name missing\n");
if (input_file_name==NULL || output_file_name==NULL)
return;
{
int arg_i;
n_arg_chars=0;
for (arg_i=1; arg_i<argc-4; ++arg_i)
n_arg_chars+=strlen (argv[arg_i]);
}
input_file=fopen (input_file_name,"r");
if (input_file==NULL){
printf ("Couldn't open %s\n",input_file_name);
return;
}
error_file=fopen (output_file_name,"w");
if (input_file==NULL){
printf ("Couldn't create %s\n",output_file_name);
return;
}
n_lines=0;
n_chars_in_lines=0;
next_line_p=&first_line;
c=getc (input_file);
while (c!=EOF){
int i;
i=0;
while (c=="ExePath:"[i] && c!='\0'){
c=getc (input_file);
++i;
}
if (i==sizeof ("ExePath:")-1){
c=getc (input_file);
break;
}
c=skip_to_next_line (c,input_file);
}
if (c==EOF){
fprintf (error_file,"ExePath: not found in input file\n");
fclose (error_file);
return;
}
application_name_i=0;
while (c!='\n' && c!='\r' && c!=EOF){
if (application_name_i==256){
fprintf (error_file,"application name too long");
fclose (error_file);
return;
}
application_name[application_name_i++]=c;
c=getc (input_file);
}
application_name[application_name_i]='\0';
while (c!=EOF){
int i;
i=0;
while (c=="ObjectPaths"[i] && c!='\0'){
c=getc (input_file);
++i;
}
if (i==sizeof ("ObjectPaths")-1){
c=getc (input_file);
break;
}
c=skip_to_next_line (c,input_file);
}
while (c!=EOF){
static char line[257];
int i,line_i;
i=0;
while (c=="\tPath:\t"[i] && c!='\0'){
c=getc (input_file);
++i;
}
if (i!=sizeof ("\tPath:\t")-1)
break;
line_i=0;
while (c!='\n' && c!='\r' && c!=EOF){
if (line_i==256){
fprintf (error_file,"file name too long");
fclose (error_file);
return;
}
line[line_i++]=c;
c=getc (input_file);
}
line[line_i]='\0';
if (line_i>0){
struct line *next_line;
next_line=malloc (sizeof (struct line)+line_i+1);
if (next_line==NULL){
fprintf (error_file,"not enough memory");
fclose (error_file);
return;
}
strcpy (next_line->chars,line);
++n_lines;
n_chars_in_lines+=line_i;
*next_line_p=next_line;
next_line_p=&next_line->next;
}
if (c!=EOF){
c=getc (input_file);
}
}
*next_line_p=NULL;
fclose (input_file);
#if 1
command_line_begin = "link.exe /nologo /release
/entry:mainCRTStartup /subsystem:console"
" /NODEFAULTLIB:libc"
" kernel32.lib";
#else
command_line_begin = "link.exe /nologo /release /debug /machine:AMD64";
#endif
command_line=malloc (strlen
(command_line_begin)+8+n_arg_chars+(argc-5)+application_name_i+2+n_lines*3+n_chars_in_lines+1);
command_line_p=command_line;
command_line_p=string_copy (command_line_p,command_line_begin);
{
int arg_i;
for (arg_i=1; arg_i<argc-4; ++arg_i){
*command_line_p++=' ';
command_line_p=string_copy (command_line_p,argv[arg_i]);
}
}
command_line_p=string_copy (command_line_p," \"/out:");
command_line_p=string_copy (command_line_p,application_name);
*command_line_p++='\"';
*command_line_p++=' ';
{
struct line *line_p;
FILE *fd ;
char *logfile = "linklog.txt" ;
fd = fopen(logfile, "w") ;
for (line_p=first_line; line_p!=NULL; line_p=line_p->next){
*command_line_p++=' ';
*command_line_p++='\"';
command_line_p=string_copy (command_line_p,line_p->chars);
*command_line_p++='\"';
}
*command_line_p='\0';
fprintf(fd, command_line) ;
fprintf(fd, "\n") ;
fclose(fd) ;
}
fclose (error_file);
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
ZeroMemory (&si,sizeof(si));
si.cb = sizeof(si);
si.hStdOutput =
CreateFile
(output_file_name,GENERIC_WRITE,0,&sa,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
si.hStdInput=GetStdHandle (STD_INPUT_HANDLE);
si.hStdError=GetStdHandle (STD_ERROR_HANDLE);
if (si.hStdOutput==INVALID_HANDLE_VALUE)
si.hStdOutput=GetStdHandle (STD_OUTPUT_HANDLE);
si.dwFlags=STARTF_USESTDHANDLES;
ZeroMemory (&pi,sizeof(pi));
if (! CreateProcess
(NULL,command_line,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
{
fprintf (error_file,"CreateProcess failed\n");
fclose (error_file);
return;
}
WaitForSingleObject (pi.hProcess,INFINITE);
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
}
}
John van Groningen wrote:
> Matthew Bromberg wrote:
>
>> Sigh,
>> I attempted this technique with no success. I got the C code to compile (after it introduced some bugs in the cut and paste process!).
>> I replaced the StaticLinker.exe file with the new executable. I then created a .bat file that called vcvars32.bat and then the clean IDE.
>>
>> When I compiled my little toy example I got the following errors:
>> LIBC.lib(crt0.obj) : error LNK2005: _mainCRTStartup already defined in _startup0.o
>> matrix.o : error LNK2001: unresolved external symbol _cblas_daxpy
>> LIBC.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function _mainCRTStartup
>>
>
> The linker is trying to link against the C library. You probably don't
> want to do this, try passing /NODEFAULTLIB to the linker to prevent this.
> Or if you want to link against the C library, remove _startup0.0 from
> the list of object files, and add a main function in c with a call
> to clean_main().
>
>
>> I also tried this using an MS VC static link library that provides a ccall stub into the DLL. Same results. I wonder if the inability to link against
>> the library isn't a path issue? As far as the startup*.o symbol issues I have no idea. I'm using the Microsoft Visual C++ 2003 Toolkit., which can be
>> a little weird whenever certain libraries such as debug libraries are linked in. I also tried collecting all the relevant .o libraries that you mentioned into a
>> single file and tried to link them directly using link.exe. However they don't seem to be in the right format. (Is it supposed to be COFF?) I get this error:
>>
>> ....\Clean System Files>link /out:matrix.exe _startup.o _startup1.o _startup2.o _system.o matrix.o atlas.lib
>> Microsoft (R) Incremental Linker Version 7.10.3077
>> Copyright (C) Microsoft Corporation. All rights reserved.
>>
>> _startup.o : fatal error LNK1136: invalid or corrupt file
>>
>
> The _startup.o file is not used on windows, use _startup0.o, _startup1.o
> and _startup2.o instead. If there is a _startup.o file in the windows
> version of Clean it is probably not a windows COFF object file.
>
>
>> Should I try this with MS VC++ 6.0?
>>
>
> Maybe, with the linker from VC 6.0 I can link a Clean program.
>
> Kind regards,
>
> John van Groningen
>
>
More information about the clean-list
mailing list