Windows makefile: generate debug information - c

I have to automate couple of simple builds on windows.
I am able to generate debug information if I use specific target.
My Makefile
.c.obj:
#echo executing compile rule
$(cc) $(cdebug) $(cflags) $(cvars) $*.c
.obj.exe:
#echo executing linker rule
$(link) $(ldebug) $(conflags) -out:$# $** $(conlibs)
foo.exe: foo.obj
#echo executing target rule
$(link) $(ldebug) $(conflags) -out:$# $** $(conlibs)
nmake /f Makefile.win foo.exe : make Output:
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
executing compile rule
cl -Zi -Od -DDEBUG -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_X
86_=1 -DWIN32 -D_WIN32 -W3 -D_WINNT -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=0x050
00000 -D_WIN32_IE=0x0500 -DWINVER=0x0500 -D_MT -MTd foo.c
foo.c
executing target rule
link /DEBUG /DEBUGTYPE:cv /INCREMENTAL:NO /NOLOGO -subsystem:console,5.
0 -out:foo.exe foo.obj kernel32.lib ws2_32.lib mswsock.lib advapi32.lib
nmake /f Makefile.win bar.exe : make Output:
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
cl bar.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
bar.c
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:bar.exe
bar.obj
Notice that none of the suffix rules were executed second time. What am I doing wrong?
I have added .SUFFIXES: .exe .obj at the top.

First be sure both .obj and .exe are in the suffixes list, or those suffix rules won't take effect:
.SUFFIXES: .obj .exe
Second, using $** is very odd. Why are you adding foo* to your link line? I would think you'd want something like $^ instead.
Other than that all I can suggest is you examine the actual linker lines that are printed by make in both situations and figure out what the difference is between them. You don't show that here.

GNU make takes the approach of modeling the entire dependency tree at once, and tracing the modified files all the way through to the output. This is great if make is the only build tool you use. This doesn't work well if you have very large projects, so you need to make them in a specific order. This doesn't work well if 'make' doesn't support some tools of your build process, so you would need to run make multiple times anyway.
nmake.exe takes the approach of doing the simplest possible thing: Only doing one pass at a time. It assumes it will be part of a larger tool chain. So if you have multi-pass dependencies, you will need multiple passes of nmake. If your build process requires more than 3 passes, you are probably doing A Bad Thing and you should fix your process. And for crying out loud, if you need multiple passes, just write a script to do it.
from here:
nmake inference rules limited to depth of 1

Related

How to compile C code for Xeon Phi (Windows 10)

I'm starting to work with a Xeon Phi and I'm stuck trying to compile a simple C program to run it on the coprocessor. I've tried using icl and icc commands but I haven't got any luck.
1.- with icl
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018\windows\bin\intel64>icl test.c -o test.mic
Intel(R) C++ Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.0.2.185 Build 20180210
Copyright (C) 1985-2018 Intel Corporation. All rights reserved.
test.c
Microsoft (R) Incremental Linker Version 14.15.26726.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test.mic
test.obj
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018\windows\bin\intel64>
then I tried to run test.mic on the Xeon Phi
[xeon#mic0 ~]$ ./test.mic
-sh: ./test.mic: cannot execute binary file
[xeon#mic0 ~]$
2.- with icc
C:\Intel\cc_android_2018.2.185\bin\intel64>icc test.c -o test.mic
Error: A license for (Comp-CL) could not be found.
License file(s) used were (in this order):
1. C:\Program Files (x86)\Common Files\\Intel\Licenses\NCOM_W___XXXX-XXXXXXXX.lic
2. C:\Intel\cc_android_2018.2.185\bin\intel64\..\..\Licenses
3. C:\Program Files\Common Files\Intel\Licenses\NCOM_W___XXXX-XXXXXXXX.lic
4. C:\Intel\cc_android_2018.2.185\bin\intel64\NCOM_W___XXXX-XXXXXXXX.lic
Please refer https://software.intel.com/en-us/faq/licensing#invalid-license-error for more information..
icc: error #10052: could not checkout FLEXlm license
I'm not sure about this error because I have the license.
The problem was the Intel Parallel Studio version I was using (Intel Parallel Studio 2018) . I downloaded Intel Parallel Studio 2017 Update 7 and the compilation worked. The command I was using:
icl /Qmic test.c -o test.out
And I was getting this error:
icl: command line remark #10148: option '/Qmic' not supported

How to compile static .lib library for Windows in Linux or Macos

I am searching way to compile static library for Windows in Linux or Macos, there seems to be cross compiler to generate .a library for Windows like this one, but that is not what I want, what I want is a .lib static library file for Windows, preferably for Visual Studio. I know I can run a Windows virtual machine and using Visual Studio, but that is too heavy, and can't be done in command line.
For unix-like OSes (Linux, MacOS, etc) a static library means
an ar archive of object files. ar is the GNU general
purpose archiver. It doesn't care what kind of files you stick into an archive. It's
just the custom to call it "a static library" when they happen to be object files. And
it's also just a custom for an ar archive to be called *.a. You can call it
*.lib, or anything.
For Visual Studio, a static library means an archive of PE-format object files
usually created by the Microsoft tool LIB.
The format of an Microsoft LIB archive is in fact the same as that of a Unix ar archive. Microsoft
just adopted it, long long ago.
So if you compile some PE object files on Linux using your distro's PE cross-compiler
then archive them into a *.lib with ar, you've got yourself a static library that's good to go in Windows
with the Visual Studio compiler.
Well, you have as long as those object files have C binary interfaces.
If any of them have C++ interfaces, they're useless: the Microsoft and GCC C++ compilers use different name-mangling protocols and are otherwise ABI incompatible.
Demo
We start in linux with some source code for the static library:
hello.c
#include <stdio.h>
void hello(void)
{
puts("Hello world");
}
Cross-compile:
$ x86_64-w64-mingw32-gcc-win32 -o hello.obj -c hello.c
Make the static library:
$ ar rcs hello.lib hello.obj
Then a program that's going to be linked with hello.lib:
main.c
extern void hello(void);
int main(void)
{
hello();
return 0;
}
Now we hop into a Windows 10 VM where we're looking at the the files we've
just created through a shared folder:
E:\develop\so\xstatlib>dir
Volume in drive E is VBOX_imk
Volume Serial Number is 0000-0804
Directory of E:\develop\so\xstatlib
03/12/2017 18:37 72 main.c
03/12/2017 18:29 978 hello.lib
03/12/2017 18:26 66 hello.c
03/12/2017 18:27 832 hello.obj
4 File(s) 1,948 bytes
0 Dir(s) 153,282,871,296 bytes free
Compile and link our program:
E:\develop\so\xstatlib>cl /Fehello.exe main.c hello.lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:hello.exe
main.obj
hello.lib
Run it:
E:\develop\so\xstatlib>hello
Hello world

How to write makefile(nmake) for visual studio build tool cl.exe

I want to build a c application with visual-studio build tool cl.exe by invoking nmake similar like make in **NIX systems. I have written a makefile. It cannot find include files and object files for linking. I couldn't find much reference how to link libraries.
CC=cl.exe
INC=-I../include
LIB=-L../lib
socket: socket.c
$(CC) socket.c $(INC) $(LIB) -lssl -lcrypto
output
D:\client>nmake
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
cl.exe socket.c -I../include -L../lib -lssl -lcrypto
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
cl : Command line warning D9002 : ignoring unknown option '-L../lib'
cl : Command line warning D9002 : ignoring unknown option '-lssl'
cl : Command line warning D9002 : ignoring unknown option '-lcrypto'
socket.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:socket.exe
socket.obj
LINK : fatal error LNK1104: cannot open file 'Ws2_32.lib'
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\cl.exe"' : return code '0x2'
Stop.
the cl.exe does not use the gcc syntax for libraries and include files.
Here is a (usable but not perfect) example of how to specify the files:
cl main.c freetype.lib gdi32.lib glew.lib jpeg.lib
you might also want to read how to include in cl.exe

C: LINK.EXE fails from Makefile but not from the Command line

When I attempt to link from a makefile I get the following error:
LINK : fatal error LNK1104: cannot open file 'LIBCMT.lib'.
Makefile Execution:
C:\Users\snmcdonald\Desktop\winMake2\winMake2>nmake "_DEBUG=" /f win2.mk build
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /ZI /Fo"Debug\\" /Fe"Debug\\" main.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
cl /c /ZI /Fo"Debug\\" /Fe"Debug\\" lib.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
lib.c
lib Debug\lib.obj /out:Debug\lib.lib
Microsoft (R) Library Manager Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
link Debug\main.obj Debug\lib.lib /out:Debug\main.exe
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
main.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:ICF' specif
ication
LINK : fatal error LNK1104: cannot open file 'LIBCMT.lib'
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 10.0\VC\BI
N\link.EXE"' : return code '0x450'
Stop.
However, if I rerun the exact same line that failed and link from the console I get a successful build. I am using the exact same lib and obj that were produced from my make file.
Console Execution:
C:\Users\snmcdonald\Desktop\winMake2\winMake2>link Debug\main.obj Debug\lib.lib /o
ut:Debug\main.exe
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
main.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:ICF' specif
ication
C:\Users\SHANEM~1\Desktop\winMake2\winMake2>debug\main.exe
print from lib
I have included my makefile for reference.
Makefile
!ifdef _DEBUG
CC = cl
CFLAGS = /c /ZI
FILES = *.c
OUT = /Fo"Debug\\" /Fe"Debug\\"
LINKOUT = /out:Debug
DIR = Debug
!else
CC = cl
CFLAGS = /O2
FILES = *.c
OUT = /Fo"Release\\" /Fe"Release\\"
LINKOUT = /out:Release
DIR = Release
!endif
LIB = lib
LINK = link
RM = del
RMFLAGS = *.ojb *.exe 2>NUL
build: main.exe
clean:
$(RM) $(RMFLAGS)
rebuild: clean build
main.exe: main.obj lib.lib
$(LINK) $(DIR)\main.obj $(DIR)\lib.lib $(LINKOUT)\main.exe
lib.lib: lib.obj
$(LIB) $(DIR)\lib.obj $(LINKOUT)\lib.lib
main.obj:
$(CC) $(CFLAGS) $(OUT) main.c
lib.obj:
$(CC) $(CFLAGS) $(OUT) lib.c
Testing
I have tested this on both Visual C version 9 and version 10. I am confused why it would fail on my makefile but run successfully when manually entered on the command line.
Solution:
nmake /E /f win2.mk build
/E - overrides macro vars with environmental paths.
LIB = lib
That screws up the LIB environment variable. Yes, /E will fix it but your next project that actually needs lib.exe is going to fail. Pick another name, win32.mak uses "implib".
The file should exist in
...\Microsoft Visual Studio 8\VC\lib
It could be difference of environment variables setting. Check what are the enviroment variables setting when you run it manually from the command line.
http://us.generation-nt.com/answer/lnk1104-open-file-libcmt-lib-help-21575202.html
The LIB environment variable should
contain the path to your various lib
directories. You can also run the
VCVARS32.BAT file, which will
automatically set the environment up
for you. If you do a lot of command
line builds, I recommend creating a
shortcut that invokes the above
mentioned VSVARS32.BAT

Why is -o a candidate for deletion from the Microsoft compiler and linker?

I came across the following, and I am wondering what implications it is going to have on my Cygwin/GNU environment. Should I be using something other than -o to name the output from a compile?
Has there been some new standard adopted and do other compilers adhere to it?
What would be the motivation for removing -o?
DOS PROMPT> type compile.bat
cl.exe -D YY_MAIN=1 lex.yy.c libfl.obj -o foobar
DOS PROMPT> compile
cl.exe -D YY_MAIN=1 lex.yy.c libfl.obj -o foobar
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
lex.yy.c
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
/out:lex.yy.exe
/out:foobar.exe
lex.yy.obj
libfl.obj
cl: Command line warning D9035 : option 'o' has been deprecated and will be removed in a future release
As the answer below asks, Are they trying to make more of a rift between Windows and UNIX intentionally? I hope not. I am hoping I am missing some new convention adopted by all the compilers out there.
Yes. You should use /F to set compiler output options.
Command line arguments on Windows are different than command line arguments on Unix. They usually start with a / instead of a -, and the arguments to cl.exe won't necessarily match those of cc on Unix.
Looks like the option you're looking for is /Fe
I wouldn't necessarily see a nefarious purpose behind that - it's more likely to be some compatibility-related thing (perhaps -o is interfering with some build system or the other used by some big Microsoft customer or the other.)
However, it is annoying when a compiler vendor throws away entrenched practices and learned reflexes.
But the (syntactical and philosophical) differences between the Microsoft compilers and the Unix compilers are bigger than a simple command line switch. To that end, you could try to step away from simple batch build scripts and towards Makefiles - or, better yet, an actual cross-platform build system such as CMake or SCons (please note that they're just examples, I'm not married to any of them :) ).

Resources