catkin_tools icon indicating copy to clipboard operation
catkin_tools copied to clipboard

Unable to run roslint on all packages in a workspace?

Open koenlek opened this issue 10 years ago • 33 comments

To use roslint for a pkg foo I used to do:

catkin_make roslint_foo

However, I cannot figure out to get this working in catkin tools. I tried:

catkin build roslint_foo
catkin build --catkin-make-args roslint_foo
catkin build --make-args roslint_foo
catkin build --cmake-args roslint_foo

But none of this works... Doing it the old way works, but I need to clear my ws after that if I want to build using catkin build again. So essentially I recompile my full ws, which takes a lot of time...

So: does catkin tools not yet support roslint? Or am I doing it wrong?

koenlek avatar Apr 22 '15 13:04 koenlek

The positional arguments to catkin build are package names, unlike catkin_make where they are target names. To pass a target name to make via catkin build, you're correct in using --make-args, but I suspect that the warnings just aren't being printed to the console

If that's the case, then this should work:

catkin build -v foo --make-args roslint_foo

jbohren avatar Apr 22 '15 13:04 jbohren

As an aside, roslint has unfortunately been designed to accommodate catkin_make's merged devel pattern, which is why it needs to create targets with the package name in them.

jbohren avatar Apr 22 '15 13:04 jbohren

Thanks for the quick reply. Found the solution. You also need to add --no-deps. I guess otherwise it will check the dependencies too, running make roslint_foo on each of them. This causes errors, as the dependencies of foo don't have these make targets... So the working command is:

catkin build --no-deps foo --make-args roslint_foo

I understand how this comes from the different design that catkin tools follows, with separate devels. However, it would be nice if a more convenient way of running roslint would be added eventually, don't you agree?

koenlek avatar Apr 22 '15 13:04 koenlek

However, it would be nice if a more convenient way of running roslint would be added eventually, don't you agree?

Absolutely.

Until that point, however, feel free to add this to your bashrc:

roslint () {
  catkin build --no-deps $1 --make-args roslint_$1
}

jbohren avatar Apr 22 '15 13:04 jbohren

When roslint was originally created, catkin_make was what we had to use. It is not clear to me what should be done differently with catkin_tools. If you can figure out how to make it work better, please open a roslint issue, so it can better support both build approaches.

FWIW, I have had reasonable luck first running catkin build, then change to the build/PACKAGENAME directory and running make roslint there.

jack-oquin avatar Apr 22 '15 16:04 jack-oquin

@jack-oquin Is roslint a valid target for any given package? Then catkin build could simply implement an alias like:

roslint: build --no-deps --make-args roslint --

Then the following would work quite well:

catkin roslint PKG1 [PKG2...]
catkin roslint --this

jbohren avatar Apr 22 '15 17:04 jbohren

@jbohren For any package with a CMakeLists.txt that contains a roslint_cpp(...) block, the roslint_PKGNAME target exists... So I think your proposal makes sense.

koenlek avatar Apr 22 '15 17:04 koenlek

Jon: I seem to remember that for every CMake build, roslint depends on all the individual package roslint_PKGNAME targets. That should be true for each single catkin build package as well.

It will only be defined if at least one package in the build uses roslint.

Let me know if I am wrong about that.

jack-oquin avatar Apr 22 '15 18:04 jack-oquin

Ideally, roslint would behave similar to run_tests, which is that it always creates a run_tests target whether or not you're building one package (catkin build) or many (catkin_make). That way you can always just run the roslint target and not have to run the roslint_package_name target. Also just like run_tests it can keep the package specific target name and just add it as a dependency of the general target, i.e. run_tests_foo vs. run_tests.

I'd rather not bake roslint specific knowledge into catkin_tools, but there's always the opportunity to extend catkin_tools externally if that is necessary.

wjwwood avatar Apr 22 '15 18:04 wjwwood

I'd rather not bake roslint specific knowledge into catkin_tools, but there's always the opportunity to extend catkin_tools externally if that is necessary.

