Microsoft nmake: $? expands but $< does not - nmake

I'm trying to compile some third-party code and have hit some strange NMAKE behavior.
The line in the Makefile is
cholmod_aat.o: ../Core/cholmod_aat.c
$(C) -c $(I) $< -Fo$#
which produces the following error:
Wed, Aug 15 2012 23:25:20 ../Include/cholmod.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_blas.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_check.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_cholesky.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_complexity.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_config.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_core.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_internal.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_matrixops.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_modify.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_partition.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_supernodal.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_template.h
Fri, Aug 17 2012 16:06:24 ../Core/cholmod_aat.c
cholmod_aat.o target does not exist
NMAKE : warning U4006: special macro undefined : '$<'
cl -O2 -nologo -D__MINGW32__ /MD -DNPARTITION -c -I../../AMD/Include -I.
./../AMD/Source -I../../COLAMD/Include -I../../metis-4.0/Lib -I../../CCOLAMD/In
clude -I../../CAMD/Include -I../Include -I../../UFconfig -Focholmod_aat.o
cl : Command line error D8003 : missing source filename
NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio 10.0
\VC\BIN\cl.EXE"' : return code '0x2'
Stop.
Why is nmake saying '$<' is "undefined" when it lists cholmod_aat.c as a dependency right beforehand? Even more confusing is that if I replace $< with $? in the makefile, nmake expands '$?' just fine:
Wed, Aug 15 2012 23:25:20 ../Include/cholmod.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_blas.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_check.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_cholesky.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_complexity.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_config.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_core.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_internal.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_matrixops.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_modify.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_partition.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_supernodal.h
Wed, Aug 15 2012 23:25:20 ../Include/cholmod_template.h
Fri, Aug 17 2012 16:06:24 ../Core/cholmod_aat.c
cholmod_aat.o target does not exist
cl -O2 -nologo -D_MINGW32_ /MD -DNPARTITION -c -I../../AMD/Include -I.
./../AMD/Source -I../../COLAMD/Include -I../../metis-4.0/Lib -I../../CCOLAMD/In
clude -I../../CAMD/Include -I../Include -I../../UFconfig ../Include/cholmod.h .
./Include/cholmod_blas.h ../Include/cholmod_check.h ../Include/cholmod_cholesky.
h ../Include/cholmod_complexity.h ../Include/cholmod_config.h ../Include/cholmod
_core.h ../Include/cholmod_internal.h ../Include/cholmod_matrixops.h ../Include/
cholmod_modify.h ../Include/cholmod_partition.h ../Include/cholmod_supernodal.h
../Include/cholmod_template.h ../Core/cholmod_aat.c -Focholmod_aat.o
What is going on?

The answer is on MSDN:
$< - Dependent file with a later timestamp than the current target.
Valid only in commands in inference rules.
It's not in an "inference rule", it's in a "description block", as these things are called in NMAKE.
--- EDIT: Expanding on my original answer ---
The terminology is a little strange so in this case it's easiest to show by example. I created a makefile with 2 rules - a description block (a.k.a. target rule), and an inference rule.
C:\temp>type makefile.txt
c.txt : a.txt b.txt
#echo $?
#echo %s
.SUFFIXES: .log
.log.txt:
#echo $<
I created empty files a.txt, b.txt and d.log for dummy input. Then I ran the makefile on targets c.txt and d.txt:
C:\temp>nmake /f makefile.txt c.txt d.txt
Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
a.txt b.txt
a.txt
d.log
C:\temp>
Hopefully this illustrates the difference between $?, %s and $<. The MSDN documentation is rather terse, but the code really does work as documented. Honest!

You could try the following:
cholmod_aat.obj: ../Core/cholmod_aat.c
$(C) -c $(I) %s -Fo$#
The symbol %s maps to the first dependency in the list

Related

How to find which process periodicitly write to a file?

There is a file in /tmp/echo_test.txt, and some process periodicitly write timestamp to this file one minute.
I checked process list and crontab, but found nothing. Is there a way to find the process quickily?
Thanks you.
My OS is Centos 6, the text like below:
Mon Oct 19 10:47:01 CST 2020
Mon Oct 19 10:48:01 CST 2020
Mon Oct 19 10:49:01 CST 2020
Mon Oct 19 10:50:01 CST 2020
Mon Oct 19 10:51:01 CST 2020
Mon Oct 19 10:52:01 CST 2020
If it's a single, continuous process, lsof or fuser should help.
Otherwise, it's probably a cron job or at job, or someone put together a while loop with a sleep 60 in it that's fork+exec'ing.

Extract Date From Long Date - Time Format

I have the following dates and time in a column:
23 Jul 2016 04:36:37 GMT
24 Jul 2016 07:46:12 GMT
26 Jul 2016 05:44:21 GMT
25 Jul 2016 14:25:39 GMT
20 Jul 2016 15:14:42 GMT
22 Jul 2016 11:52:02 GMT
23 Jul 2016 14:31:31 GMT
23 Jul 2016 11:04:36 GMT
12 Jul 2016 22:33:19 GMT
21 May 2016 20:51:54 GMT
8 Jul 2016 07:38:34 GMT
5 Jun 2016 05:00:29 GMT
I would like to get an output in the format MM/DD/YYYY or M/D/Y.
I have tried using the following post as a reference: Removing time element of Long Date Format
However, I can not use =INT(A1) due to the formatting or =LEFT(A1,10) because it may be 10 or 11 characters.
Combine the two:
=INT(--LEFT(A1,LEN(A1)-3))
Since we only need to remove the GMT we don't care how long it is we just remove the last three.
Similar to Scott Craner's answer, you can remove the last the characters ("GMT") and then find the date value as follows:
=DATEVALUE(LEFT(A1,LEN(A1)-3))

