Menu

--no-warn still warns about stale files

Help
giksos
2009-10-09
2016-01-22
  • giksos

    giksos - 2009-10-09

    hi,

      the title says it all: if I call makepp with -no-warn, I still get very verbose warnings about stale files. Any way to get rid of those warnings?

     
  • Daniel Pfeiffer

    Daniel Pfeiffer - 2011-10-03

    Long since fixed.

     
  • Jeffrey Fuller

    Jeffrey Fuller - 2015-12-10

    Hi
    I'm having the same issue as the OP: I'm giving "--no-warn" to makepp, but still getting stale file warnings (note that I know why there are stale files, and am fine with the situation for now). Interstingly, I tried printing out MAKEFLAGS, and "--no-warn" doesn't show up.

    I should add that I can give the "-v" or "--verbose" option, and see that print from MAKEGLAGS (with "--version" printing as "-v"), so I know I'm printing MAKEFLAGS correctly.

    I noticed in the manpage for makepp installed on my system that the "no warn" flag is given as "--nowarn". So I tried that too, but with the same result: it doesn't appear to be in MAKEFLAGS, and it doesn't prevent stale file warnings.

    On the makepp website, the help for version 2 of makepp gives the "no warn" flag as "--no-warn", but the help for older versions (pre 2) list it as "-nowarn". So I checked my version of makepp with the "--version" option, and it says it's version 2.0.98.3. So I'm not sure what's going on with that.

    But regardless, neither format of the "no-warn" flag works for stale files, and it doesn't even seem to "stick", as it's not present in MAKEFLAGS.

    Thanks in advance for any help.

     
  • Jeffrey Fuller

    Jeffrey Fuller - 2015-12-10

    After reading some of the other topics on this forum, I thought I'd expand on my previous post, because I'm afraid based on some of the other things I read that my initial post may lead someone to think I'm using makepp in a way in which I'm not (to do recursive make).

    I use infer_objects to generate a list of all source files that need to be compiled.

    Let's say I've got a project with source code in multiple directories (all under a common parent dir, of course). Some of those directories contain code for executables, some just have library code. And then let's say I'm building in a sub directory that contains code for an executable, and that the code uses some of the code in some of the other library directories. infer_objects detects all of this fine, and builds the executable.

    After building, I can clean only the object files used to build that particular executable by invoking my clean rule, which in turn invokes makeppclean. If executed in the aforementioned sub directory, it only cleans items related to that executable.

    So recently, just for giggles, I tried to add a variable to our system that would allow the user to specify a single directory to put all object files generated from a build. So that all such files could be placed in the same directory to keep everything clean (especially if different versions of the code are built, e.g. release/debug, a different directory could be used for the object files). This variable is a directory path. I had to add the variable to the various rules I use, including the call to infer_objects. After doing this, I can build fine, and the objects go into the defined directory, but makeppclean wouldn't detect the object files anymore when running from the aforementioned sub directory (not surprising as it doesn't see them because it doesn't know about the directory they were written to). Note I can clean fine if I clean from the top-level directory, but that cleans everything.

    I tried to find a way to tell makeppclean about the directory with the object files, but couldn't (well, I could give it the top-level directory, but then it cleans everything, not just the files related to the executable).

    So then I decided to do this: My infer_objects call saves the results in a variable so it can be used in various rules. So I figured I could just give the variable to makeppclean as an argument, and it would clean only the files related to the executable. This works, but if make clean is run twice in row (i.e. after the executable and its object files have already been cleaned), just referencing the variable that holds the results of infer_objects seems to trigger a build of all the objects again (the infer objects variable is referenced in my compile rule, too). This happens even though the infer objects variable appears in no dependencies, including my clean rule (which has no dependencies).

    Here is some pseudo-code of my makefile system:

    $csInferedObjects = an infer_objects call that figures out all the object files needed by certain executable.

    %.o: %.cpp
    My compile rule that uses $(csInferedObjects)

    $(phony clean):
    @echo CLEANING WITH makeppclean -rv...
    @makeppclean -rv $(csInferedObjects)

    So csInferedObjects is the one that holds the results of infer_objects. I was a bit surprised to see it cause a build just for reading the variable in the clean rule, as I would have though that would happen only if it's in a dependency list somewhere - but it's not. But I have now seen it happen in other contexts (e.g. printing the value of the variable for a debug message when trying to get the make files working)

    After trying different things, I decided to only conditionally include the rule that builds the objects, so that the objects in csInferedObjects wouldn't be able to be built even if the objects didn't exists. This would prevent make clean from doing a build when cleaning already-cleaned items.

    So I enclosed the build in an if-statement:

    ifeq $(filter clean, $(MAKECMDGOALS))
    %.o: %.cpp
    My compile rule that uses $(csInferedObjects)
    endif

    This worked sort of: now the reference to $(csInferedObjects) in the clean rule doesn't trigger a build when I do make clean, because the rule to build doesn't exist when "clean" is in MAKECMDGOALS. But this of course led to the stale file warnings that my original post mentioned, since the files being cleaned were built by a rule that no longer exists.

    And that's why I figured I could just use the --no-warn flag to suppress the stale file warnings. But, then I ran into the issue described in my original post.

    So I'm open to any solution: I'd be happy to have a more elegant way to handle the cleaning, or a way to not trigger a build just by referencing csInferedObjects. Failing that, my current solution with a functioning --no-warn working would be acceptable.

    I know of the rm-stale option to makepp, and this seems to work to clean things as all of the files in csInferedObjects are now a stale, so this may be a way to go.

    Thanks in advance!

     

    Last edit: Jeffrey Fuller 2015-12-10
  • Daniel Pfeiffer

    Daniel Pfeiffer - 2015-12-29

    Hi,
    option dashes are optional so --no-warn and --nowarn are identical. This was fixed in CVS on 2014-07-20, but there's been no release since. :-(
    As for your infer magic, the function was intended to be used in rules, because it may have to build the files to read (which wasn't documented, but will now be). So calling it top level isn't such a great idea, especially if you put cleanup into the make file (because the two now work against one another).
    regards -- Daniel

     
  • Jeffrey Fuller

    Jeffrey Fuller - 2016-01-15

    Thanks for the response, Daniel.

    I can easily get rid of the top-level calls to infer_objects by not storing the results of the call in a varaible, and instead putting the call in the depednency list of a rule. I was storing it in a variable because the results are used in several places, so wanted to avoid multiple calls and also make the makefiles more readable, since a variable that holds the results is more readable than the call itself.

    I'm kind of swamped with other things, but will be reutring to trying to get this working at some point, so I want to ask: **regardless of how --no-warn is given (i.e. --no-warn or --nowarn), it doesn't seem to work. It doesn't show up MAKEGLAGS when I give it as an option, and it doesn't stop stale file warnings.
    **
    Do you have any insight into that?

    Thanks again!

     
  • Daniel Pfeiffer

    Daniel Pfeiffer - 2016-01-21

    Hi Jeffrey,

    you can use "var ;= value" to get at most a single expansion at the time of first use.

    Are you saying that even with a recent version from CVS, like I wrote last time, it's still not working???

    As for exporting it, you have a point, but that variable is only needed if you do --traditional-recursive-make, which you really should try to get rid of.

    regards -- Daniel

     
  • Jeffrey Fuller

    Jeffrey Fuller - 2016-01-22

    Hi Daniel,

    Thanks again.

    Yes, it appears that nowarn is not suppressing stale file warnings for me. I'm at version 2.0.98.3, which I think is the newest that's not under development. I've tried using nowarn every way I can think of, as described above...

    I've read about the evils of recursive make, and understand them. The thing is, I wanted my make system to automatically detect everything that needs to be compiled, without having to list it in a makefile, by simply finding a file with a main function and then following the include path to find everything else. This includes both the code in the directory that contains a given executable's code, as well as selectively choosing only the source files needed for the current executable from other directories that contain library code shared between various executables.

    So I can basically have a makefile with a target executable name, that includes various makepp statements I've written, and some common project settings like include directories and compiler options, and boom, of it goes and finds everything it needs and builds it, without having to tell it any of the required files.

    This of course requires the caveat that, for this to work, all required source files must have a header of the same name if they are to be found. I kind of think that's good practice anyway; I've never been a fan of splitting classes across multiple .cpp files. Finding the right .cpp that contains the function one is looking for, though trivial, drives me nuts after having to do it for the 100th time that day, especially when looking though unfamiliar code. ;)

    So I used infer_objects (along with makepp's great ability to detect changed files) to do this. I also have to support using Qt moc and rcc tools for some projects, so I kept the infer_objects results around in a variable so that I could parse header files (that are part of the executable build) for Q_OBJECT, and generate required moc objects for any classes that extend QObject.

    Is there a better way to do this?

    I am far from a makepp or make guru; I think I, like most people, just grab the makefile from the last project, and hack it into what is needed on the next project. So this has been kind of just an excuse to learn the depths of make, and even better, makepp. I am, however, currently using it on one real embedded C++ project (it supports C as well, though it still requires header files for all .c files), some of which is Qt, and it's working except for some of the issues described above. I would like to share it with others at my company if it goes well, and it's almost there. My teammates like it so far.

    In all, I think makepp is pretty damn slick!

    Best
    Jeff

     

Log in to post a comment.

MongoDB Logo MongoDB