Makefile: how to declare a dependency for all targets that match a pattern?when multiple pattern rules match a targetmakefile pattern rules without recipesMakefile adds itself as targetRelink Makefile target when list of dependencies changesHow to makefile parseMakefile static rule syntax explainationAlternatives to pattern rules with .PHONY targets in a makefile?Is the first target in Makefile an implicit phony target?Makefile pattern rule with multiple targetsAdding a dependency to all uses of an implicit rulePattern rule for prerequisite regardless of targetMakefile : last resort match anything pattern

How could a sequence of random dates be generated, given year interval?

A partially ugly group with a casual secret

How to apply a macro for every single matching pattern

Is there any algorithm that runs faster in Mathematica than in C or Fortran?

What is more proper notation in piano sheet music to denote that the left hand should be louder?

Why are bagpipes tuned using just intonation?

Can I take the high-speed bullet train Beijing–Hong Kong under Chinese 144 h visa-free transit rules?

Should I do a regression analysis even if the variables do not seem to be associated at all?

Remove vertical space in gather enviroment

Is CR12 too difficult for two level 4 characters?

Novel in which space traders train a spearman army for a decaying medieval empire

More elegant way to express ((x == a and y == b) or (x == b and y == a))?

Intuition behind the paradox of instantaneous heat propagation

Modeling the Choose function

What's a good strategy for offering low on a house?

Why do microwaves use magnetron?

Tips for attracting more math majors in a liberal arts college mathematics department

Noise reduction using multiple recordings of the same signal

How to formulate a MIP that can minimize the costs with a combination of subsets given a set?

Why is Eastern Switzerland called Suisse orientale in French?

Novel about a woman who is transformed into an elf

How do I figure out how many hydrogens my compound actually has using a mass and NMR spectrum?

Why is Iceland Air's Saga Premium product classified as Business class?

How does AT-AT deploy troops?



Makefile: how to declare a dependency for all targets that match a pattern?


when multiple pattern rules match a targetmakefile pattern rules without recipesMakefile adds itself as targetRelink Makefile target when list of dependencies changesHow to makefile parseMakefile static rule syntax explainationAlternatives to pattern rules with .PHONY targets in a makefile?Is the first target in Makefile an implicit phony target?Makefile pattern rule with multiple targetsAdding a dependency to all uses of an implicit rulePattern rule for prerequisite regardless of targetMakefile : last resort match anything pattern






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









2

















Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:



static/app.mjs: js2/.legacy_app.built.mjs
static/admin_unit.mjs: js2/.legacy_admin.built.mjs
static/admin_source.mjs: js2/.legacy_admin.built.mjs
static/admin_module.mjs: js2/.legacy_admin.built.mjs


But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:



static/app.mjs: js2/.legacy_app.built.mjs
static/admin_%.mjs: js2/.legacy_admin.built.mjs


But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:




Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule




Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?










