how to handle spaces in the filepath - openfiledialog

So, i wrote a code, that would compile a C++ code using tdm gcc compiler. My code uses openfiledialog to allow the user to choose the file to be compiled and then I construct a String command as,
cmd = "/c g++ " + openfiledialog.filename.toString() + " -o temp.exe";
And then i'm executing this command in a normal way using process instance. But, if there are spaces in filepath, eg: "D:\haha haha\test.cpp" then the g++ compiler shows an error saying no such directory haha etc etc. how to overcome this?

You'll need quotes around the file name to form the g++ command line:
cmd = "/c g++ \"" + openfiledialog.filename.toString() + "\" -o temp.exe";
Alternatively, you could post-process the value returned by .toString() to insert an escape (backslash \) character before each space. But the quote method is easier.

Related

Standard error file when there is no error

I'm new to Linux & shell and I'm struggling with checking if the compilation is successful.
g++ code.cpp -o code.o 2>error.txt
if [ ! -e error.txt ]
then
do something
else
echo "Failed to compile"
I guess an error file is created even if the compilation is successful. What is the content of the error file when there is no error? I need to change the if condition to check if the compilation is successful.
It's just the order of things. What happens when the shell parses the string g++ code.cpp -o code.o 2>error.txt is:
The shell creates error.txt, truncating the file if that name already exists.
g++ is called with its error output redirected to the new file.
If g++ does not write any data, then the file remains as it was (empty) at the end of step 1.
You probably aren't so much interested in the error file as you are the return value. You probably ought to just do:
if g++ code.cpp -o code; then : do something; done
or even just:
g++ code .cpp -o code && : do something
but if really want to do something else with the errors, you can do:
if g++ code.cpp -o code.o 2> error.txt; then
rm error.txt
: do something
else
echo >&2 Failed to compile code.cpp.\ See "$(pwd)"/error.txt for details.
fi
Make sure you escape at least one of the spaces after the . so that you get 2 spaces after the period (or just quote the whole argument to echo). Although it's become fashionable lately to claim that you only need one space, all of those arguments rely on the use of variable width fonts and any command line tool worth using will be used most often in an environment where fixed width fonts are still dominant. This last point is totally unrelated to your question, but is worth remembering.

How to let MAKEFILE retain the backslash sequences within a string when used in a make rule?

This is my first question on Stackoverflow so forgive me if I ask anything ridiculous :D.
Problem:
Suppose I want to compile a program that is in the directory "my dir/" with a space in it. Say the pathname of the program is "my dir/test.c".
Here is the sample makefile that I was trying out:
CC = gcc
DIR = my\ dir
$(DIR)/test.out: $(DIR)/test.c
# $(CC) $< -o $#
$(CC) $(DIR)/test.c -o $(DIR)/test.out
As you can see that in the last line(line-5) I have written the pathnames of the source and the output files directly as written in the prerequisite and the target, respectively. Doing this works fine because it yields the command:gcc my\ dir/test.c -o my\ dir/test.outwhich a syntactically correct way of passing filenames(with spaces) to gcc or any other shell command.
The second last line(line-4) is where the problem is(commented line). I've used automatic variables $# (Target) and $< (First and the only Prerequisite) to produce the filename arguments for gcc which I expected to bemy\ dir/test.out and my\ dir/test.c, respectively. But here, for some reason, the produced filenames are my dir/test.out and my dir/test.c and hence the yielded command is: gcc my dir/test.c -o my dir/test.out
Now here, gcc considers my and dir/test.c as different two different input filenames and the command generates errors.
Here is a screenshot of the generated error output when I uncomment line-4 and comment line-5 of the above Makefile:
My Question:
Is there any way to retain those backslashes even by using automatic variables the way I did? Or is there any alternative that will achieve the same goal as using automatic variables and also solve my problem? Because flexibility is important here.
Thanks in advance for your help!!!
Use double or single quotes for the automatic variables.
Use single quotes, if you want to avoid shell expansion of the values referenced by the automatic variables:
$(DIR)/test.out: $(DIR)/test.c
$(CC) '$<' -o '$#'
Double quotes allow shell expansion. For example, if there was a dollar sign in DIR:
DIR := $$my\ dir
then "$#" would expand to "$my dir", and the shell would interpret $my as variable.

Reading makefiles. Meaning of symbols

