kofhearts
kofhearts

Reputation: 3794

how to compile multiple cpp files with main methods at once?

For the sake of example i have 10 cpp files with main method.

a.cpp 
b.cpp 
c.cpp 
d.cpp 
e.cpp 

f.cpp 
g.cpp 
h.cpp 
i.cpp 
j.cpp 

All these scripts do different things so they have their own main method.

I have been compiling them one by one

for example

g++ -o a a.cpp

My question is is there a way to compile all cpp files and produce 10 different executables with the same name as the source file.

For example

a.cpp should produce executable a b.cpp should produce executable b

There are more than 50 cpp files so it should produce 50 executables. Is there a way of doing this maybe using a loop?

I appreciate any guidance.

Thanks!

Upvotes: 0

Views: 1189

Answers (3)

user3359240
user3359240

Reputation: 1

you can create file abcde.cpp and like this.

#include "a.cpp"
#include "b.cpp"
#include "c.cpp"
#include "d.cpp"
#include "e.cpp"

you can compile abcde.cpp at once.

Upvotes: -1

RARE Kpop Manifesto
RARE Kpop Manifesto

Reputation: 2915

simply call awk only once, batch process the file names found, including shell-safe single-quotation of them :

gfind -L . -iname "*.cpp" -type f -not -empty -print0 \
\
 | mawk 'function escQ(_,__) {
                         __="\47"
                    gsub(__,"&\\\\&&",_) return (__)(_)__ 
     
   } sub(".+","g++ +o "escQ($(NF-1))" "escQ($+_)" ")' RS='\0' FS='^.*/|[.]cpp$'


g++ +o 'jmp' './jmp.cpp' 
g++ +o 'printf' './printf.cpp' 
g++ +o 'memory' './memory.cpp' 
g++ +o 'fcall' './fcall.cpp' 
g++ +o 're_cmpl' './re_cmpl.cpp' 
g++ +o 'print' './print.cpp' 
g++ +o 'array' './array.cpp' 
g++ +o 'cast' './cast.cpp' 
g++ +o 'init' './init.cpp' 
g++ +o 'files' './files.cpp' 
g++ +o 'execute' './execute.cpp' 
g++ +o 'fin' './fin.cpp' 
g++ +o 'scancode' './scancode.cpp' 
g++ +o 'scan' './scan.cpp' 
g++ +o 'split' './split.cpp' 
g++ +o 'makescan' './makescan.cpp' 
g++ +o 'bi_funct' './bi_funct.cpp' 
g++ +o 'hash' './hash.cpp' 
g++ +o 'rexp2' './rexp/rexp2.cpp' 
g++ +o 'rexpdb' './rexp/rexpdb.cpp' 
g++ +o 'rexp1' './rexp/rexp1.cpp' 
g++ +o 'rexp0' './rexp/rexp0.cpp' 
g++ +o 'rexp3' './rexp/rexp3.cpp' 
g++ +o 'wait' './rexp/wait.cpp' 
g++ +o 'rexp' './rexp/rexp.cpp' 
g++ +o 'bi_vars' './bi_vars.cpp' 
g++ +o 'da' './da.cpp' 
g++ +o 'main' './main.cpp' 
g++ +o 'error' './error.cpp' 
g++ +o 'version' './version.cpp' 
g++ +o 'kw' './kw.cpp' 
g++ +o 'parse' './parse.cpp' 
g++ +o 'field' './field.cpp' 
g++ +o 'zmalloc' './zmalloc.cpp' 
g++ +o 'code' './code.cpp' 
g++ +o 'int' './int.cpp'

now you can even more easily parallelize these jobs (if that's something that works for your use case). That said, this solution doesn't have any handling of duplicate file-names from sub-folders - adjust it accordingly to your needs, including where you want the output locations of the compiled binary objects.

Upvotes: 0

Wilk Maia
Wilk Maia

Reputation: 137

I'll start by stating I don't believe this question's tags are not exactly related to the problem at hand. The compilation one is the closest one but, even though, I consider the question to be more related to specific environment file selection and string manipulation than anything else.

Nonetheless there are several ways of doing it. It mostly comes down to the system in which you want to compile these files and the compilation environment, if any.

Basic options will involve Makefiles, Shell Scripting, for Linux environments, Batch Files and PowerShell for Windows environments, and so on.

Given the way the question was formulated I'll assume you're on a Linux system using Bash. A simple solution for that would involve a few commonly-distributed tools (you can find out more about each of them on their man pages):

  • for
  • echo
  • awk

Assuming you're running the commands in the same folder the source files are located, the following line should do the trick for you:

for f in *.cpp; do g++ -o $(echo $f | awk -F.cpp '{printf "%s", $1}') $f; done

What the line above is doing is:

  • for f in *.cpp - iterates over all files in the current directory that match the provided wildcard. On each iteration the file name is stored at the $f variable
  • echo $f | awk -F.cpp '{printf "%s", $1}' - this snippet removes the .cpp extension from the file name we've got

Edit note: the proposed solution was improved by removing the parsing over ls -l's result because of @clcto's reference in this answer's comments.

Upvotes: 1

Related Questions