Agreed, but that doesn't mean we can't have a second repo / package that just adds a bunch of contributed aliases, and in the meantime, people can add them as they see fit.

jbohren avatar Apr 22 '15 18:04 jbohren

If my earlier comment was unclear: I believe the roslint target does work like run_tests. As long as at least one package uses roslint, the general target exists and depends on all the package targets.

jack-oquin avatar Apr 22 '15 18:04 jack-oquin

If my earlier comment was unclear: I believe the roslint target does work like run_tests. As long as at least one package uses roslint, the general target exists and depends on all the package targets.

Oh, in that case, @jbohren's verb aliases should work just fine. That's for clarifying @jack-oquin.

wjwwood avatar Apr 22 '15 18:04 wjwwood

If my earlier comment was unclear: I believe the roslint target does work like run_tests. As long as at least one package uses roslint, the general target exists and depends on all the package targets.

@jack-oquin, I doubt that. To my knowledge there is no generic target similar to run_tests for roslint.

koenlek avatar Apr 22 '15 18:04 koenlek

Works for me. I just tried it.

What happens when you go to the relevant build directory and type: make roslint?

jack-oquin avatar Apr 22 '15 19:04 jack-oquin

So what command did you use? I am not at work currently, so in about 12 hours I can give it a shot…

koenlek avatar Apr 22 '15 19:04 koenlek

I did something like this:

cd ~/catkin_ws
catkin build
cd build/your_package
make roslint

jack-oquin avatar Apr 22 '15 22:04 jack-oquin

That worked, so this works too:

catkin build --no-deps foo --make-args roslint

However, there is no generic target to run all roslints (which is impossible with catkin_make as well btw), as there is for running tests: catkin build --catkin-make-args run_tests I thought you meant that when stating that there is a generic target... So such a generic target does not exits for roslint I still think.

Also, I don't really like the --no-deps trick. Without it, make will try to build a roslint target for all dependencies of foo, preceding the actual foo build... This throws errors, as they don't exist. However, I think that (generally speaking), building a specific target of a package does require the dependencies to be build first. Hence, maybe two different categories should be added:

--make-args // for general make arguments, passed to all packages in the scope of the current catkin build command.
--make-targets //for make targets, passed only to the specified package.

What do you think?

koenlek avatar Apr 23 '15 09:04 koenlek

However, there is no generic target to run all roslints (which is impossible with catkin_make as well btw), as there is for running tests:

catkin build --catkin-make-args run_tests

For catkin_make, roslint is a generic target:

catkin_make roslint

works just like:

catkin_make run_tests

Suggestions for how to make that work similarly with catkin build are welcome.

jack-oquin avatar Apr 23 '15 18:04 jack-oquin

I think a separate --make-targets option which runs make with the target iff it has that target is a good idea. We'd need to make that clear from the docs, or the name of the option (maybe --try-make-target?).

wjwwood avatar Apr 23 '15 18:04 wjwwood

Maybe: --make-if-target?

jack-oquin avatar Apr 23 '15 18:04 jack-oquin

Why could it not just work like the generic run_tests currently works in catkin_tools? catkin build --catkin-make-args run_tests already works, so why not similarly support: catkin build --catkin-make-args roslint?

I am not sure how the run_tests 'target' is currently implemented?