share|improve this question


































    2

















    Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:



    static/app.mjs: js2/.legacy_app.built.mjs
    static/admin_unit.mjs: js2/.legacy_admin.built.mjs
    static/admin_source.mjs: js2/.legacy_admin.built.mjs
    static/admin_module.mjs: js2/.legacy_admin.built.mjs


    But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:



    static/app.mjs: js2/.legacy_app.built.mjs
    static/admin_%.mjs: js2/.legacy_admin.built.mjs


    But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:




    Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule




    Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?










    share|improve this question






























      2












      2








      2


      0






      Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:



      static/app.mjs: js2/.legacy_app.built.mjs
      static/admin_unit.mjs: js2/.legacy_admin.built.mjs
      static/admin_source.mjs: js2/.legacy_admin.built.mjs
      static/admin_module.mjs: js2/.legacy_admin.built.mjs


      But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:



      static/app.mjs: js2/.legacy_app.built.mjs
      static/admin_%.mjs: js2/.legacy_admin.built.mjs


      But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:




      Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule




      Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?










      share|improve this question

















      Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:



      static/app.mjs: js2/.legacy_app.built.mjs
      static/admin_unit.mjs: js2/.legacy_admin.built.mjs
      static/admin_source.mjs: js2/.legacy_admin.built.mjs
      static/admin_module.mjs: js2/.legacy_admin.built.mjs


      But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:



      static/app.mjs: js2/.legacy_app.built.mjs
      static/admin_%.mjs: js2/.legacy_admin.built.mjs


      But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:




      Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule




      Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?







      makefile






      share|improve this question
















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 29 at 7:45









      Tsyvarev

      32k5 gold badges37 silver badges73 bronze badges




      32k5 gold badges37 silver badges73 bronze badges










      asked Mar 28 at 21:37









      natevwnatevw

      10.2k5 gold badges52 silver badges71 bronze badges




      10.2k5 gold badges52 silver badges71 bronze badges

























          3 Answers
          3






          active

          oldest

          votes


















          1


















          As you know, a pattern rule like:



          static/admin_%.mjs: js2/.legacy_admin.built.mjs
          recipe...


          does not specify any targets, just a template for discovering
          the prerequisites of targets that you specify otherwise,
          with a recipe for making those targets from the prerequisites.



          So there has to be something else in your makefile that determines
          what the targets are. Let's suppose it is just a list as in:



          $ cat Makefile
          MJS_STEMS := app admin_unit admin_source admin_module
          MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

          .PHONY: all clean
          all: $(MJS_FILES)

          $(MJS_FILES): js2/.legacy_admin.built.mjs

          static/%.mjs: | static
          @echo $< > $@
          @echo "$@ depends on $<"

          js2/.legacy_admin.built.mjs: | js2
          touch $@

          static js2:
          mkdir -p $@

          clean:
          $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


          Here,



          $(MJS_FILES): js2/.legacy_admin.built.mjs


          says that each of $(MJS_FILES) depends on js2/.legacy_admin.built.mjs.
          That's the most concise way to do it without a pattern rule. The make runs like:



          $ make
          mkdir -p static
          mkdir -p js2
          touch js2/.legacy_admin.built.mjs
          static/app.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_module.mjs depends on js2/.legacy_admin.built.mjs


          If you want you can move the maintenance of the MJS_STEMS list out of the
          makefile into another file:



          $ cat ./mjs_stems
          app
          admin_unit
          admin_source
          admin_module

          $ cat Makefile
          MJS_STEMS := $(shell cat ./mjs_stems)
          MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

          .PHONY: all clean
          all: $(MJS_FILES)

          $(MJS_FILES): js2/.legacy_admin.built.mjs

          static/%.mjs: | static
          @echo $< > $@
          @echo "$@ depends on $<"

          js2/.legacy_admin.built.mjs: | js2
          touch $@

          static js2:
          mkdir -p $@

          clean:
          $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


          $ make clean
          rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs

          $ echo "admin_foobar" >> mjs_stems
          $ make
          touch js2/.legacy_admin.built.mjs
          static/app.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs


          Or you can just get the MJS_STEMS list from the environment:



          $ cat Makefile
          MJS_STEMS := $(strip $(MJS_STEMS))
          MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

          .PHONY: all clean
          all: $(MJS_FILES)

          $(MJS_FILES): js2/.legacy_admin.built.mjs

          static/%.mjs: | static
          @echo $< > $@
          @echo "$@ depends on $<"

          js2/.legacy_admin.built.mjs: | js2
          touch $@

          static js2:
          mkdir -p $@

          clean:
          $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


          $ make clean
          rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

          $ export MJS_STEMS=$(cat ./mjs_stems)
          $ make
          touch js2/.legacy_admin.built.mjs
          static/app.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
          static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs

          $ make clean
          rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

          $ export MJS_STEMS="aa bb cc"
          $ make
          touch js2/.legacy_admin.built.mjs
          static/aa.mjs depends on js2/.legacy_admin.built.mjs
          static/bb.mjs depends on js2/.legacy_admin.built.mjs
          static/cc.mjs depends on js2/.legacy_admin.built.mjs

          $ make clean
          rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs


          But one way or another, somewhere, you have to specify the list of targets, and
          to add new targets you have to update something.






          share|improve this answer




























          • Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

            – natevw
            Apr 1 at 16:07


















          1


















          If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...):



          $(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs





          share|improve this answer


























          • Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

            – natevw
            Apr 1 at 15:56











          • Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

            – natevw
            Apr 1 at 15:58


















          0


















          I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.



          Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:



          .PHONY: ADMIN
          ADMIN: js2/.legacy_admin.built.mjs

          static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
          node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@

          # …also contains recipe to build "js2/.legacy_admin.built.mjs" itself



          Now before any static/admin_%.mjs file is built, make ensures that the common js2/.legacy_admin.built.mjs helper file has been created.



          (See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)






          share|improve this answer





























            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/4.0/"u003ecc by-sa 4.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%2f55407224%2fmakefile-how-to-declare-a-dependency-for-all-targets-that-match-a-pattern%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown


























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1


















            As you know, a pattern rule like:



            static/admin_%.mjs: js2/.legacy_admin.built.mjs
            recipe...


            does not specify any targets, just a template for discovering
            the prerequisites of targets that you specify otherwise,
            with a recipe for making those targets from the prerequisites.



            So there has to be something else in your makefile that determines
            what the targets are. Let's suppose it is just a list as in:



            $ cat Makefile
            MJS_STEMS := app admin_unit admin_source admin_module
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            Here,



            $(MJS_FILES): js2/.legacy_admin.built.mjs


            says that each of $(MJS_FILES) depends on js2/.legacy_admin.built.mjs.
            That's the most concise way to do it without a pattern rule. The make runs like:



            $ make
            mkdir -p static
            mkdir -p js2
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs


            If you want you can move the maintenance of the MJS_STEMS list out of the
            makefile into another file:



            $ cat ./mjs_stems
            app
            admin_unit
            admin_source
            admin_module

            $ cat Makefile
            MJS_STEMS := $(shell cat ./mjs_stems)
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs

            $ echo "admin_foobar" >> mjs_stems
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs


            Or you can just get the MJS_STEMS list from the environment:



            $ cat Makefile
            MJS_STEMS := $(strip $(MJS_STEMS))
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS=$(cat ./mjs_stems)
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS="aa bb cc"
            $ make
            touch js2/.legacy_admin.built.mjs
            static/aa.mjs depends on js2/.legacy_admin.built.mjs
            static/bb.mjs depends on js2/.legacy_admin.built.mjs
            static/cc.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs


            But one way or another, somewhere, you have to specify the list of targets, and
            to add new targets you have to update something.






            share|improve this answer




























            • Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

              – natevw
              Apr 1 at 16:07















            1


















            As you know, a pattern rule like:



            static/admin_%.mjs: js2/.legacy_admin.built.mjs
            recipe...


            does not specify any targets, just a template for discovering
            the prerequisites of targets that you specify otherwise,
            with a recipe for making those targets from the prerequisites.



            So there has to be something else in your makefile that determines
            what the targets are. Let's suppose it is just a list as in:



            $ cat Makefile
            MJS_STEMS := app admin_unit admin_source admin_module
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            Here,



            $(MJS_FILES): js2/.legacy_admin.built.mjs


            says that each of $(MJS_FILES) depends on js2/.legacy_admin.built.mjs.
            That's the most concise way to do it without a pattern rule. The make runs like:



            $ make
            mkdir -p static
            mkdir -p js2
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs


            If you want you can move the maintenance of the MJS_STEMS list out of the
            makefile into another file:



            $ cat ./mjs_stems
            app
            admin_unit
            admin_source
            admin_module

            $ cat Makefile
            MJS_STEMS := $(shell cat ./mjs_stems)
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs

            $ echo "admin_foobar" >> mjs_stems
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs


            Or you can just get the MJS_STEMS list from the environment:



            $ cat Makefile
            MJS_STEMS := $(strip $(MJS_STEMS))
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS=$(cat ./mjs_stems)
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS="aa bb cc"
            $ make
            touch js2/.legacy_admin.built.mjs
            static/aa.mjs depends on js2/.legacy_admin.built.mjs
            static/bb.mjs depends on js2/.legacy_admin.built.mjs
            static/cc.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs


            But one way or another, somewhere, you have to specify the list of targets, and
            to add new targets you have to update something.






            share|improve this answer




























            • Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

              – natevw
              Apr 1 at 16:07













            1














            1










            1









            As you know, a pattern rule like:



            static/admin_%.mjs: js2/.legacy_admin.built.mjs
            recipe...


            does not specify any targets, just a template for discovering
            the prerequisites of targets that you specify otherwise,
            with a recipe for making those targets from the prerequisites.



            So there has to be something else in your makefile that determines
            what the targets are. Let's suppose it is just a list as in:



            $ cat Makefile
            MJS_STEMS := app admin_unit admin_source admin_module
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            Here,



            $(MJS_FILES): js2/.legacy_admin.built.mjs


            says that each of $(MJS_FILES) depends on js2/.legacy_admin.built.mjs.
            That's the most concise way to do it without a pattern rule. The make runs like:



            $ make
            mkdir -p static
            mkdir -p js2
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs


            If you want you can move the maintenance of the MJS_STEMS list out of the
            makefile into another file:



            $ cat ./mjs_stems
            app
            admin_unit
            admin_source
            admin_module

            $ cat Makefile
            MJS_STEMS := $(shell cat ./mjs_stems)
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs

            $ echo "admin_foobar" >> mjs_stems
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs


            Or you can just get the MJS_STEMS list from the environment:



            $ cat Makefile
            MJS_STEMS := $(strip $(MJS_STEMS))
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS=$(cat ./mjs_stems)
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS="aa bb cc"
            $ make
            touch js2/.legacy_admin.built.mjs
            static/aa.mjs depends on js2/.legacy_admin.built.mjs
            static/bb.mjs depends on js2/.legacy_admin.built.mjs
            static/cc.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs


            But one way or another, somewhere, you have to specify the list of targets, and
            to add new targets you have to update something.






            share|improve this answer
















            As you know, a pattern rule like:



            static/admin_%.mjs: js2/.legacy_admin.built.mjs
            recipe...


            does not specify any targets, just a template for discovering
            the prerequisites of targets that you specify otherwise,
            with a recipe for making those targets from the prerequisites.



            So there has to be something else in your makefile that determines
            what the targets are. Let's suppose it is just a list as in:



            $ cat Makefile
            MJS_STEMS := app admin_unit admin_source admin_module
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            Here,



            $(MJS_FILES): js2/.legacy_admin.built.mjs


            says that each of $(MJS_FILES) depends on js2/.legacy_admin.built.mjs.
            That's the most concise way to do it without a pattern rule. The make runs like:



            $ make
            mkdir -p static
            mkdir -p js2
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs


            If you want you can move the maintenance of the MJS_STEMS list out of the
            makefile into another file:



            $ cat ./mjs_stems
            app
            admin_unit
            admin_source
            admin_module

            $ cat Makefile
            MJS_STEMS := $(shell cat ./mjs_stems)
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs

            $ echo "admin_foobar" >> mjs_stems
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs


            Or you can just get the MJS_STEMS list from the environment:



            $ cat Makefile
            MJS_STEMS := $(strip $(MJS_STEMS))
            MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))

            .PHONY: all clean
            all: $(MJS_FILES)

            $(MJS_FILES): js2/.legacy_admin.built.mjs

            static/%.mjs: | static
            @echo $< > $@
            @echo "$@ depends on $<"

            js2/.legacy_admin.built.mjs: | js2
            touch $@

            static js2:
            mkdir -p $@

            clean:
            $(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs


            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS=$(cat ./mjs_stems)
            $ make
            touch js2/.legacy_admin.built.mjs
            static/app.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
            static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs

            $ export MJS_STEMS="aa bb cc"
            $ make
            touch js2/.legacy_admin.built.mjs
            static/aa.mjs depends on js2/.legacy_admin.built.mjs
            static/bb.mjs depends on js2/.legacy_admin.built.mjs
            static/cc.mjs depends on js2/.legacy_admin.built.mjs

            $ make clean
            rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs


            But one way or another, somewhere, you have to specify the list of targets, and
            to add new targets you have to update something.







            share|improve this answer















            share|improve this answer




            share|improve this answer








            edited Mar 29 at 16:14

























            answered Mar 29 at 12:12









            Mike KinghanMike Kinghan

            35.9k8 gold badges80 silver badges127 bronze badges




            35.9k8 gold badges80 silver badges127 bronze badges















            • Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

              – natevw
              Apr 1 at 16:07

















            • Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

              – natevw
              Apr 1 at 16:07
















            Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

            – natevw
            Apr 1 at 16:07





            Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via appfiles = $(shell ls -1 js2/*.build.mjs) and js2: $(appfiles:js2/%.build.mjs=static/%.mjs) [I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1/substitution tricks to generate a sub-list.

            – natevw
            Apr 1 at 16:07













            1


















            If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...):



            $(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs





            share|improve this answer


























            • Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

              – natevw
              Apr 1 at 15:56











            • Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

              – natevw
              Apr 1 at 15:58















            1


















            If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...):



            $(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs





            share|improve this answer


























            • Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

              – natevw
              Apr 1 at 15:56











            • Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

              – natevw
              Apr 1 at 15:58













            1














            1










            1









            If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...):



            $(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs





            share|improve this answer














            If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...):



            $(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs






            share|improve this answer













            share|improve this answer




            share|improve this answer










            answered Mar 29 at 6:02









            MattMatt

            5,8661 gold badge6 silver badges13 bronze badges




            5,8661 gold badge6 silver badges13 bronze badges















            • Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

              – natevw
              Apr 1 at 15:56











            • Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

              – natevw
              Apr 1 at 15:58

















            • Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

              – natevw
              Apr 1 at 15:56











            • Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

              – natevw
              Apr 1 at 15:58
















            Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

            – natevw
            Apr 1 at 15:56





            Unfortunately in my case the static/admin_*.mjs targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean.

            – natevw
            Apr 1 at 15:56













            Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

            – natevw
            Apr 1 at 15:58





            Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g. src/admin_*.build.mjs) so I can probably combine this with a substitution.

            – natevw
            Apr 1 at 15:58











            0


















            I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.



            Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:



            .PHONY: ADMIN
            ADMIN: js2/.legacy_admin.built.mjs

            static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
            node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@

            # …also contains recipe to build "js2/.legacy_admin.built.mjs" itself



            Now before any static/admin_%.mjs file is built, make ensures that the common js2/.legacy_admin.built.mjs helper file has been created.



            (See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)






            share|improve this answer
































              0


















              I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.



              Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:



              .PHONY: ADMIN
              ADMIN: js2/.legacy_admin.built.mjs

              static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
              node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@

              # …also contains recipe to build "js2/.legacy_admin.built.mjs" itself



              Now before any static/admin_%.mjs file is built, make ensures that the common js2/.legacy_admin.built.mjs helper file has been created.



              (See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)






              share|improve this answer






























                0














                0










                0









                I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.



                Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:



                .PHONY: ADMIN
                ADMIN: js2/.legacy_admin.built.mjs

                static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
                node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@

                # …also contains recipe to build "js2/.legacy_admin.built.mjs" itself



                Now before any static/admin_%.mjs file is built, make ensures that the common js2/.legacy_admin.built.mjs helper file has been created.



                (See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)






                share|improve this answer
















                I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.



                Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:



                .PHONY: ADMIN
                ADMIN: js2/.legacy_admin.built.mjs

                static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
                node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@

                # …also contains recipe to build "js2/.legacy_admin.built.mjs" itself



                Now before any static/admin_%.mjs file is built, make ensures that the common js2/.legacy_admin.built.mjs helper file has been created.



                (See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)







                share|improve this answer















                share|improve this answer




                share|improve this answer








                edited Sep 3 at 17:51

























                answered Sep 3 at 17:45









                natevwnatevw

                10.2k5 gold badges52 silver badges71 bronze badges




                10.2k5 gold badges52 silver badges71 bronze badges































                    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%2f55407224%2fmakefile-how-to-declare-a-dependency-for-all-targets-that-match-a-pattern%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

                    Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                    SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                    은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현