How to remove terminal control escape sequences in the file?

I got a log from remote linux computer. It looks like:
2013-10-23T08:19:05+0300 Last login: Wed Oct 23 08:17:38 EEST 2013 from 10.9.167.55 on pts/0
2013-10-23T08:19:05+0300 Last login: Wed Oct 23 08:19:05 2013 from 10.9.167.55^M
2013-10-23T08:19:07+0300 ^[[?1034h-bash-4.1$ date
2013-10-23T08:19:07+0300 Wed Oct 23 08:19:07 EEST 2013
2013-10-23T08:19:08+0300 -bash-4.1$ ls
2013-10-23T08:19:08+0300 ^[[0m^[[01;34m99^[[0m #avail.info ^[[01;34mgmoTemp^[[0m raml21.dtd SNMP4JTestAgentBC.cfg
2013-10-23T08:19:08+0300 an_mainHost_localhost_20131023081654000136.xml #avail.info~ gsh.txt ^[[01;34mresults^[[0m
2013-10-23T08:19:09+0300 ^[[m-bash-4.1$ exit
2013-10-23T08:19:09+0300 logout
But it should be:
Last login: Wed Oct 23 08:17:38 EEST 2013 from 10.9.167.55 on pts/0
Last login: Wed Oct 23 08:19:05 2013 from 10.9.167.55
-bash-4.1$ date
Wed Oct 23 08:19:07 EEST 2013
-bash-4.1$ ls
99 #avail.info gmoTemp raml21.dtd SNMP4JTestAgentBC.cfg
an_mainHost_localhost_20131023081654000136.xml #avail.info~ gsh.txt results
-bash-4.1$ exit
logout
The messy codes are terminal control escape sequences, you can use command "infocmp xterm" and "man terminfo" to get more details.
My question is how can I remove these terminal control escape sequences in the file?
Thanks a lot!
Simple way to remove most parts of the control character is using the command below in vim:
:%s/<escape-key>\[[0-9;]*m/ /g
Press Ctrl+V followed by esc-key for the <escape-key> character above. Everything else is the same literal key as in your keyboard.
i use a pipe or direct sed like this
sed 's/[^[:print:]]\[[^a-zA-Z]*[a-zA-Z]//g' YourFile
I solved this issue using lots of regular expressions according to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

Monitor the rate of log file writes matching a pattern

I have a timestamped log file that I am watching. Every so often the log writes a message, "OK"
How could I capture the number of "OK"s written per second? E.g. output like
10.5 OK/sec
9 OK/sec
20 OK/sec
The log is pretty big, its not practical to do a grep on the entire file. I started with
tail -f my.log | grep OK
which is helpful but doesn't quite get me the rate.
Thanks!
First solution below is great (and other is good too), I altered it a bit and this is what I came up with
tail -f my.log | perl -lne 'if(/(\d+:\d+:\d+).*OK/) { print $1; }'| uniq -c
When your log is in form like:
Wed Jul 10 22:44:00 CEST 2013 OK
Wed Jul 10 22:44:00 CEST 2013 OK
Wed Jul 10 22:44:00 CEST 2013 OK
Wed Jul 10 22:44:00 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
Wed Jul 10 22:44:01 CEST 2013 OK
so, in form timestamp OK, you can try the simple:
tail -f logfile | uniq -c
and you will get the next result:
4 Wed Jul 10 22:44:00 CEST 2013 OK
8 Wed Jul 10 22:44:01 CEST 2013 OK
^
+---- number of OK in the same timestamp
Here's a quick script to do it:
#! /bin/bash
log="/var/log/messages"
seconds="1"
filter="OK"
while true; do
echo "$(timeout $seconds tail -n0 -f $log|grep $filter|wc -l) OK/sec"
done
There's a bit of a race condition where it might lose one or two lines during the loop, but it is unlikely. Also, not every Linux distro has timeout installed by default, so you might want to check.

one week information of alertlofile

I want to view the ORA errors in alertlogfile of past 7 (monday-sunday)days,
by writting in shell scripts.
Can anybody help me.
Thanks
Something like:
sed -n -e '/start_time/,/end_time/ {/ORA/ p}' logfile
or with awk
$ start="Fri Feb 27 08:00:00 2009"
$ end="Fri Mar 6 08:00:00 2009"
$ awk -v prev="$start" -v last="$end" '$0 ~ prev,$0 ~ last' logfile
A more sophisticated script looking for last date entries in ORA file is available here, but also at dba-oracle.com
This does not answer exactly your request but might give you some clues to start your own script.
I want the scripts which give output as follows (one week errors) and it should be mail to my id.
Sat Mar 14 10:30:51 IST 2009
ORA-01157: cannot identify/lock data file 2 - see DBWR trace file
Sat Mar 12 12:35:06 IST 2009
ORA-01110: data file 2: '/u02/oradata/Globe/undotbs01.dbf'
Sat Mar 10 09:54:05 IST 2009
ORA-27037: unable to obtain file status
Sat Mar 08 :15:02 IST 2009
ORA-1157 signalled during: ALTER DATABASE OPEN...
Sat Mar 07 12:35:51 IST 2009
ORA-01157: cannot identify/lock data file 2 - see DBWR trace file

Resources