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

Cleanup header includes #392

Merged
merged 5 commits into from
Feb 28, 2019
Merged

Conversation

ilammy
Copy link
Collaborator

@ilammy ilammy commented Feb 26, 2019

The main issue addressed by this PR are circular dependencies in header files. Many of them include umrella headers (<soter/soter.h>, <themis/themis.h>) which creates a circular dependency in other headers included from umrella headers. This prevents individual headers from compiled and analyzed separate by the tools. It also introduces hidden dependency on the inclusion order. To resolve issue avoid using umbrella headers in library code: include specific headers where necessary. Umbrella headers should be used only for the user code (and tests).

While we're here, do some cosmetic improvement as well:

  • unify include guard style to be <PROJECT>_<HEADER>_H everywhere
  • sort included headers alphabetically
  • group headers in the meaningful groups
  • use proper relative paths in headers
  • consistently use quotes "soter/soter_rsa_key.h" for internal inclusions
  • consistently use angle brackets <soter/soter.h> for public inclusions

These changes are inspired and rationalized by Google C++ Style Guide.

@ilammy ilammy added the core Themis Core written in C, its packages label Feb 26, 2019
Copy link
Collaborator

@Lagovas Lagovas left a comment

Choose a reason for hiding this comment

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

why you include soter/openssl/boringssl/soter_engine.h in several variants: as <path> and "path"?

#include <soter/soter_ec_key.h>
#include "soter_engine.h"
#include <soter/soter_error.h>
#include <soter/boringssl/soter_engine.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

why we use angle braces here? should boringssl/soter_engine.h be public?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Mmm... I think you're right, it's not public. I initially assumed all headers to be public and thus use only angled brackets there (and quotes in *.c files). I'll review the headers and will tweak the quotes.

Now when I think of it... It's kinda hard to distinguish public headers from private ones. I've seen quite a few libraries put their public headers into a separate top-level directory include. For example:

include
  themis
    secure_cell.h
    themis.h
    ...
src
  themis
    message.h
    portable_endian.h
    secure_session_utils.h
    ...

How do you feel about moving to this layout in the next PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Based on the include analysis, here are the public headers. I.e., this gets included with #include <themis/themis.h>:

soter/soter.h
soter/soter_asym_cipher.h
soter/soter_asym_ka.h
soter/soter_asym_sign.h
soter/soter_error.h
soter/soter_hash.h
soter/soter_hmac.h
soter/soter_kdf.h
soter/soter_rand.h
soter/soter_rsa_key.h
soter/soter_rsa_key_pair_gen.h
soter/soter_sym.h

themis/themis.h
themis/themis_error.h
themis/secure_cell.h
themis/secure_comparator.h
themis/secure_keygen.h
themis/secure_message.h
themis/secure_session.h

And these ones are private:

soter/boringssl/*
soter/ed25519/*
soter/openssl/*
soter/soter_container.h
soter/soter_crc32.h
soter/soter_ec_key.h
soter/soter_sign_ecdsa.h
soter/soter_sign_rsa.h
soter/soter_t.h

themis/message.h
themis/portable_endian.h
themis/secure_cell_alg.h
themis/secure_comparator_t.h
themis/secure_message_wrapper.h
themis/secure_session_peer.h
themis/secure_session_t.h
themis/secure_session_utils.h
themis/sym_enc_message.h

@vixentael
Copy link
Contributor

vixentael commented Feb 26, 2019 via email

@ilammy
Copy link
Collaborator Author

ilammy commented Feb 27, 2019

@vixentael, understood. Thank you for the warning.

@ilammy
Copy link
Collaborator Author

ilammy commented Feb 27, 2019

@vixentael you can try checking the iOS wrapper now.

I've managed to see the tests pass locally and it seems to have used the correct source code for that, but I'm not really sure. Please check.

Now that I've interacted with iOS wrapper a bit I completely agree with you to not touch that fine-tuned header magic unless absolutely necessary. Though, it seems that we export too many headers for iOS, but I'm no expert, maybe we really need to do that because of reasons.

@vixentael
Copy link
Contributor

vixentael commented Feb 27, 2019

@ilammy i've checked iOS wrapper – it's working fine.
If @Lagovas doesn't have any more comments – let's merge!

The reasoning behind my warning (lots of details inside)

It's not a magic of any kind, it's more a fine-tuned Header Search Paths.

In podspec we precisely define what Themis core files and iOS wrapper files should be exported, what path should be preserved and what are public headers:

# don't use as independent target
so.subspec 'core' do |ss|
    ss.source_files = "src/themis/*.{h,c}", "src/soter/*.{c,h}", "src/soter/ed25519/*.{c,h}", "src/soter/openssl/*.{c,h}"
    ss.header_mappings_dir = "src"
    ss.header_dir = 'src'
    ss.preserve_paths = "src/themis/*.h", "src/soter/*.h", "src/soter/ed25519/*.h", "src/soter/openssl/*.h"
    ss.public_header_files = "src/themis/*.h", "src/soter/*.h", "src/soter/ed25519/*.h", "src/soter/openssl/*.h"
end

# don't use as independent target
so.subspec 'objcwrapper' do |ss|
    ss.header_mappings_dir = 'src/wrappers/themis/Obj-C/objcthemis'
    ss.source_files = "src/wrappers/themis/Obj-C/objcthemis/*.{m,h}"
    ss.public_header_files = 'src/wrappers/themis/Obj-C/objcthemis/*.h'
    ss.header_dir = 'objcthemis'
    ss.dependency 'themis/themis-openssl/core'
end

This is how these headers in Themis pod.xcconfig looks like:

HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/themis" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/GRKOpenSSLFramework" "${PODS_ROOT}/Headers/Public/themis" "${PODS_ROOT}/themis/src" "${PODS_ROOT}/themis/src/wrappers/themis/Obj-C"

This is how they are transformed (notice a "flat" structure, without any folders):
feb-27-2019 18-57-35

@@ -14,7 +14,8 @@
* limitations under the License.
*/

#include <soter/soter.h>
#include "soter_sign_ecdsa.h"
Copy link
Collaborator

Choose a reason for hiding this comment

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

why here we use relative to file's folder path instead soter/soter_sign_ecdsa.h ? it's third variant of imports in the code. do we have any reason for that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

do we have any reason for that?

No, that's just me not having enough attention. Thanks for noticing this, I'll review the includes once again. All paths should start from the 'project root'.

I have missed a couple of includes which did not use correct relative
paths. Update them.
@ilammy ilammy merged commit e0f71df into cossacklabs:master Feb 28, 2019
@ilammy ilammy deleted the optimize-includes branch February 28, 2019 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Themis Core written in C, its packages refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants