put OBJ files in subdirectory in MAKEFILE












0















my basic Makefile create the .o without the need of writing a line with gcc :



NAME = libtest.h
CC = gcc
CFLAGS = -I. -c
SRCS = example01.c
example02.c
OBJ = $(SRCS:.c=.o)

all: $(NAME)
$(NAME): $(OBJ)
ar -rc $@ $<


I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $< because i didn't need to call for the compiler explicitly ?



But then when I try to do the same with the add of a subdirectory in wich goes the OBJ files it doesn't work :



NAME = libtest.h
CC = gcc
CFLAGS = -I. -c
SRCS = example01.c
example02.c
ODIR = ./builds
OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))

all: $(NAME)
$(NAME): $(OBJ)
ar -rc $@ $<


The subdirectory already exist in this example of course. The error output is : No rule to make target 'builds/example01.o', needed by 'libtest.a'
I saw solutions that both explicitly call the compiler and have the rule $(SRCS:.c=.o) but i feel like it calls for the compiler two times with no need then ?










share|improve this question



























    0















    my basic Makefile create the .o without the need of writing a line with gcc :



    NAME = libtest.h
    CC = gcc
    CFLAGS = -I. -c
    SRCS = example01.c
    example02.c
    OBJ = $(SRCS:.c=.o)

    all: $(NAME)
    $(NAME): $(OBJ)
    ar -rc $@ $<


    I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $< because i didn't need to call for the compiler explicitly ?



    But then when I try to do the same with the add of a subdirectory in wich goes the OBJ files it doesn't work :



    NAME = libtest.h
    CC = gcc
    CFLAGS = -I. -c
    SRCS = example01.c
    example02.c
    ODIR = ./builds
    OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))

    all: $(NAME)
    $(NAME): $(OBJ)
    ar -rc $@ $<


    The subdirectory already exist in this example of course. The error output is : No rule to make target 'builds/example01.o', needed by 'libtest.a'
    I saw solutions that both explicitly call the compiler and have the rule $(SRCS:.c=.o) but i feel like it calls for the compiler two times with no need then ?










    share|improve this question

























      0












      0








      0








      my basic Makefile create the .o without the need of writing a line with gcc :



      NAME = libtest.h
      CC = gcc
      CFLAGS = -I. -c
      SRCS = example01.c
      example02.c
      OBJ = $(SRCS:.c=.o)

      all: $(NAME)
      $(NAME): $(OBJ)
      ar -rc $@ $<


      I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $< because i didn't need to call for the compiler explicitly ?



      But then when I try to do the same with the add of a subdirectory in wich goes the OBJ files it doesn't work :



      NAME = libtest.h
      CC = gcc
      CFLAGS = -I. -c
      SRCS = example01.c
      example02.c
      ODIR = ./builds
      OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))

      all: $(NAME)
      $(NAME): $(OBJ)
      ar -rc $@ $<


      The subdirectory already exist in this example of course. The error output is : No rule to make target 'builds/example01.o', needed by 'libtest.a'
      I saw solutions that both explicitly call the compiler and have the rule $(SRCS:.c=.o) but i feel like it calls for the compiler two times with no need then ?










      share|improve this question














      my basic Makefile create the .o without the need of writing a line with gcc :



      NAME = libtest.h
      CC = gcc
      CFLAGS = -I. -c
      SRCS = example01.c
      example02.c
      OBJ = $(SRCS:.c=.o)

      all: $(NAME)
      $(NAME): $(OBJ)
      ar -rc $@ $<


      I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $< because i didn't need to call for the compiler explicitly ?



      But then when I try to do the same with the add of a subdirectory in wich goes the OBJ files it doesn't work :



      NAME = libtest.h
      CC = gcc
      CFLAGS = -I. -c
      SRCS = example01.c
      example02.c
      ODIR = ./builds
      OBJ = $(addprefix $(ODIR)/, $(SRCS:.c=.o))

      all: $(NAME)
      $(NAME): $(OBJ)
      ar -rc $@ $<


      The subdirectory already exist in this example of course. The error output is : No rule to make target 'builds/example01.o', needed by 'libtest.a'
      I saw solutions that both explicitly call the compiler and have the rule $(SRCS:.c=.o) but i feel like it calls for the compiler two times with no need then ?







      makefile gnu-make






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 '18 at 17:43









      hugogogohugogogo

      438




      438
























          1 Answer
          1






          active

          oldest

          votes


















          1














          This:




          I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<




          is not quite right. Make has a suite of built-in pattern rules it can apply if you don't define your own rule. One of these tells it how to build a foo.o file from a foo.c file.



          But make has no built-in rule telling it how to build a ./builds/foo.o file from a foo.c file, so you have to supply that yourself:



          $(ODIR)/%.o : %.c
          $(COMPILE.c) -o $@ $<


          (this uses a built-in variable COMPILE.c which is what the built-in rule uses; of course you can define your own).






          share|improve this answer
























          • perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

            – hugogogo
            Nov 21 '18 at 22:13











          • It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

            – MadScientist
            Nov 21 '18 at 23:46











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417824%2fput-obj-files-in-subdirectory-in-makefile%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          This:




          I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<




          is not quite right. Make has a suite of built-in pattern rules it can apply if you don't define your own rule. One of these tells it how to build a foo.o file from a foo.c file.



          But make has no built-in rule telling it how to build a ./builds/foo.o file from a foo.c file, so you have to supply that yourself:



          $(ODIR)/%.o : %.c
          $(COMPILE.c) -o $@ $<


          (this uses a built-in variable COMPILE.c which is what the built-in rule uses; of course you can define your own).






          share|improve this answer
























          • perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

            – hugogogo
            Nov 21 '18 at 22:13











          • It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

            – MadScientist
            Nov 21 '18 at 23:46
















          1














          This:




          I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<




          is not quite right. Make has a suite of built-in pattern rules it can apply if you don't define your own rule. One of these tells it how to build a foo.o file from a foo.c file.



          But make has no built-in rule telling it how to build a ./builds/foo.o file from a foo.c file, so you have to supply that yourself:



          $(ODIR)/%.o : %.c
          $(COMPILE.c) -o $@ $<


          (this uses a built-in variable COMPILE.c which is what the built-in rule uses; of course you can define your own).






          share|improve this answer
























          • perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

            – hugogogo
            Nov 21 '18 at 22:13











          • It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

            – MadScientist
            Nov 21 '18 at 23:46














          1












          1








          1







          This:




          I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<




          is not quite right. Make has a suite of built-in pattern rules it can apply if you don't define your own rule. One of these tells it how to build a foo.o file from a foo.c file.



          But make has no built-in rule telling it how to build a ./builds/foo.o file from a foo.c file, so you have to supply that yourself:



          $(ODIR)/%.o : %.c
          $(COMPILE.c) -o $@ $<


          (this uses a built-in variable COMPILE.c which is what the built-in rule uses; of course you can define your own).






          share|improve this answer













          This:




          I suppose that the rule $(SRCS:.c=.o) is making an equivalent as running $(CC) $(CFLAGS) -o $@ $<




          is not quite right. Make has a suite of built-in pattern rules it can apply if you don't define your own rule. One of these tells it how to build a foo.o file from a foo.c file.



          But make has no built-in rule telling it how to build a ./builds/foo.o file from a foo.c file, so you have to supply that yourself:



          $(ODIR)/%.o : %.c
          $(COMPILE.c) -o $@ $<


          (this uses a built-in variable COMPILE.c which is what the built-in rule uses; of course you can define your own).







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '18 at 18:13









          MadScientistMadScientist

          46.8k55267




          46.8k55267













          • perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

            – hugogogo
            Nov 21 '18 at 22:13











          • It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

            – MadScientist
            Nov 21 '18 at 23:46



















          • perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

            – hugogogo
            Nov 21 '18 at 22:13











          • It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

            – MadScientist
            Nov 21 '18 at 23:46

















          perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

          – hugogogo
          Nov 21 '18 at 22:13





          perfect ! little precision : thanks to COMPILE.c I don't need to put the -c option in CFLAGS (for what i got), because COMPILE.c already compile with -c

          – hugogogo
          Nov 21 '18 at 22:13













          It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

          – MadScientist
          Nov 21 '18 at 23:46





          It's something of an anti-pattern to put -c into CFLAGS, because CFLAGS can be used in places where you don't want to generate an object file. For example, it's common to include CFLAGS on the linker line as well to get all the same optimization, warning, threading, C standard selection, etc. at link time as you do compile time.

          – MadScientist
          Nov 21 '18 at 23:46




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417824%2fput-obj-files-in-subdirectory-in-makefile%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith