Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmake/evercbor.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
# Licensed under the Apache 2.0 License.

# Build EverCBOR
set(EVERCBOR_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/exported/evercbor")
set(EVERCBOR_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/internal/evercbor")
set(EVERCBOR_SRCS "${EVERCBOR_DIR}/CBORNondet.c")

add_library(evercbor STATIC ${EVERCBOR_SRCS})

target_include_directories(
evercbor PUBLIC $<BUILD_INTERFACE:${CCF_3RD_PARTY_EXPORTED_DIR}/evercbor>
evercbor PUBLIC $<BUILD_INTERFACE:${CCF_3RD_PARTY_INTERNAL_DIR}/evercbor>
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is right, I think the target_include_directories should be PRIVATE instead, and probably not refer to the install interface, since the point of moving from external to internal is to not export these headers.

For this to work, we need to make sure that none of the headers we export in include/ccf include headers from evercbor. I do not know if that is (already) the case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This PR simply moves it from exported to internal to avoid them being packaged

Copy link
Member

Choose a reason for hiding this comment

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

but we still export the include directory as a public dependency, so that seems like a breaking change

Copy link
Member

Choose a reason for hiding this comment

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

I think there's 2 levels of fix here, but we should do both.

First is moving from exported to internal to say that consumers of CCF should not use our evercbor directly, and it is not packaged with the install. As a side effect of that (of the changes in this PR already), I believe the include/3rdparty/evercbor directory will not be created in the installed dir, so we should remove the line below.

Second is whether consumers of our evercbor-using libraries (eg - a test case calling verify_uvm_endorsements_against_roots_of_trust) need to see evercbor headers (types) themselves. I think the answer to that is also no, so we should make this PRIVATE rather than PUBLIC. A corollary of that, though hard-to-enforce (beyond "it'll probably break the build"), is that we should only be including evercbor headers in .cpp files, never in .h files, so that it's visibility can be contained to specific libraries. I think that's another reason for defining some wrappers - not just getting C++-type-safety back, but also drawing a firm line on visibility.

2 notes on the latter:

  • We could have also done this for qcbor, but didn't, as we have a lot of header-implementation, and new of apps that might want to do their own parsing of CBOR/COSE. I think the former is an accident, and the latter should be avoided - they get implementation-library-agnostic wrappers if we think they're of sufficient value, or include their own CBOR support libraries.
  • nlohmann::json and quickjs are 3rd party dependencies where we explicitly make the other choice. We think nlohmann::json is a sufficiently useful, rich type that we use it directly in the API between CCF and app code, so apps need to see "our" copy of the library. That's also easier because it is header-only. For quickjs we do have wrappers for safe lifetime-management, but accept that they're incomplete and leaky. Apps get to access JSValues directly and call functions in quickjs headers directly, so that they can insert FFIs directly into the runtime, and accept that they're eventually hitting a quickjs binary that we have built.

Copy link
Member

Choose a reason for hiding this comment

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

You're absolutely right about the two levels.

A corollary of that, though hard-to-enforce (beyond "it'll probably break the build"), is that we should only be including evercbor headers in .cpp files, never in .h files

Never in exported .h files (i.e. files under include/ccf). We already have a check that looks at exported headers, it should be too difficult to add one that looks for "evercbor" in there too.

I don't remember how the qcbor situation came to be, but I think it was a mistake that happened because other headers accidentally exposed t_cose/qcbor, not a deliberate decision to provide the library. One thing to consider is that even if no types are exposed in the API, static objects have no visibility mechanisms to cope with conflicting copies of the same symbols.
Interestingly, because evercbor is extracted from F*, it is perhaps relatively easy to obtain a copy with all the symbols prefixed (I believe the generate supports that), and we may want to do that.

$<INSTALL_INTERFACE:include/3rdparty/evercbor>
)
set_property(TARGET evercbor PROPERTY POSITION_INDEPENDENT_CODE ON)
Expand Down