0

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!

3
  • 3
    this isnt so much about c++. You want a bash script or a makefile or other build tools that can do this out of the box Commented Apr 14, 2022 at 13:27
  • 3
    Some notes about terminology. C++ source code files are not scripts (because C++ is not a scripting language, it is a compiled language). Also, main() is not a method, it is a free (i.e., non-member) function. Commented Apr 14, 2022 at 13:29
  • Simple answer: make -k a b c d e f g h i j. Or write a short makefile that depends on $(patsubst *.cpp,%,$(wildcard *.cpp)). Commented Sep 15, 2023 at 13:53

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Interesting reading. But as far as I can tell that's pretty much an issue with parsing ls? ls -l shouldn't fall into that category, correct? In any case, thanks for sharing, @clcto, I wasn't aware of that specific pitfall.
No, try it and see. Create a filename with a newline or other unexpected characters. Even a space breaks your awk call: mkdir test && cd test && touch "a b.cpp" && ls -l | grep .cpp | awk '{print $9}' ==> a
Once more thanks, @clcto. I've updated the proposed solution to remove ls altogether and, instead, iterate over the folder's files.
awk is being used there to filter out the .cpp extension. You can check it’s man page, specifically the -F flag and the FIELDS section for more clarification. In a very abstract manner you could think of that as splitting the string by the “.cpp” substring (mind it’s regex matching) and taking (that’s print’s job) the first element as the result.
|
0

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.

Comments

-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.

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
This is blatantly wrong. If each source file is a full program, then attempting to compile them into a single translation unit could never succeed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.