I am trying to learn how to read makefiles and came across this one. My question is referring to the rule with target %.c. On the first command. where it says
%.c: %.psvn psvn2c_core.c psvn2c_state_map.c psvn2c_abstraction.c
../psvn2c $(PSVNOPT) --name=$(*F) < $< > $#
What does $(*F) < $ < > $# mean? I have posted the whole makefile below.
CC = gcc
CXX = g++
OPT = -g -Wall -O3 -Wno-unused-function -Wno-unused-variable -std=c++11
PSVNOPT = --no_state_map --no_backwards_moves --history_len=0 --abstraction --state_map
psvn2c_core.c:
cp ../psvn2c_core.c ./psvn2c_core.c
psvn2c_state_map.c:
cp ../psvn2c_state_map.c ./psvn2c_state_map.c
psvn2c_abstraction.c:
cp ../psvn2c_abstraction.c ./psvn2c_abstraction.c
%.c: %.psvn psvn2c_core.c psvn2c_state_map.c psvn2c_abstraction.c
../psvn2c $(PSVNOPT) --name=$(*F) < $< > $#
rm -f ./psvn2c_core.c ./psvn2c_state_map.c ./psvn2c_abstraction.c
I want to understand this as a first step towards learning how to run a c++ debugger such as gdb with eclipes or visual studio.
Anything that begins with a $ in a makefile is a variable reference (or, in GNU make, a built-in function), unless it's escaped with another $ (i.e., is $$). The name of the variable can either be a single character, like $#, $A, etc., or it can be one or more characters enclosed in parentheses or braces, like $(#), ${A} (the same as the last ones), $(FOO), ${FOO}, etc.
The GNU make manual has lots of information about all the pre-defined and special variables. These odd-looking variables in particular are automatic variables.
If it's not a variable, and it's part of a recipe, then it's sent to the shell, so you should look at the shell documentation to understand it.
Is it correct to say that < means pipe the input in from and then $< is the first file in the list of dependancies. and > means pipe output to and $# is the output file ie. the file on the left hand side of the : symbol?

scons surrounds option with double quotes

I use scons (V1.1.0) for a project that contains a build step that involves the flex tool.
The definition for the flex command in the scons default rules is:
env["LEX"] = env.Detect("flex") or "lex"
env["LEXFLAGS"] = SCons.Util.CLVar("")
env["LEXCOM"] = "$LEX $LEXFLAGS -t $SOURCES > $TARGET"
which I don't want to change.
However, since -t causes #line directives to be created in the output file that refer to the file "<stdout>", this confuses the subsequent gcov processing.
As a solution, I found that -o can be used to override the file name flex produces into the #line directives (it still produces its output on stdout due to the -t option which apparently has precedence).
To achieve that, I added this in the project's SConscript file:
env.AppendUnique(LEXFLAGS = ['-o $TARGET','-c'],delete_existing=1)
I added the -c option (which does nothing) only to show the difference between how it is treated compared to -o.
An according debug print in the SConscript file results in the following (as expected):
repr(env["LEXFLAGS"]) = ['-o $TARGET', '-c']
This results in the following command line, according to the scons log:
flex "-o build/myfile.cpp" -c -t src/myfile.ll > build/myfile.cpp
So the -c option gets into the command line as desired, but the -o option and its filename parameter has double quotes around it, that must have been created by scons when expanding the LEXFLAGS variable.
When I use this definition for LEXFLAGS instead:
env.AppendUnique(LEXFLAGS = ['--outfile=$TARGET','-c'],delete_existing=1)
the resulting command line works as desired:
flex --outfile=build/myfile.cpp -c -t src/myfile.ll > build/myfile.cpp
So one could speculate that the blank in the -o case caused the double quotes to be used, maybe in an attempt to bind the content together into one logical parameter for the command.
So while my immediate problem is solved by using --outfile, my question is still is it possible to rid of the double quotes in the -o case?
Thanks,
Andy
SCons 1.1.0 is extremely old at this point. I'd recommend trying 2.3.0. But your analysis is correct; if an option (a single option, that is) has a space in it, SCons will quote it so it stays a single option. But you don't have a single option; you really have two, '-o' and '$TARGET'. Just break it up like that and it'll work.

ubuntu - can not find shared library while compiling

I would like to compile code with such a statement:
c++ -I /usr/boost_1_53_0 boost_test.cpp -o boost \ /usr/lib/boost/libboost_regex.a
but it throws
c++: error: /usr/lib/boost/libboost_regex.a: No such file or directory
I am sure, that libboost_regex.a is existing i above mentioned directory.
How to solve it? I am new to ubuntu and linux.
Looking forward for your tips. Thanks.
The issue is the backslash included in the command line:
c++ -I /usr/boost_1_53_0 boost_test.cpp -o boost \ /usr/lib/boost/libboost_regex.a
^
+-- escaped space character
This backslash escapes the following space character, so that effectively the path name is (using percent encoding for better readability):
%20/usr/lib/boost/libboost_regex.a
To solve it, simply remove the backslash character.

Resources