Comments (26)
No, while ament might pass specific options any command line invocation can contain the same arguments.
Can you explain a bit more why you want differentiate those two cases?
from ament_cmake.
I want to create a project I can build via
ament build
like described in the tutorial,
but I also want to do a build where I can use cmake directly.
An example:
workspace
-project
- package 1
- package 2
- package 3
Package 3 depends on package 2 and 1. I can provide a findPackage1.cmake and a findPackage2.cmake inside of package 3 in order to build it inside the package folder.
I need this kind of build process due to some legacy reasons.
It is also nice to be able to build a ros 2 project the classical cmake way. But I also want to be able to build some parts of this project with ament (especially it's easier if these components should be used by someone else)
My idea was to check inside the cmake file if the build process was called via ament build(Especially the cmake invokation). If not i would provide my own findPackageX.cmake file for resolving the cmake find_package statement.
I think this should be quite easy if the ament build command would set a cmake variable i could check.
from ament_cmake.
We have some packages that attempt to do this, like rttest, but I believe we don't run CI on the CMake-only build for that package. You can do a find_package(ament_cmake
) and then condition the logic for the ament build on ament_cmake_FOUND
.
from ament_cmake.
From your example it is not clear to me which folder is the actual ament package with the package.xml file.
Each package specifies its build type. If it is ament_cmake
the CMake file is expected to call ament_package()
. If it is cmake
the CMake code can do whatever it wants (but should provide a way to let downstream packages find it). See http://design.ros2.org/articles/ament.html for more details.
The flag ament_cmake_FOUND
does not allow you to distinguish how the build of the package was triggered. It only indicates that ament_package()
was called (or the package faked that by setting the flag manually).
from ament_cmake.
I took some time to think about this question. I probably don't have enough understanding of ament, but still think my question ist kind of valid. I use ament_cmake
in all my packages. (In the example package 1, package 2 and so on). So I can use ament build
in this environment to build the packages an determine dependencies between the packages.
But I also want to be able to build the packages locally without ament build
. So I go for example into the package 1 folder, create a build folder, call cmake
.. and then make
. I have solved the problem of finding upstream packages by providing the fitting packageX_Config.cmake
and setting the correct CMAKE_PREFIX_PATH
.See https://github.com/firesurfer/ros2_components_demo/blob/master/CMakeLists.txt#L12
If I could check if the build was started via ament build
, I would not need to uncomment that line manually.
The reason why I want to do this kind of build: I have some weird legacy components (low level control software that uses another framework) that are nasty to build with ament build
, furthermore it's faster to just build the package I need to rebuild. Ament always checks all packages in the workspace.
from ament_cmake.
I don't see a way to distinguish a build done by ament build
from a manual cmake
invocation. Since the tool is at the end of the day just doing the same, invoking cmake
. While the tool could pass a specific flag to CMake the user is free to also pass that flag to the manual CMake invocation.
Is your questions answered by this thread?
from ament_cmake.
I would appreciate if ament could pass cmake a flag. I don't think that it would be wrong if the user can set the flag himself, but usually the user should check what can happen before he sets a flag.
from ament_cmake.
What do you suggest for the name of such a flag?
from ament_cmake.
Something that contains AMENT and BUILD. How about USES_AMENT_BUILD or do you have any better ideas for a name?
from ament_cmake.
@firesurfer is it not sufficient to do something like this:
find_package(ament_cmake)
if(ament_cmake_FOUND)
# ... use ament
else()
# ... use plain cmake
endif()
Or are you trying to detect if the package is being built with the tool provided in ament_tools?
I don't think it makes sense for our tool to pass something like USES_AMENT_BUILD
because cmake packages which do not use it will produce a cmake warning like this:
CMake Warning:
Manually-specified variables were not used by the project:
USES_AMENT_BUILD
If we were to indicate to packages that they're being built with our tool, then I'd say an environment variable is the best way, but I'm not yet convinced that's helpful. @firesurfer perhaps you could point us at an example package and explain the ways you'd like to use it so we could better understand your use case (I looked at what you linked above https://github.com/firesurfer/ros2_components_demo/blob/master/CMakeLists.txt#L12, but that no longer points to a line of code)? For what it's worth you can take any ament_cmake
based package and just do mkdir build; cd build; cmake ..; make
so long as ament_cmake
and its dependencies have been installed and are on the CMAKE_PREFIX_PATH
.
from ament_cmake.
Please have a look at https://github.com/firesurfer/ros2_components_demo/blob/master/CMakeLists.txt#L14
At the moment I have specified an option so I can tell cmake to do a "LocalBuild" which means I use my own cmake script for searching packages that provide a Config.cmake inside of a specified workspace. I use this in case I want to do a build with: mkdir build; cd build; cmake ..; make
It would be nice if I could just check if the build was started via ament and in case it wasn't started via ament use my own script for finding other packages inside of a workspace: findPackageInWorkspace(ros2_components_msg)
from ament_cmake.
Ok so you do mean you want to know when it's being built with the ament build tool. In that case I still think an environment variable like BUILT_WITH_AMENT_BUILD
is the best strategy.
from ament_cmake.
I agree with you, I wasn't aware that cmake complains about unused flags.
Would you mind adding the setting of said variable to ament ?
from ament_cmake.
Adding the environment variable BUILT_WITH_AMENT_BUILD
as suggested above is fine.
But I still don't see how your custom logic in that case is supposed to work. You can simply not make general assumptions about the location of other packages. They might be in a completely separate workspace and / or built with / without ament build
. Also the way you search for any CMake config files completely bypasses the dependency hierarchy. I might not understand your use case but there might be a much cleaner solution that this.
from ament_cmake.
Okey, I try to explain my usecase to you. I'm also sorry that I couldn't carve out my scenario before.
I agree with you that I can't make assumptions about the location or the build order of other packages in a general usecase. In this case my usage is tied to a specific workspace, so I may do some assumptions.
My workspace is structured like that:
- workspace
- src
- package_1
- package_2
- ....more packages
- legacy package with a custom cmake based build system that doesn't like ament
- src
There are three things I want to be able to do:
- Build every package inside of it's directory in it's own build folder
- Depend from a package to another package in that workspace (that was build locally)
- But also do a build with ament
At the moment I do this in the way that I create a Config.cmake for each package in the workspace I want to use (I know they are doing assumptions about the workspace). These files can be found via a cmake script (findPackageInWorkspace) that looks for the Config.cmake files and add a CMAKE_PREFIX_PATH according to them.
Why I'd like to automatically check if this build is done via ament:
- exclude the legacy package if build via ament (this package can be build by hand afterwards)
- disable the search for Config.cmake in case the build is done via ament
Why I'd want to build my packages locally:
- It's faster (I know i can go into the build dir ament creates and call make in the correct sub directory)
- Having full control over my build (Ok I know this doesn't sound like a good argument...)
- Being able to build my legacy package I unfortunately need in order to access the robot hardware
- Qt creator doesn't load the correct include files if I use it for debugging the binaries created with ament (Perhaps I'm just doing it wrong)
I think there might be more use cases where checking for a BUILT_WITH_AMENT_BUILD
variable might be usefull.
from ament_cmake.
While I see your use case I don't understand why you need to perform all this custom CMake logic within your packages. An important goal of ament is to allow you to build the exact same packages with the native tools and workflows. Without any modification to your packages I would expect you to be able to do the standard CMake workflow. Each package will still provide you with a setup file to prepare your environment to build the next package:
- `cd /path/to/first/pkg
mkdir build
cmake .. -DCMAKE_INSTALL_PREFIX=/some/install/path
(plus any flags you like to use)make
(plus any flags you like to use). /some/install/path/local_setup.sh
(or bash or zsh)- Currently you need to set your
CMAKE_PREFIX_PATH
but ament/ament_tools#76 would even get rid of that manual step - rinse and repeat with the next package
from ament_cmake.
- Build every package inside of it's directory in it's own build folder
You can already do that. All ament packages can be built by doing cd path/to/project; mkdir build; cd build; cmake ..; make
.
- Depend from a package to another package in that workspace (that was build locally)
This is why you've created findPackageInWorkspace
(I assume). However, I would suggest trying to find a way that you can accomplish this without modifying the source of the packages. Ideally you could build with or without ament.py build
without any special logic in your packages.
My recommendation in that case would be to do what catkin
from ROS 1 does and have a top level CMakeLists.txt
. Let me set up a simple example. Consider you have a CMake project "foo" with a CMakeLists.txt
like this:
cmake_minimum_required(VERSION 2.8.3)
project(foo)
find_package(ament_cmake REQUIRED)
Then you have a project "bar" with a CMakeLists.txt
like this:
cmake_minimum_required(VERSION 2.8.3)
project(bar)
find_package(ament_cmake REQUIRED)
find_package(foo REQUIRED)
Notice that it does find_package(foo REQUIRED)
. Then if you build with ament.py build
(and you have a dependency in the package.xml
of bar on foo) it will just work.
If you wanted to build without ament build
, then you could create another CMakeLists.txt
just above those projects like this:
cmake_minimum_required(VERSION 2.8.3)
# Include foo's CMakeLists.txt
add_subdir(foo)
# Add the directory where foo creates a fooConfig.cmake file
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_BINARY_DIR}/foo)
# Include bar's CMakeLists.txt
add_subdir(bar)
# Add the directory where foo creates a fooConfig.cmake file
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_BINARY_DIR}/bar)
# and so on...
Your workspace would like this now:
├── CMakeLists.txt <-- This is the "top level" cmake file
├── bar
│ └── CMakeLists.txt <-- This is bar's cmake file
└── foo
└── CMakeLists.txt <-- This is foo's cmake file
- exclude the legacy package if build via ament (this package can be build by hand afterwards)
This can be done by placing an AMENT_IGNORE
file in the folder of your legacy project. ament
will not traverse the filesystem past this file to look for more packages to build. However, depending on your legacy package, there should be no reason ament could not build it for you. We build fastrtps
and fastcdr
as they are (plain cmake projects) just fine and we can do the same for python setuptools based packages. You would only need to extend ament_tools
to support the build system of your legacy package. That's somewhat involved, but completely possible. Support for plain cmake and plain python projects dogfood a plugin system for this.
- It's faster (I know i can go into the build dir ament creates and call make in the correct sub directory)
You can also use the --only
, --start-with
, and --end-with
options to ament build
.
- Having full control over my build (Ok I know this doesn't sound like a good argument...)
That's an understandable reaction to a relatively exotic system like ament
or catkin
. However, I hope you come to see that the tools exist for a reason and that we've worked hard to make sure it is as non-intrusive and modular as possible.
- Qt creator doesn't load the correct include files if I use it for debugging the binaries created with ament (Perhaps I'm just doing it wrong)
I don't know about that one, but since each package can be treated as a plain CMake project, I imagine it should work. Others in the catkin_tools
repository have been talking about generating a file that could be used across several packages at once: catkin/catkin_tools#266 That's for XCode, but I think a similar thing could be done for QtCreator or Eclipse.
from ament_cmake.
The "feature" of catkin
of building multiple CMake project within a single CMake invocation has been intentionally dropped in ament
. Simply because there are various ways it can break:
- all targets across package need to be unique
- targets need dependencies on targets in other projects
- global side effects in a single package affect other packages
Therefore I wouldn't recommend to use a single CMake file in the root of the workspace. Just for the record this rational is also mentioned in http://design.ros2.org/articles/ament.html#building-within-a-single-cmake-context
from ament_cmake.
That's all true, and the same could be said of the approach that @firesurfer described with findPackageInWorkspace
. I agree that using the build tool or emulating the build tool (by building, installing, sourcing, repeat) is the better way.
from ament_cmake.
I see your points and agree that it is more comfortable to use a build tool. (I actually managed to use ament for all packages now) But from my point of view also more exotic ways for building a project should be made as easy as possible. From my experiences especially in an academic environment there are very strange ways of dealing with code. If you want more people to use ROS 2 I think it is necessary to think about ways how to integrate ROS 2 in other build environments/ let people build their projects the way they want. (Ament already makes this already fairly easy - just wanted to note that there are many ways of building c++ code)
from ament_cmake.
@firesurfer I agree with all your points in the most recent comment. I think we should have the environment variable to let people know that they're being built with the ament tools, especially for scenarios that we can't imagine right now. I haven't had time to look into that, but it should be fairly easy to do since the tool is written in Python. We'd appreciate help with this change, either from you or someone else in the community.
Separately, I hope we've pointed out a few things with your particular situation which suggests that you don't actually need to know when you're being built with the ament tools. Which is not to say no one needs it, but that in this case we don't think you do. This isn't obvious, but since this is sort of how catkin
's non-isolated build worked we have some unique insight into the pattern 😄.
from ament_cmake.
Hi guys, I have the same issue, any news on this topic?
Thanks!
from ament_cmake.
@barbalberto Since we don't have any use case for this it is unlikely that we will spend time implementing this feature. Please consider to provide a pull request for it.
from ament_cmake.
Ok, I'll try.
from ament_cmake.
I found what I think it is a suitable entry point for setting the variable and made a PR.
from ament_cmake.
Addressed by ament/ament_tools#142.
from ament_cmake.
Related Issues (20)
- `ament_auto` macros are too slow? HOT 5
- surround variables with quotes inside `if` ? HOT 3
- ament_add_test default runner cannot handle Catch2 (or generalized) JUnit result files
- Regarding `ament_libraries_deduplicate` implementation HOT 1
- `ament_target_dependencies` does not link PCL properly HOT 2
- Backporting features from `ament_cmake_extension` to `ament_cmake_auto`
- add support for COMPONENTS in `ament_export_dependencies` HOT 2
- "Files to be generated by multiple different commands" Problem in Iron HOT 2
- Using install(DIRECTORY ... TYPE ...) results in "can't find error"
- Using install(DIRECTORY ... TYPE ...) results in "can't find error" HOT 1
- Resolving ament packages at build time HOT 4
- ament_vendor should be able to use mirror site of git HOT 2
- ament_vendor() does not install vendor project to correct path HOT 1
- How to install ament on ubuntu20.04? Or build front the source? HOT 1
- Question about `ament_export_include_directories(include)` and `${PACKAGE_INCLUDE_DIRS}`. HOT 3
- Exporting dependencies of header-only (interface) libraries to downstream packages HOT 3
- ament_pack_build_configuration is very slow for many dependencies HOT 4
- PRIVATE option to ament_target_dependencies does not work HOT 1
- Add support for gmock in ament_cmake_auto
- Enable compulsory sign-off for ament organization or ament_cmake repo? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ament_cmake.