GNU make builtin rules produce linker error due to command line arguments order

2010-04-06 Thread Robrecht Dewaele

Hello everyone,

I'm not sure whether this is a make or a cygwin issue, but it has 
occured to me only on cygwin, so I thought to ask here first.
To illustrate my problem, I have written a little testcase (options.c) 
which uses libpopt and illustrate how to reproduce the behaviour at the 
bottom of this message.


I think the basic issue here is that the linker only resolves symbols in 
files in the order as they appear on the command line.
This is afaik not an erroneous behaviour, but it doesn't play well with 
the builtin make rules as shown below.


This test was run using a fresh cygwin install from today, on a windows 
XP host.

The account I'm using is an administrator account.

# Version of the make and cc programs.
$ cc --version = cc (GCC) 4.3.4 20090804 (release) 1
$ make --version = GNU Make 3.81

# Only the C source file is present, and it uses libpopt.
$ ls
options.c

# Using builtin make rules and LDFLAGS seems to yield an incorrect 
order of arguments for cc.

$ LDFLAGS=-lpopt make options
cc   -lpopt  options.c   -o options
/tmp/ccW0jXSk.o:options.c:(.text+0x3e): undefined reference to 
`_poptGetContext'
/tmp/ccW0jXSk.o:options.c:(.text+0x56): undefined reference to 
`_poptGetNextOpt'
/tmp/ccW0jXSk.o:options.c:(.text+0x78): undefined reference to 
`_poptBadOption'
/tmp/ccW0jXSk.o:options.c:(.text+0x85): undefined reference to 
`_poptStrerror'
/tmp/ccW0jXSk.o:options.c:(.text+0xb8): undefined reference to 
`_poptPrintHelp'
/tmp/ccW0jXSk.o:options.c:(.text+0xfa): undefined reference to 
`_poptFreeContext'
/tmp/ccW0jXSk.o:options.c:(.data+0x68): undefined reference to 
`_poptHelpOptions'

collect2: ld returned 1 exit status
make: *** [options] Error 1

# When '-lpopt' is positioned after the source file, no linker 
errors appear.

$ cc options.c -lpopt -o options
(no output)

# And a working executable is produced.
$ ./options.exe -t
test option set!

Kind regards,
Robrecht
#include stdio.h
#include popt.h
#include stdbool.h

static bool testSet = false;

static struct poptOption subOptionsTable[] = {
	{ test, 't', POPT_ARG_NONE, testSet, 0, do a test, NULL },
	POPT_TABLEEND
};

static struct poptOption mainOptionsTable[] = {
	{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, sub1, NULL },
	POPT_AUTOHELP POPT_TABLEEND
};

int main(int argc, const char * argv[]) {
	int ret;
	poptContext optCon = poptGetContext(NULL, argc, argv, mainOptionsTable, 0);
	mainOptionsTable[0].arg = subOptionsTable;
	while ((ret = poptGetNextOpt(optCon))  0);
	if (ret  -1) {
		printf(\n%s: %s\n\n, poptStrerror(ret), poptBadOption(optCon, 0));
		poptPrintHelp(optCon, stdout, 0);
		return -1;
	}
	printf(test option%sset!, testSet ?   :  not );
	optCon = poptFreeContext(optCon);
	return 0;
}

Cygwin Configuration Diagnostics
Current System Time: Tue Apr 06 22:21:43 2010

Windows XP Professional Ver 5.1 Build 2600 Service Pack 3

Path:   C:\cygwin\usr\local\bin
C:\cygwin\bin
C:\cygwin\bin
C:\WINDOWS\system32
C:\WINDOWS
C:\WINDOWS\System32\Wbem

Output from C:\cygwin\bin\id.exe
UID: 1003(robbe)GID: 513(None)
513(None)   0(root) 544(Administrators) 545(Users)

SysDir: C:\WINDOWS\system32
WinDir: C:\WINDOWS

USER = 'robbe'
PWD = '/home/robbe'
HOME = '/home/robbe'

HOMEPATH = '\Documents and Settings\robbe'
MANPATH = '/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man'
APPDATA = 'C:\Documents and Settings\robbe\Application Data'
HOSTNAME = 'lemming'
TERM = 'cygwin'
PROCESSOR_IDENTIFIER = 'x86 Family 6 Model 15 Stepping 6, GenuineIntel'
WINDIR = 'C:\WINDOWS'
OLDPWD = '/usr/bin'
USERDOMAIN = 'LEMMING'
OS = 'Windows_NT'
ALLUSERSPROFILE = 'C:\Documents and Settings\All Users'
!:: = '::\'
VS90COMNTOOLS = 'C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\'
COMMONPROGRAMFILES = 'C:\Program Files\Common Files'
USERNAME = 'robbe'
PROCESSOR_LEVEL = '6'
FP_NO_HOST_CHECK = 'NO'
SYSTEMDRIVE = 'C:'
LANG = 'C.UTF-8'
USERPROFILE = 'C:\Documents and Settings\robbe'
CLIENTNAME = 'Console'
PS1 = '\[\e]0;\w\a\]\n\[\e[32m\...@\h \[\e[33m\]\w\[\e[0m\]\n\$ '
LOGONSERVER = '\\LEMMING'
PROCESSOR_ARCHITECTURE = 'x86'
!C: = 'C:\cygwin\bin'
SHLVL = '1'
PATHEXT = '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH'
HOMEDRIVE = 'C:'
PROMPT = '$P$G'
COMSPEC = 'C:\WINDOWS\system32\cmd.exe'
SYSTEMROOT = 'C:\WINDOWS'
PRINTER = 'Microsoft XPS Document Writer'
CVS_RSH = '/bin/ssh'
PROCESSOR_REVISION = '0f06'
INFOPATH = '/usr/local/info:/usr/share/info:/usr/info:'
PROGRAMFILES = 'C:\Program Files'
NUMBER_OF_PROCESSORS = '1'
SESSIONNAME = 'Console'
COMPUTERNAME = 'LEMMING'
_ = '/usr/bin/cygcheck'

HKEY_CURRENT_USER\Software\Cygwin
HKEY_CURRENT_USER\Software\Cygwin\Program Options
HKEY_CURRENT_USER\Software\Cygwin\setup
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Start
 Menu2\Programs\Cygwin
  (default) = (unsupported type)
HKEY_LOCAL_MACHINE\SOFTWARE\Cygwin
HKEY_LOCAL_MACHINE\SOFTWARE\Cygwin\Installations
  (default) = '\??\C:\cygwin'

Re: GNU make builtin rules produce linker error due to command line arguments order

2010-04-06 Thread Dave Korn
On 07/04/2010 00:24, Robrecht Dewaele wrote:

 $ LDFLAGS=-lpopt make options

  Only put flags in LDFLAGS.  Put libs in LDLIBS.  The default rule is

 %: %.c
 #  commands to execute (built-in):
   $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

and LINK.c embeds LDFLAGS.  On ELF platforms where command-line order of
linker inputs doesn't matter so much, it'll often work to put -l options in
LDFLAGS, but it's not portable to PE platforms like Windows/Cygwin where the
libraries have to come last on the command-line.

cheers,
  DaveK


--
Problem reports:   http://cygwin.com/problems.html
FAQ:   http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple



Re: GNU make builtin rules produce linker error due to command line arguments order

2010-04-06 Thread Greg Chicares
On 2010-04-06 23:24Z, Robrecht Dewaele wrote:
 
 # Using builtin make rules and LDFLAGS seems to yield an incorrect 
 order of arguments for cc.
 $ LDFLAGS=-lpopt make options

http://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules
| The precise command used is `$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)'.

so use
  LDLIBS=-lpopt make options
instead.

--
Problem reports:   http://cygwin.com/problems.html
FAQ:   http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple



Re: GNU make builtin rules produce linker error due to command line arguments order

2010-04-06 Thread Robrecht Dewaele

Dave Korn wrote:

On 07/04/2010 00:24, Robrecht Dewaele wrote:

  

$ LDFLAGS=-lpopt make options



  Only put flags in LDFLAGS.  Put libs in LDLIBS.  The default rule is

  

%: %.c
#  commands to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@



and LINK.c embeds LDFLAGS.  On ELF platforms where command-line order of
linker inputs doesn't matter so much, it'll often work to put -l options in
LDFLAGS, but it's not portable to PE platforms like Windows/Cygwin where the
libraries have to come last on the command-line.
  
Thanks for the very quick reply, it works perfectly now, and I became a 
bit wiser thanks to you. :-)


Nevertheless I apologize for taking up your and everyone else's time 
with something that wasn't an odd behaviour at all.


Kind regards,
Robrecht


--
Problem reports:   http://cygwin.com/problems.html
FAQ:   http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple