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

Refactor CMake files to better support nmos-cpp as a library #2

Closed
wants to merge 107 commits into from

Conversation

garethsb
Copy link
Owner

@garethsb garethsb commented Aug 2, 2021

See the commits for explanation of each change, but in summary, I'm trying to refactor the CMake files towards more modern CMake, with the goal of nmos-cpp being usable as a library from another CMake project.

That means initially aiming to allow use via add_subdirectory like so:

project(my-nmos-node)
add_subdirectory(.../nmos-cpp/Development nmos-cpp-build EXCLUDE_FROM_ALL)
add_executable(
    my-nmos-node
    ...
    )
target_link_libraries(
    my-nmos-node
    nmos-cpp::nmos-cpp
    ...
    )

Next will be to support use via the INSTALLed location and some generated -config.cmake files so that find_package works:

project(my-nmos-node)
find_package(nmos-cpp REQUIRED)
add_executable(
    my-nmos-node
    ...
    )
target_link_libraries(
    my-nmos-node
    nmos-cpp::nmos-cpp
    ...
    )

As you can see the only difference will be using the find_package command rather than add_subdirectory.

At that point nmos-cpp really needs versioning, which is another discussion.
And following on from that would be to publish a Conan package.

…s; get rid of link_directories and most of the include_directories
…s depend on it

(e.g. there are some question marks in the code as to whether lldp and mdns libs should or not)
…AGS for specific definitions and add_compile_options or add_definitions for almost all other cases that are more general
…dependencies' interface definitions, etc. don't need to be transitively applied
… module and recently also by Conan for most generators (cmake_find_package for example) so Linux and Visual Studio "Open folder" work fine, but with cmake_find_package_multi (which we've traditionally used to generate multi-configuration Visual Studio solutions) it isn't, so map the required components to targets instead

Same seems to be true for OPENSSL_INCLUDE_DIR and WEBSOCKETPP_INCLUDE_DIR
…eeds to do it (seems no worse than force disabling compiler warnings)
…op-level project (see PROJECT_IS_TOP_LEVEL in CMake 3.21)
(it'd still be better to auto-detect in the long run)
… same directory, and rely on searching the directory where the current file is found, in order to avoid the need for the project root directory to be in the include path
…the Boost recipe uses features from at least 1.33.0
…/system libs, Boost components, Bonjour and PCAP, so that (next) each target's dependencies can be brought together
…e and compiler config; the CACHE variables are still spread through the files, but BUILD_LLDP, the only one that affects _what_ is built rather than _how_, is now in the top-level CMakeLists.txt
…found where expected, add --debug-find to the install test
… additional logging we got from --debug-find
…kflows were successful on Windows and Ubuntu 18.04 and 20.04, it failed on macOS (couldn't find CoreFoundation) and on Ubuntu 14.04 (couldn't find system-installed Boost), and the logs weren't much shorter anyway... so I'll keep --debug-find for occasional debugging!
@garethsb
Copy link
Owner Author

garethsb commented Aug 10, 2021

I haven't changed the Sandbox/my-nmos-node example which is used in the "install test" step in GitHub Actions, so it still does something a bit weird for a real-life app - uses Conan to install the dependencies (Boost, cpprestsdk, etc.) but then expects a compatible copy of nmos-cpp to be installed in the system. Not sure what to do there (hence all the force pushes, exploring and rejecting various ideas).

OK... I've now tweaked that project's CMakeLists.txt to never use Conan, but in the CI "install test" I add the location of the nmos-cpp install package to the CMAKE_PREFIX_PATH and the location of the dependencies fetched while building that to the CMAKE_INSTALL_PREFIX and CMAKE_MODULE_PATH. Since we also set CMAKE_FIND_PACKAGE_PREFER_CONFIG=1, the find_package search procedure means that everything is found where we hope (confirmed by tortuous experiments with --debug-find). Running locally, you need to set these same variables or the <PackageName>_DIR variables. (I haven't squashed all those commits because some of the experiments had interesting results... I learnt quite a bit about find_package and discovered lukka/run-cmake#55.)

garethsb and others added 2 commits August 10, 2021 19:14
…d dump into the console a log file of where the most important dependencies have been found
@garethsb
Copy link
Owner Author

garethsb commented Aug 11, 2021

One more thought... I noticed how when you using the add_subdirectory method, you get BUILD_EXAMPLES and so on in your CMake cache. There is certainly the potential for some of these to conflict with the parent project's ones, especially, BUILD_EXAMPLES, BUILD_TESTS and USE_CONAN.

Preparing project for CPM.cmake (the CMake Package Manager) offers the guidance to "Scope any options your root CMakeLists.txt depends on (e.g. BUILD_TESTING -> MY_LIBRARY_BUILD_TESTING)".

Those three therefore might benefit from being renamed with an NMOS_CPP_ prefix...
Would it be going too far to transition to the prefixed names but set NMOS_CPP_<BUILD_EXAMPLES|BUILD_TESTS|USE_CONAN> from the unprefixed ones if the latter were defined and the former weren't? Edit: I guess the question is what would get put in the cache when you first configured nmos-cpp? Hmm.

What about some of the others? They basically all have a prefix, we could just argue about whether they need an extra NMOS_CPP_ prefix.

In any case, it seems like in most use cases, only the two or three BUILD_ vars are interesting for users. In the Conan recipe, I have only exposed BUILD_TESTS and BUILD_EXAMPLES (and left BUILD_LLDP as OFF).

The MDNS_SYSTEM_BONJOUR variable could maybe do with a rename, as it's only controlling whether or not the patched DLL stub library is used, or the one from the Bonjour SDK. Either way, the stub library uses LoadLibrary and GetProcAddress to load the dnssd.dll. I'm not sure if that DLL is part of the Bonjour SDK or of the main Bonjour installer that includes the Windows service (daemon). The CI script is installing Bonjour64.msi after extracting it from the downloaded BonjourPSSetup.exe (print service installer). On the other hand, Bonjour SDK (from 2011...) is available from https://download.developer.apple.com/Developer_Tools/bonjour_sdk_for_windows_v3.0/bonjoursdksetup.exe but only with an Apple ID. Anyway, "System Bonjour" doesn't express the effect well!

Cache Variable Default Type Description Marked As Advanced Platform
BUILD_EXAMPLES ON BOOL Build example applications No All
BUILD_TESTS ON BOOL Build test suite application No All
BUILD_LLDP OFF BOOL Build LLDP support library Yes All
USE_CONAN ON BOOL Use Conan to acquire dependencies Yes All
CMAKE_CXX_STANDARD 11 STRING Default value for CXX_STANDARD property of targets No All
NMOS_CPP_CONAN_BUILD_LIBS "missing" STRING Semicolon separated list of libraries to build rather than download Yes All
NMOS_CPP_CONAN_OPTIONS "" STRING Semicolon separated list of Conan options Yes All
MDNS_SYSTEM_BONJOUR OFF BOOL Use dnssd.lib from the installed Bonjour SDK Yes Windows
BONJOUR_INCLUDE "$ENV{PROGRAMFILES}/Bonjour SDK/Include" PATH Bonjour SDK include directory (if MDNS_SYSTEM_BONJOUR) No Windows
BONJOUR_LIB_DIR "$ENV{PROGRAMFILES}/Bonjour SDK/Lib/x64" PATH Bonjour SDK library directory (if MDNS_SYSTEM_BONJOUR) No Windows
PCAP_INCLUDE_DIR "third_party/WpdPack/Include" PATH WinPcap include directory No Windows
PCAP_LIB_DIR "third_party/WpdPack/Lib/x64" PATH WinPcap library directory No Windows
SLOG_LOGGING_SEVERITY slog::max_verbosity STRING Compile-time logging level, e.g. between 40 (least verbose, only fatal messages) and -40 (most verbose) Yes All

…argets are not available because the find-module or config-file packages use add_library() without GLOBAL for the IMPORTED targets, so the target names only have scope in the subdirectory. Rather than set the IMPORTED_GLOBAL target property explicitly somewhere in nmos-cpp itself, just generate the list of include directories directly from the my-nmos-node executable instead.
…ache variables, e.g. BUILD_EXAMPLES, BUILD_TESTS, USE_CONAN
Add NMOS_CPP_ prefix to the CMake cache variables, e.g. BUILD_EXAMPLES, BUILD_TESTS, USE_CONAN
@garethsb
Copy link
Owner Author

garethsb commented Aug 12, 2021

I've noticed that the build instructions for cpprestsdk mention setting CPPREST_PPLX_IMPL to winpplx... We'd either need a Windows-specific copy of Development/conanfile.txt with cpprestsdk:pplx_impl=winpplx, picked up by NmosCppConan.cmake or a conanfile.py that would only add the option on Windows. On Linux, Conan reports an error if that option is present, which makes sense. I'm slightly loathe to do it because of course this will prevent using binaries from Conan Center Index on Windows, although it doesn't take long to build cpprestsdk locally.

@garethsb
Copy link
Owner Author

I've noticed that the build instructions for cpprestsdk mention setting CPPREST_PPLX_IMPL to winpplx... We'd either need a Windows-specific copy of Development/conanfile.txt with cpprestsdk:pplx_impl=winpplx

I tried this out by setting that option in Sandbox/my-nmos-node, and it worked OK apart from a slew of link warnings. I've opened conan-io/conan-center-index#6847 to resolve those.

…building from third_party source

Reorder dependencies consistently in conanfiles, NmosCppDependencies.cmake and Dependencies docs
…d comment to more clearly explain the rationale for building the patched dnssd.lib and that the Bonjour service and client DLL (dnssd.dll) are still required
…vs. nlohmann_json_schema_validator)

Fixes bug in 0b7689b
@garethsb garethsb force-pushed the library-cmake branch 2 times, most recently from c842a8b to 190cea9 Compare August 16, 2021 15:56
garethsb and others added 2 commits August 16, 2021 16:56
…end slightly) since the existing include in NmosCppConan.cmake didn't work for out-of-source builds, and it seems slightly more elegant to keep the as much of the Conan recipe-specific stuff alongside the conanfile.py and just "turn off" NmosCppConan.cmake in the case of CONAN_EXPORT but take no other action.
@garethsb
Copy link
Owner Author

Ready to make PR to sony/nmos-cpp

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.

2 participants