Glob files except that including some expression - c++

I want to write a command to build FooMain.cc among the following files:
$ ls src
FooMain.cc
FooMain2.cc
BarMain.cc
Helper.cc
Helper.h
FileToInclude.cc
FileToInclude.h
...
Each main file (those including Main) has main() function and they require all the other files without Main in filenames.
The straightforward way to build would be like:
clang++ [options] FooMain.cc Helper.cc FileToInclude.cc ...
Here the expression HelperOne.cc FileToInclude.cc ... includes all the files but those including Main.
What I want to do is rephrase this expression with glob expression
clang++ [options] FooMain.cc [Some clever glob expression]
I looked up for a while but could not find similar questions.
Appreciate any clues. Thank you!

Using ksh93, bash with the extglob option turned on (shopt -s extglob), or zsh with the ksh_glob option turned on (setopt ksh_glob):
$ clang++ [options] FooMain.cc !(*Main*).cc
Using zsh with the extended_glob option turned on (setopt extended_glob):
$ clang++ [options] FooMain.cc *.cc~*Main*

Related

g++ -I include all subdirectories with header files

I've just stumbled upon this post about compiling all .cpp files, including those in subdirectories using the linux find command:
g++ -g $(find RootFolderName -type f -iregex ".*\.cpp") -o OutputName
The problem with this is that all files need their relative path written out when doing #include for this to work. You can get around it by adding what ever directory you need using the -I tag:
g++ -g $(find RootFolderName -type f -iregex ".*\.cpp") -o OutputName -I ./somePath
But that's still quite a hassle if you have multiple subdirectories. Is it possible to use find again with some other regular expression to include all of the subdirectories?
Is it possible to use find again with some other regular expression to include all of the subdirectories?
Yes it is - some projects, like mbed and arduino, seem to include all possible directories to include paths. In shell assuming there are no whitespaces, you could:
find . -type f -iname '*.h' -printf "-I%h\n" | sort -u
This is error prone to whitespaces in path. When using:
command $(stuff)
you will have problems with spaces in filenames. Research other methods and how to handle whitespaces in shell. Better yet, do not write such stuff manually and reinvent the wheel and move to a build system, like cmake.

Pass a regex pattern to Perl Packer from Powershell

