Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/483 Conan 2 Support #620

Merged
merged 23 commits into from
Aug 24, 2023
Merged

Feature/483 Conan 2 Support #620

merged 23 commits into from
Aug 24, 2023

Conversation

PengZheng
Copy link
Contributor

@PengZheng PengZheng commented Aug 23, 2023

This PR updates the whole project to support both Conan 1.x and the current Conan 2:

  • All generators unsupported by Conan 2 are dropped. CMake, CMakeDeps and CMakeToolchain are used instread.
    • Find modules are updated to account for changed targets name introduced by these generators.
    • CI has been updated to use conanrun.sh/deactivate_conanrun.sh
  • Re-implement automatic intra-package dependency deduction in a way supported by both Conan 1 and Conan 2:
  • Specify dependency option in configure() method. Previously this is done in requirements() method, which is not supported by Conan 2.
  • Use self.requires("openssl/1.1.1t", override=True) to resolve version conflict of openssl caused by civetweb and libcurl. Note that it does not introduce any dependency of openssl into Celix. For an extensive discusson, see [question] Resolve Version Conflicts Caused by Indirect Dependencies conan-io/conan#14535 (comment)
  • Update conan_create/ubuntu_build to use Conan 2, leaving other GitHub actions untouched. Due to the low cache hit rate of Conan 2, updating them all will lead to long build time.
  • Uppdate documentation to reflect the new conan based workflow.
    • Note that conan build . -bf cmake-build-debug --configure does not work anymore. It will always lead to a full build.
    • A CMake command line generated by conan install is used instead to configure the build directory.
    • Conan is said to produce a CMakeUserPresets.json in the project root, which should enable a seamless integration with CLion. However, this file will cause CLion's CMake window lose correspondence. Removing it from the project root will fix the issue. Thus an extra line tc.user_presets_path = False is added to suppress its production. I reported it to JetBrains (https://youtrack.jetbrains.com/issue/CPP-34818). Once this issue solved, we can expect excellent user experience by combining Conan and CLion.

@PengZheng PengZheng linked an issue Aug 23, 2023 that may be closed by this pull request
@codecov-commenter
Copy link

codecov-commenter commented Aug 23, 2023

Codecov Report

Merging #620 (4e7c7a4) into master (9647e66) will increase coverage by 1.60%.
The diff coverage is 50.00%.

@@            Coverage Diff             @@
##           master     #620      +/-   ##
==========================================
+ Coverage   80.00%   81.61%   +1.60%     
==========================================
  Files         260      260              
  Lines       34674    34674              
==========================================
+ Hits        27741    28298     +557     
+ Misses       6933     6376     -557     
Files Changed Coverage Δ
libs/dfi/src/json_serializer.c 82.83% <0.00%> (ø)
...sub_admin_udp_mc/src/pubsub_udpmc_topic_receiver.c 73.68% <100.00%> (+73.68%) ⬆️

... and 10 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@PengZheng PengZheng requested review from pnoltes August 24, 2023 01:56
Copy link
Contributor

@pnoltes pnoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see an upgrade to conan 2, I do have some remarks.

