1

Suppose I have a folder structure as such:

|
| - src
    |- file.c
    |- folderOne
        |- file2.c
        |- file3.S
    |- folderTwo
        |-folderThree
            |- file4.c

I currently have a makefile that will grab all my assembly and C files like so:

S_SRC  = $(wildcard *.S) $(wildcard **/*.S)
C_SRC  = $(wildcard *.c) $(wildcard **/*.c)

S_OBJS = $(patsubst %.S,%.o,$(filter %.S,$(S_SRC)))
C_OBJS = $(patsubst %.c,%.o,$(filter %.c,$(C_SRC)))

OBJS   = $(S_OBJS) $(C_OBJS)

Those lines simply get all the .c and .S files, and also creates their equivalent .o values. My pipeline is running GCC on the source files and then manually linking them.

I run GCC with the following syntax:

$(OBJS): $(C_SRC) $(S_SRC)
    $(CC) $(CC_F) $(S_SRC) $(C_SRC) -o $(OBJS)

Where I pass in my source files to GCC. The CC_F variable is my flags variable:

CC_F   = -m32 -Wall -Wextra -Werror -g -c

And I would like to run my linker like this afterwards:

$(PROGR): $(OBJS) $(LINK_SRC)
    $(LD) $(LD_F) -o $(PROGR) $(OBJS)

Again, LD_F are simply my linker flags.

The problem I am currently getting is that with more than once source file, GCC cannot parse the command, outputting something like:

gcc -m32 -Wall -Wextra -Werror -g -c  src/file1.S  src/file2.c -o src/file1.o src/file2.o
gcc: error: src/file2.o: No such file or directory

What I would like to be able to do is have GCC output the object files of each source file in the same directory as the source file. In the given example, running the makefile should result in this layout:

|
| - src
    |- file.c
    |- file.o
    |- folderOne
        |- file2.c
        |- file2.o
        |- file3.S
        |- file3.o
    |- folderTwo
        |-folderThree
            |- file4.c
            |- file4.o

How is this possible with my current setup and perhaps a varying number of directories/files.

2
  • You cannot have multiple output files. The file src/file2.o is treated as a source object but didn't exist. Change your Makefile to compile one source and output one object at a time. Commented Mar 24, 2017 at 1:48
  • @alvits Could you show me how to this? Commented Mar 24, 2017 at 2:05

1 Answer 1

1

gcc does not allow multiple output files in one invocation. You will need to run gcc as many times as the number of object files you need to create.

One object file may contain 1 or more compiled source.

You need to remove this block from your Makefile:

$(OBJS): $(C_SRC) $(S_SRC)
    $(CC) $(CC_F) $(S_SRC) $(C_SRC) -o $(OBJS)

Assuming you want 1 object file for each source file, replace it with:

**/%.o: **/%.c
    $(CC) $(CC_F) -c -o $@ $<

This will create the object file in the same directory as the source file recursing through the directories.

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

4 Comments

One caveat to your solution is this: suppose I have a unknown number of directories, how would make handle this then?
If you have arbitrary number of folders, how would you know which object files to link together to make an executable program? This is where autoconf and automake comes in handy. You need to delete your question and ask specifically for automake and autoconf features. This answer is meant for your original post. Don't change the question after you got an answer.
I know exactly which object files to link together because I can grab the source file names from an arbitrary number of directories and arbitrary number of files and convert those all to a .o extension while maintaining paths to each file with the willdcards I have. All I need to do after generating the object files is pass them to my linker, thus before GCC touches any of these, I know where they all are.
@Tanishqdubey - I updated my answer to compile the sources recursively when needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.