Search code examples
makefilegnu-makegnu

How to skip one of the dependency file to not include while creating target library


I want to create a library skipping one of the dependency file not to include while creating the same.

Eg:-

liba.so: a.o b.o c.o test.psm
        <command for creating liba.so, which includes all its dependencies.> 

Here when there is a change is any of its dependencies i have to create liba.so file. But .so file should include only .o files and not test.psm file.

It will throw the error when we try to create .so file with non-object file.

Please help me how can we achieve this using GNUmake.


Solution

  • The best way to solve the problem is to avoid it. I see absolutely no reason to rebuild a library that exists already and whose prerequisites have not changed since it was last built. If for some bizarre reason one wants to ensure that the library's timestamp is not earlier than that of some associated documentation file, then the best alternatives would run along the lines of creating a separate process around maintaining or distributing that file. For example,

    • touch a corresponding source file whenever the documentation file is changed; or
    • build the documentation from the corresponding source, such as via a Doxygen or a similar tool, so that it is a built artifact that shares the same prerequisites as the library; or
    • manage timestamps as part of the installation / distribution process instead of the build process. For instance, make a copy, without timestamp preservation, before installing or distributing the built files, so that all the files in the copy are timestamped as of the copying.

    But if you must obey the dictates of a pointy-haired boss who will not accept pushback, then the answer to the actual question is that make does not have any special variable or operator for designating subsets of rules' prerequisite lists, but you nevertheless have plenty of options for writing the recipe appropriately. This then becomes about the details of of the rule's recipe.

    If one starts with

    liba.so: a.o b.o c.o
            $(archiver_command) $(archiver_options) a.o b.o c.o
    

    then one can add test.psm to the prerequisite list without any other changes.

    Suppose one starts with a rule of this form, however:

    liba.so: a.o b.o c.o
            $(archiver_command) $(archiver_options) $^
    

    . The recipe uses the automatic variable $^ to refer to the (whole) list of prerequisites, so if one adds test.psm as a new prerequisite then it would be included, too, which you do not want. You have multiple options here, among them

    • Use shell code in the recipe to process the prerequisite list and remove the last element. This is a bit nasty.
    • Rewrite the recipe in the previous form, with an explicit list of objects in the recipe instead of a variable. This carries an added maintenance burden, however.
    • Designate the real prerequisites via a user-defined variable, and use that in the recipe, too. This may be particularly natural in view of the fact that it is common for there already to be just such a variable.

    The last alternative would be my recommendation. Specifically, it would look something like this:

    A_OBJS = a.o b.o c.o
    
    # ...
    
    liba.so: $(A_OBJS) test.psm
            $(archiver_command) $(archiver_options) $(A_OBJS)