I think the --try-make-target makes more sense than --make-if-target, which is a bit confusing/ambiguous to me. But why not just call it --make-target and only make that target plus its dependencies without passing those dependencies the same target (which is what essentially makes --make-target``` different from--make-args). And if you pass a --make-target to a package that does not know it, just print a warning? This way I think one can safely runcatkin build --make-targets roslint``` (although it will print a lot of warnings).

Alternatively, one could add both --make-target and --try-make-target, for which the first prints errors/warnings if targets do not exists, while the latter suppresses those...

koenlek avatar Apr 24 '15 09:04 koenlek

Why could it not just work like the generic run_tests currently works in catkin_tools?

That's because the run_tests target is created for all catkin packages.

Alternatively, one could add both --make-target and --try-make-target, for which the first prints errors/warnings if targets do not exists, while the latter suppresses those...

This sounds like it's nearly duplicating the behavior of combining --continue-on-failure and --make-args roslint. Is there a reason why that's insufficient?

jbohren avatar Apr 25 '15 04:04 jbohren

Aha, I just confirmed for myself that indeed, a catkin package always has a run_tests target, even if there are no tests specified in the CMakeLists.txt. Unfortunately this doesn't go for roslint...

So far I found no catkin tools equivalent for running all roslints: catkin_make roslint

This does not work: catkin build -v --no-deps --continue-on-failure --make-args roslint

From my ws, it fails to build about half of the packages, and half it "did not try to build", as stated in the build summary.

To me, it still seems that --make-targets and/or --try-make-targets would be the best solution... They could btw be combined: just use a strict version of --make-targets when called for a specific package, e.g.: catkin build foo --make-targets roslint (would be equiv. to: catkin_make roslint_foo) It should then report errors if the target does not exist for pkg foo.

And make it behave like --try-make-targets when applied to a full workspace, e.g.: catkin build --make-targets roslint (would be equiv. to: catkin_make roslint) It should then for each package in the ws try to build the target if it exists, and continue without any errors otherwise...

P.s. I changed --make-targets to plural, like --make-args and friends... Makes more sense to me.

koenlek avatar Apr 28 '15 08:04 koenlek

Is anyone yet aware of a way to run all roslints?

koenlek avatar Jun 07 '15 10:06 koenlek

@koenlek How about this:

catkin build $(catkin list --depends-on roslint -u) --catkin-make-args roslint

jbohren avatar Jun 08 '15 01:06 jbohren

Ideally it would be --depends-on-direct or --depends-on-1 so that only packages with direct deps are built. (PR for that would be welcome, I think)

jbohren avatar Jun 08 '15 01:06 jbohren

@jbohren Thanks for the suggestion. You are right in your 'self-reply' directly after that: --depends-on does not work right, because of indirect dependencies. I'd still prefer --make-targets or --try-make-targets, but the --depends-on-direct would also be an option. I myself don't plan to look into creating a PR any time soon, so hopefully someone else will be able to pick it up...

Maybe at some point I might make some script that finds all roslint targets and builds them one by one. If so, I'll give an heads-up here.

koenlek avatar Jun 16 '15 20:06 koenlek

You are right in your 'self-reply' directly after that: --depends-on does not work right, because of indirect dependencies.

Actually I'm not right. The --depends-on in catkin list is actually a --depends-on-direct. So this will work assuming people properly depend on roslint in their package.xml files.

jbohren avatar Jun 16 '15 20:06 jbohren

It does not work for our workspace, here part of an error I get (I get several of these).

Starting ==> voxel_grid                                                                                                                                                                                        

[hardware_interface] ==> '/home/koenlek/catkin_ws/build/hardware_interface/build_env.sh /usr/bin/make roslint --jobserver-fds=3,5 -j' in '/home/koenlek/catkin_ws/build/hardware_interface'
make: *** No rule to make target `roslint'.  Stop.
[hardware_interface] <== '/home/koenlek/catkin_ws/build/hardware_interface/build_env.sh /usr/bin/make roslint --jobserver-fds=3,5 -j' failed with return code '2'

Failed   <== hardware_interface     [ 0.3 seconds ]    

However, if I do grep -Hrn roslint in the top level src folder of the hardware_interface pkg, there are zero results. Which means that both the package.xml and CMakeLists.txt do not contain a dependency on roslint, don't you agree?

koenlek avatar Jun 16 '15 20:06 koenlek

It does not work for our workspace, here part of an error I get (I get several of these).

What's the output of this in your workspace:

catkin list --depends-on roslint -u

jbohren avatar Jun 16 '15 21:06 jbohren