documents/building/dev_celix_with_clion.md Outdated Show resolved Hide resolved
set_target_properties(RapidJSON::RapidJSON PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
if(RapidJSON_FOUND AND NOT TARGET rapidjson)
add_library(rapidjson INTERFACE IMPORTED)
set_target_properties(rapidjson PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
"${RapidJSON_INCLUDE_DIRS}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, in my opinion, this is a breaking change.

The reason is that downstream Apache Celix containers need to link against rapidjson to ensure a functional C++ Remote Services. This requirement also applies to ZerMQ and czmq, but then for PubSub ZMQ usage.

I believe this issue could be addressed with an additional alias:
add_library(RapidJSON::RapidJSON ALIAS rapidjson)

A more optimal solution would have been to introduce an Apache Celix library with an INTERFACE link to the required library, thereby abstracting the underlying library target names. This approach is used with civetweb for cmake target Celix::http_admin_api. However, since this wasn't done for rapidjson, ZeroMQ or czmq usage, changing the container-required library names now, is in my view, a breaking change.

Perhaps we should add a paragraph to the coding convention. It could mention that an Apache Celix INTERFACE library should be added if a bundle requires the associated executable to link against an external library. This ensures the specific required library is abstracted away.

Copy link
Contributor Author

@PengZheng PengZheng Aug 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that downstream Apache Celix containers need to link against rapidjson to ensure a functional C++ Remote Services. This requirement also applies to ZerMQ and czmq, but then for PubSub ZMQ usage.

Fortunately, all these targets (zmq/czmq/libzip/rapidjson) need not to be specified explicitly by our downstream users, since they are all linked privately by their users, for exmaple RsaConfiguredDiscovery. For a container containing RsaConfiguredDiscovery, e.g. RemoteCalculatorConsumer, there is no need to refer to rapidjson/RapidJSON::RapidJSON directly. All needed information is encoded in DT_NEEDED tag, the dynamic loader will find them automatically provided the needed library is in the canonical search path or LD_LIBRARY_PATH.

I have removed many such unnecessary extra linkages in tests of Celix in the past two years. They were needed because we have no BUILD_RPATH in the past. When they are installed, even without BUILD_RPATH, our user will encounter no issue, since Conan setup LD_LIBRARY_PATH to containing all dependencies (direct and indirect).

I believe this issue could be addressed with an additional alias: add_library(RapidJSON::RapidJSON ALIAS rapidjson)

Our user may have encounter the same issues we had before, and resort to explicit linking as we did before.
So I will add these alias in find modules to avoid breaking these usage.

There is indeed a interesting corner case: Conan does not describe CMake private linkage well enough, we have the following workaround in Celix:

        # the following is workaround https://github.com/conan-io/conan/issues/7192
        if self.settings.os == "Linux":
            cmake.definitions["CMAKE_EXE_LINKER_FLAGS"] = "-Wl,--unresolved-symbols=ignore-in-shared-libs"
        elif self.settings.os == "Macos":
            cmake.definitions["CMAKE_EXE_LINKER_FLAGS"] = "-Wl,-undefined -Wl,dynamic_lookup"

Note that the above is to avoid build time linker error, there is nothing wrong at run time (all information is encoded in DT_NEEDED correctly).
For more on this, see conan-io/conan#13302

Perhaps we should add a paragraph to the coding convention. It could mention that an Apache Celix INTERFACE library should be added if a bundle requires the associated executable to link against an external library. This ensures the specific required library is abstracted away.

We don't need to do this. Our user should live happily without knowing a private dependency of Celix if they don't use it directly. It's a pure implementation detail of Celix. Yes, at runtime, we need these dependencies at the right place so that dynamic linker could find them. The good news is that Conan helps a lot with this scenario:
conan import will fetch all direct and indirect dependencies from the cache. Users only need to copy all of them collected by Conan into the library path when deploying their application. Conan 2 facilitate this usage even further.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear and thanks for explanation.

I agree that linked system libraries is mostly an implementation details, but the libraries need to be available runtime so there is some leakage and therefore I prefer no changes to libs target name .. if possible.

@PengZheng PengZheng linked an issue Aug 24, 2023 that may be closed by this pull request
@PengZheng
Copy link
Contributor Author

Once https://youtrack.jetbrains.com/issue/CPP-34818 is addressed, using Conan with Clion will be enjoyable.
A quick conan install then everything will be setup automatically in CLion.

Copy link
Contributor

@pnoltes pnoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the added lib alias, LGTM.

@PengZheng PengZheng merged commit 9763b61 into master Aug 24, 2023
@PengZheng PengZheng deleted the feature/483-conan-2-support branch August 24, 2023 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conan 2.0 support Coverage result for PSA UDPMC not working
3 participants