How to escape multiple parameters with "-with-rtsopts" - haskell-stack

Using stack, you can specify -with-rtsopts in package.yaml as follows
ghc-options:
- -with-rtsopts=-N
However, it is unclear how to represent several rtsopts at once. In this example I've put double quotes around them
ghc-options:
- -with-rtsopts="-N -I0 -qg"
... but this does not work ...
Preprocessing library for uke-0.1.0.0..
Building library for uke-0.1.0.0..
Preprocessing executable 'uke-exe' for uke-0.1.0.0..
Building executable 'uke-exe' for uke-0.1.0.0..
ghc: unrecognised flag: -qg"
What is the proper way to escape multiple -with-rtsopts values in package.yaml?

It works if you double quote the whole expression:
ghc-options:
- '"-with-rtsopts=-N -I0 -qg"'

Related

Universally escape dollar sign

I'm working on embedded project, which consists of my own code as well as 3rd party libraries and executables. To build all the parts consistently, I've written a script, which sets environment variables for cross-compilation (CC, CXX, CFLAGS, etc.). Among others it sets LDFLAGS to pass the rpath flag to linker. The rpath value contains $ORIGIN token, which must not be expanded and must be seen by linker and written to output binary as is. I then build several needed 3rd party projects using the environment set by the script. The projects uses different build systems (make, CMake, others maybe). Because of this and maybe because of the build scripts written in different ways, the dollar sign is expanded differently. I.e., whatever escaping I try, I get different results in different projects (e.g., $$ORIGIN, RIGIN, empty string), but never I managed to get the same $ORIGIN value in all the binaries. Is there a universal way to escape dollar sign so that it will work the same in at least make and shell, but in any combination?
This is how I've finally solved this problem.
In addition to the previous environment variables, needed to build for my platform, I've added two more:
ORIGIN=$ORIGIN
O=$$O
The former is to workaround shell expansion, and the latter is to workaround makefile expansion. With this fix, variables are resolved to themselves.
Yes, this does not look like an ideal solution, looks more like a hack, but it works so far allowing me to avoid adapting my build environment for every third party project I use.
I've hit the same expansion problem, and here is the adapted version for a bash script.
LDFLAGS="-Wl,-rpath=\$ORIGIN"
LDFLAGS="-lfoo $LDFLAGS"
LDFLAGS="-L. $LDFLAGS"
echo $LDFLAGS
# -L. -lfoo -Wl,-rpath=$ORIGIN # <== correct ORIGIN
ORIGIN='$ORIGIN'
eval echo $LDFLAGS
# -L. -lfoo -Wl,-rpath=$ORIGIN # <== correct ORIGIN

How to make install using path with space and dot

I want to make install(sudo make install) using path with space and dot. (e.g. /Applications/Sample App.app/Contents/Resources)
However, following error invoked.
ginstall: target 'App.app/Contents/Resources/lib/libserialport.a' is not a directory
If I use the path with only space, sudo make install really works well with \ escape character.
Makefiles and pathnames which contain spaces do not mix well. Make uses whitespace to split strings into lists. For example, of you write this:
SOURCES = foo.c bar.c baz.c
OBJECTS = $(patsubst %.c,%.o, $(SOURCES))
program: $(OBJECTS)
Then make will treat the variables SOURCES and OBJECTS as lists of strings, split on whitespace characters, and program will depend on the three items foo.o, bar.o, baz.o.
Make does not know at all that some strings should not be split this way (because they refer to pathnames). Like many early scripting languages, it is completely based on string interpolation. This is true for the shell script fragments used to write the build steps as well.
There are some workarounds possible, but they all depend on how variables are used within the makefile. Recursive makefiles can pose additional problems if the contents of these variables are passed down explicitly to the invoked make command using the shell.
In some cases, the fix is rather simple, so if there is an install rule like this:
install: program
$(INSTALL) -m 755 program $(DESTDIR)$(bindir)/program
It may be sufficient to add quotes, like this:
install: program
$(INSTALL) -m 755 program "$(DESTDIR)$(bindir)/program"
But this really depends on the makefile in question.
If the project uses automake (like libserialport), the simplest solution is to use the DESTDIR support in the generated makefile to install the whole thing to a path which does not contain spaces, and then move it to the final destination afterwards. This assumes that the project does not internally embed the final installation path, though.

gcc preprocessor: how to escape quotes in an argument

I am trying to use gcc preprocessor for its macro expansion capabilities (I'm not trying to produce code).
I have a macro — MY_MACRO — that needs to get an argument that has double quotes inside
As you can see, the preprocessor produces an error: unterminated argument list
Is there a way to escape the quotes?
#define MY_MACRO(X)
MY_MACRO(prefix"suffix)
For example:
$ gcc -E -P -w a.txt
error: unterminated argument list invoking macro "MY_MACRO"
$
The C preprocessor works on C source code. A lone " is not valid C, so the cpp rejects it. You can cpp for other purposes only if you're willing to stick to the C syntax rules.
m4 is a general-purpose macro-processor and standard installed on anything Unix-like, though nobody likes it. There aren't many alternatives.

How to make gcc uses march=native as default?

Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?
Related things in the default specs file is:
*cc1:
%(cc1_cpu)
*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.
Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?
BTW, what does %> do? Seems like it is not specified in the documentation.
I am using MinGW's gcc-4.6.2.
Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:
%>S Similar to "%<S", but keep it in the GCC command line.
For the sake of completeness following the comment for %< form the same file:
%<S remove all occurrences of -S from the command line.
Note - this command is position dependent. % commands in the
spec string before this one will see -S, % commands in the
spec string after this one will not.
To answer the first question in short: yes, but ....
... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.
1 The solution (without workaround)
Create a specs-file called let's say specs.nativealways containing:
*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).
2 The workaround
To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).
The modfied specs-file looks like this:
*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.
While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.
*cc1_cpu:
+ %{!march*:-march=native}

GCC preprocessor removing comments

Is it possible to instruct the GCC preprocessor not to remove comments when processing files?
GCC has the -C option to preserve comments.
`-C'
Do not discard comments. All comments are passed through to the
output file, except for comments in processed directives, which
are deleted along with the directive.
You should be prepared for side effects when using `-C'; it causes
the preprocessor to treat comments as tokens in their own right.
For example, comments appearing at the start of what would be a
directive line have the effect of turning that line into an
ordinary source line, since the first token on the line is no
longer a `#'.
Yes, you can do it with the -C option. E.g.
gcc -C -E myfile.c
man gcc and use / -C (slash, space, dash, capitcal C) to make less (which is probably your pager program) search for the -C option, use n to search again (the description is the 3rd hit). Related options are both above and below.

Resources