If I have this task in a nimble file:
task readme, "generate README.md":
exec "nim c -r readme.nim > README.md"
with this readme.nim:
echo "# Hello\nworld"
executing task with nimble (nimble readme) does not redirect the output of readme.nim to file.
As expected running nim c -r readme.nim > README.md from terminal correctly creates/updates README.md.
Is this intended behaviour of nimble? is there a workaround?
note: the above was tested on windows.
thanks to answer by #xbello and ensuing discussion, I found a good workaround for my use case:
task readme, "generate README.md":
exec "nim c readme.nim"
"README.md".writeFile(staticExec("readme"))
the explanation to why the simple exec has to do with the fact that nimble uses nimscript.exec which internally uses rawExec which is a builtin that (judging from different behaviours reported here for windows and linux) is not entirely cross-platform when it regards output pipeline.
I end up with the expected README.md:
$ cat README.md
# Hello
world
But sometimes (the readme.nim has to be compiled or recompiled) I end up with something like this:
CC: readme.nim
# Hello
world
That is, the full stdout (not the stderr) of the nim c -r readme.nim command, as expected. As a workaround you could encapsulate what you want to do in the readme.nim:
import os
let f: File = open(commandLineParams()[0], fmWrite)
f.write "# Hello\nworld"
f.close()
And in your nimble file:
task readme, "generate README.md":
exec "nim c -r readme.nim README.md"
Another workaround could be to suppress the output of nim c:
task readme, "generate README.md":
exec "nim c --verbosity:0 -r readme.nim > README.md"
I'm using c++ (cxx) on z/OS USS to compile and link c programs.
I'm getting errors from IEW (linker) that it can't access SYSLIB.
I'm assuming that this has to be an export e.g.
export _CXX_LSYSLIB="CEE.SCEELKEDX:CEE.SCEELKED:CBC.SCCNOBJ:SYS1.CSSLIB"
That was my best shot but still getting errors during linking.
ABEND S013-38 OCCURRED WHILE PROCESSING PARTITIONED DATA SET DDNAME SYSLIB.
There is an easy way to get the right setting of environment variables needed to properly link an application in USS on z/OS. The following command illustrates how this works:
> xlC -v a.C
FSUM0000I Utility(xlc) Level(D170323.1712)
exec: export(export,XL_CONFIG=/bin/../usr/lpp/cbclib/xlc/etc/xlc.cfg:xlC,NULL)
exec: /usr/lpp/cbclib/xlc/exe/ccndrvr(/usr/lpp/cbclib/xlc/exe/ccndrvr,./,./a.C,*.C,CXX,CMDOPTS(DEFINE(errno=(*__errno())),NOTEST,-qoe,-qargparse,-qexecops,-qflag=i,-qhalt=16,-qnodebug,-qnolsearch,-qredir,-qlocale=POSIX,-qlongname,-qmaxmem=*,-qmemory,-qnestinc=255,-qnoexpmac,-qnoexportall,-qnogonumber,-qtarget=le,-qnolibansi,-qlist=/dev/fd1,-qnolist,-qnomargins,-qnooffset,-qnosequence,-qnoshowinc,-qsource=/dev/fd1,-qnosource,-qnoxref,-qterminal,-qnooptimize,-qplist=host,-qspill=128,-qstart,-qnoipa,DEFINE(_OPEN_DEFAULT=1),-qdigraph,-qinfo=lan,-qtempinc=tempinc,-qnortti,-qlanglvl=extended:nolibext:nolonglong,-qnoattr,-qinlrpt=/dev/fd1,-qnoinlrpt,-qtmplparse=no,-qansialias),object(./a.o),NOPPONLY,NULL)
exec: export(export,STEPLIB=CBC.SCCNCMP:CEE.SCEERUN2:CEE.SCEERUN,NULL)
exec: export(export,_CXX_ACCEPTABLE_RC=4,NULL)
exec: /bin/cxx(/bin/cxx,-v,a.o,NULL)
exec: export(export,_CXX_ACCEPTABLE_RC=4,NULL)
exec: export(export,_CXX_PVERSION=0x42030000,NULL)
exec: export(export,_CXX_PSYSIX=CEE.SCEELIB(C128N):CBC.SCLBSID(IOSTREAM,COMPLEX),NULL)
exec: export(export,_CXX_PSYSLIB=CEE.SCEEOBJ:CEE.SCEECPP,NULL)
exec: export(export,_CXX_LSYSLIB=CEE.SCEELKEX:CEE.SCEELKED:CBC.SCCNOBJ:SYS1.CSSLIB,NULL)
FSUM0000I Utility(c89) Level(D170323.1712)
//* cxx ------------------------------------------------------------------------
//LINKEDIT EXEC PGM=LINKEDIT,
// PARM='AMODE=31,RMODE=ANY,TERM=YES,
// DYNAM=DLL,ALIASES=NO,UPCASE=NO,
// LIST=OFF,MAP=NO,XREF=NO,INFO=NO,MSGLEVEL=4,
// REUS=RENT,EDIT=YES,AC=0,CALL=YES,CASE=MIXED'
//SYSLIB DD DSN='CEE.SCEELKEX',DISP=SHR,DCB=DSORG=DIR
// DD DSN='CEE.SCEELKED',DISP=SHR,DCB=DSORG=DIR
// DD DSN='CBC.SCCNOBJ',DISP=SHR,DCB=DSORG=DIR
// DD DSN='SYS1.CSSLIB',DISP=SHR,DCB=DSORG=DIR
//C8920 DD UNIT=SYSALLDA,SPACE=(32000,(100,100)),
// STORCLAS=,MGMTCLAS=,DATACLAS=,DSNTYPE=,
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
//C8961 DD DSN='CEE.SCEEOBJ',DISP=SHR,DCB=DSORG=DIR
//C8962 DD DSN='CEE.SCEECPP',DISP=SHR,DCB=DSORG=DIR
//C8921 DD DSN='CEE.SCEELIB(C128N)',DISP=SHR,DCB=DSORG=NOTDIR
//C8922 DD DSN='CBC.SCLBSID',DISP=SHR,DCB=DSORG=DIR
//SYSPRINT DD PATH='/dev/fd1',
// PATHOPTS=(ORDWR,OCREAT,OAPPEND),FILEDATA=TEXT,
// PATHMODE=(SIROTH,SIRGRP,SIRUSR,SIWOTH,SIWGRP,SIWUSR)
//SYSTERM DD PATH='/dev/fd2',
// PATHOPTS=(ORDWR,OCREAT,OAPPEND),FILEDATA=TEXT,
// PATHMODE=(SIROTH,SIRGRP,SIRUSR,SIWOTH,SIWGRP,SIWUSR)
//SYSLMOD DD PATH='a.out',
// PATHOPTS=(OWRONLY,OCREAT),
// PATHMODE=(SIRWXO,SIRWXG,SIRWXU)
//SYSDEFSD DD DUMMY,
// DCB=(RECFM=F,LRECL=80,BLKSIZE=80)
//SYSLIN DD *
INCLUDE C8920
INCLUDE './a.o'
AUTOCALL C8961
AUTOCALL C8962
INCLUDE C8921
INCLUDE C8922(IOSTREAM)
INCLUDE C8922(COMPLEX)
/*
The output of this command shows what environment variables need to be exported and what data sets are defined for each. Naturally, one does not need to use the c89 utility directly, the same can be accomplished by using the xlc utility.
In your case a cxx command can be replaced with xlC -F:cxx or simply xlC as the xlC command is equivalent to cxx command that invokes the c89 utility. The bonus from using the xlc instead of the c89 utility is that you get to use shell friendly options which are specified using -q syntax and not -Wc,"..." syntax.
You have a typo, I think. Instead of:
_CXX_LSYSLIB="CEE.SCEELKEDX:CEE.SCEELKED:CBC.SCCNOBJ:SYS1.CSSLIB"
I think you want:
_CXX_LSYSLIB="CEE.SCEELKEX:CEE.SCEELKED:CBC.SCCNOBJ:SYS1.CSSLIB"
It's the extra 'D' that's killing you. Crappy error message I agree.
I am trying to run Ymer tool in windows 10 platform. I have installed g++, gcc, yacc via cygwin. After configure command, When I am running make command to compile the application, it generates following error.
PS C:\ymer> make
/bin/sh ./ylwrap src/grammar.yy y.tab.c src/grammar.cc y.tab.h echo src/grammar.cc | sed -e s/cc$/hh/ -e s/cpp$/hpp/ -e s/cxx$/hxx/ -e s/c++$/h++/ -e s/c$/h/ y.output src/grammar.output -- byacc -d
byacc: e - line 514 of "/cygdrive/c/ymer/src/grammar.yy", syntax error
%defines
^
Makefile:2467: recipe for target 'src/grammar.cc' failed
make: *** [src/grammar.cc] Error 1
It seems the grammar.yy file causes the problem. Anyone knows how to solve this problem. BTW I am not familiar neither with yacc nor make files. I am just very new to cygwin as well.
Thank you,
The %defines declaration is bison-specific (not part of standard yacc). The file grammar.yy contains some bison features which byacc implements, but this is not one of those. (From the description in the manual page, it seems that this is equivalent to the standard command-line option -d, making it less than useful).
Is there a way to get rustc to only output the first few errors when compiling with Cargo, or even better, to print the oldest errors last? It seems the default threshold for aborting the compile is set quite high:
error: aborting due to 25 previous errors
I don't have the patience to scroll through 6-10 pages of text to find the first error.
Normally I would handle this by compiling inside my editor (vim), but the vim configuration that ships with rust doesn't seem to be setting errorformat properly.
Piping to a pager is also failing for some reason:
cargo test | less
cargo test writes errors to stderr, so you have to redirect stderr to stdout like this:
cargo test --color always 2>&1 | less -r
In Linux I am trying to compile something that uses the -fwritable-strings option. Apparently this is a gcc option that doesn't work in newer version of gcc. I installed gcc-3.4 on my system, but I think the newer version is still being used because I'm still get the error that says it can't recognize the command line option -fwritable-strings. How can I get make to use the older version of gcc?
You say nothing about the build system in use, but usually old versions of gcc can be invoked explicitly, by something like (this is for an autotools-based build):
./configure CXX=g++-3.4 CC=gcc-3.4
For a make-based build system, sometimes this will work:
make CXX=g++-3.4 CC=gcc-3.4
Most makefiles ought to recognise overriding CC and CXX in this way.
If editing the configuration/Makefile is not an option, Linux includes a utility called update-alternatives for such situations. However, it's a pain to use (links to various tutorials included below).
This is a little simpler - here's a script (from here) to easily switch your default gcc/g++ version:
#!/bin/bash
usage() {
echo
echo Sets the default version of gcc, g++, etc
echo Usage:
echo
echo " gcc-set-default-version <VERSION>"
echo
exit
}
cd /usr/bin
if [ -z $1 ] ; then
usage;
fi
set_default() {
if [ -e "$1-$2" ] ; then
echo $1-$2 is now the default
ln -sf $1-$2 $1
else
echo $1-$2 is not installed
fi
}
for i in gcc cpp g++ gcov gccbug ; do
set_default $i $1
done
If you 1) name this script switch-gcc, 2) put it in your path, and 3) make it executable (chmod +x switch-gcc), you can then switch compiler versions just by running
sudo switch-gcc 3.2
Further reading on update-alternatives:
https://lektiondestages.blogspot.com/2013/05/installing-and-switching-gccg-versions.html
https://codeyarns.com/2015/02/26/how-to-switch-gcc-version-using-update-alternatives/
https://askubuntu.com/questions/26498/choose-gcc-and-g-version
Maybe you could just give the whole path of the gcc-3.4 install while compiling your program:
/path_to_gcc_3.4/gcc your_program
If you can find where the writeable strings are actually being used, another possibility would be to use strdup and free on the subset of literal strings that the code is actually editing. This might be more complicated than downgrading versions of GCC, but will make the code much more portable.
Edit
In response to the clarification question / comment below, if you saw something like:
char* str = "XXX";
str[1] = 'Y';
str[2] = 'Z';
// ... use of str ...
You would replace the above with something like:
char* str = strdup("XXX");
str[1] = 'Y';
str[2] = 'Z';
// ... use of str ...
free(str);
And where you previously had:
char* str = "Some string that isn't modified";
You would replace the above with:
const char* str = "Some string that isn't modified";
Assuming you made these fixes, "-fwritable-strings" would no longer be necessary.