How do I correctly write this in a Windows Powershell? Coming from macOS, I have some problems in understanding what it is wrong with this:
pp -u -g -o Executable -f Bleach="^(AAA_|BBB_|MainScript)" MainScript.pl
The regular expression to be passed to the option -f (filter) is not accepted and fires all sort of errors (command not recognized, and so on, no matter as I try to change it). On a Unix system it works just fine.
Escape character for Powershell is `.
Something like this could work:
pp -u -g -o Executable -f Bleach=`"`(AAA_`|BBB_`|MainScript`)`" MainScript.pl`

CPP -D option for preprocessing of Fortran codes

I am trying to understand a makefile in which a Fortran code is used with cpp for preprocessing in the following manner,
cpp -P -traditional -DMPI -DLINUX -DX86_64 -DGFORTRAN -D'HEADER="testfile.h"' -D'ROOT_DIR="/home/Desktop"'...-D'FILE_DIR="/home/Desktop/MYFILES"' -I/usr/local/include file.F
I understood the usage of include directory but I am unable to understand the purpose of -D options (named as CPPFLAGS) listed here. I see that if I remove any of the -D option, my output is modified (I get only start and end of my program and no text in between).
Edit: I have a list of ifdef options and my makefile uses different subdirectories with -D option. What is it looking in those directories, Files in which the option is defined?
If I understand you correctly, you just want to figure out the meaning of -D.
gcc -D defines a macro to be used by the preprocessor.
the syntax is below:
$ gcc -Dname [options] [source files] [-o output file]
$ gcc -Dname=definition [options] [source files] [-o output file]
If you remove any -D, it means this macro isn't defined. So your output might be changed.

Full code paths in clang errors

I am looking for the clang equivalent of the cl command /FC. I need full paths for my build tool to parse out and open the code files with the errors.
https://msdn.microsoft.com/en-us/library/027c4t2s.aspx
CFLAGS+= -fdiagnostics-absolute-paths
You need to specify a fully-qualified or relative path to the file on the command-line instead of only passing in the filename. In the following example the debugger won't know where to find "blah.cc" because I compiled by specifying only the filename:
~ pwd
/mnt/scratch/myproject/src
~ clang++ blah.cc -c -o /mnt/scratch/myproject/build/blah.o
~ cd ../build
~ clang++ *.o -o myprogram
... however, if instead I'd done this:
~ pwd
/mnt/scratch/myproject
~ clang++ /mnt/scratch/myproject/src/blah.cc -c -o /mnt/scratch/myproject/build/blah.o
# or:
~ clang++ src/blah.cc -c -o build/blah.o
# ...
... then it embeds the fully-qualified or relative path into the debug sections.
If you use a partially qualified path, you'll have to tell GDB where to look for the code. You can look at the documentation for it here, though two gdb commands that may be helpful:
# This will cause gdb to look in "path2" instead of "path1"
(gdb) set substitute-path path1 path2
# This allows you to give a list of directories to search for your source.
# note that if you give relative paths on the command-line, it'll concatenate
# these paths and the relative path used at compile-time.
(gdb) set directories path [path ...]

Setting up g++ compiler and linker options

I just recently switched back to Linux from windows and VC, but I never done any special coding using g++ compiler.
Currently my libraries (boost and others) are scattered all over the hard drive and I need to learn how to setup my compiler and linker so that all the compiler settings..
(includes, libs, flags) etc.. will be held in one single file or place, so that it becomes easy to manage, because I don't want to type these things every time I launch the compiler on command line.
Also note that I'm using a vim as my code editor and do not want to use IDE.
What is the best way to achieve that goal?
You need to use some of Building tools. It's allow you type small command (in vim you need just type :make) which launch build process with predetermined parameters (includes, libs, etc).
For C++ in Linux the most common tools are:
- make;
- automake;
- CMake.
If you use Qt also qmake is available.
I've had experience with all of them and my suggestion is use plain make for small projects and CMake for others and don't use autotools while you don't have to do it.
Note: All hight-level tools just help generate appropriate files (Makefile) for plain make (CMake generate Makefile based on CMakeLists.txt, automake based on Makefile.am, qmake based on *.pro).
because I don't want to type these things every time I launch the
compiler on command line.
I don't like to type either. All I want to do for small builds is issue:
(1) a short alias (2) the name of the file to compile, and (3) an output file.
Then I want my tool to take care of all common options, and if necessary, include the paths to any extra -I include directories, -L library directories and form the command line for me.
I have a short script that can handle the drudgery. Separating your projects into separate directories and including a 'bldflags' file with specific options allows the scripts to load any project specific options you may require. It is flexible enough to take any additional options specified on the command line. Alias the script in your .bashrc, and all that is required for quick builds is:
g+ filename.cpp outname
Now this is a very basic script and is not intented to replace proper build tools for your projects, but for quick compilations, it, or something like it, will sure cut down on the typing required. Here is the short script:
#!/bin/bash
## validate input
test -n "$1" && test -n "$2"|| { echo "insufficient input. usage: ${0//*\//} source.cpp out [options]"; exit 1; }
## set standard build flags and test if exists/source ./bldflags
stdclfags="-Wall" # add any standard flags you use.
test -r ./bldflags && bldflags="`<./bldflags`"
## show build command and call g++
echo -e "building $1 with:\n g++ $stdclfags -o $2 $1 $bldflags ${#:3}"
g++ $stdclfags -o "$2" "$1" $bldflags ${#:3}
exit 0
Make the script executable and include a simple alias in your .bashrc giving it any name you like:
alias g+='/home/david/scr/utl/bgc++.sh'
Examples of basic use: (basic without additional flags or a ./bldflags file)
$ g+ input.cpp output
building input.cpp with:
g++ -Wall -o output input.cpp
With a few extra options added on the command line:
$ g+ input.cpp output -Wunused -fno-default-inline
building input.cpp with:
g++ -Wall -o output input.cpp -Wunused -fno-default-inline
Including project specific options in ./bldflags (e.g: -I/home/david/inc -L/home/david/lib -Wl,-rpath=/home/david/lib
g+ input.cpp output -Wunused -fno-default-inline
building input.cpp with:
g++ -Wall -o output input.cpp -I/home/david/inc -L/home/david/lib -Wl,-rpath=/home/david/lib -Wunused -fno-default-inline
So to address the I don't want to type these things every time I launch the
compiler on command line, this is a very quick and easy way I've found to cut the typing down to a minimum for quick/repetitive builds where a full Makefile isn't needed.