-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Enforce levelization in libxrpl with CMake #5111
base: develop
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
include(isolate_headers) | ||
|
||
# Create an OBJECT library target named | ||
# | ||
# ${PROJECT_NAME}.lib${parent}.${name} | ||
# | ||
# with sources in src/lib${parent}/${name} | ||
# and headers in include/${parent}/${name} | ||
# that cannot include headers from other directories in include/ | ||
# unless they come through linked libraries. | ||
# | ||
# add_module(parent a) | ||
# add_module(parent b) | ||
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a) | ||
function(add_module parent name) | ||
set(target ${PROJECT_NAME}.lib${parent}.${name}) | ||
add_library(${target} OBJECT) | ||
file(GLOB_RECURSE sources CONFIGURE_DEPENDS | ||
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp" | ||
) | ||
target_sources(${target} PRIVATE ${sources}) | ||
target_include_directories(${target} PUBLIC | ||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" | ||
) | ||
isolate_headers( | ||
${target} | ||
"${CMAKE_CURRENT_SOURCE_DIR}/include" | ||
"${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}" | ||
PUBLIC | ||
) | ||
isolate_headers( | ||
${target} | ||
"${CMAKE_CURRENT_SOURCE_DIR}/src" | ||
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}" | ||
PRIVATE | ||
) | ||
Comment on lines
+31
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is not needed ? Or my misunderstanding of how CMake works just showed :-D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's in case a module has private headers, not installed, but included by other translation units. I don't know if any of our modules have these (yet), but I'm copying this implementation from my more generalized project. |
||
endfunction() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Consider include directory B nested under prefix A: | ||
# | ||
# /path/to/A/then/to/B/... | ||
# | ||
# Call C the relative path from A to B. | ||
# C is what we want to write in `#include` directives: | ||
# | ||
# #include <then/to/B/...> | ||
# | ||
# Examples, all from the `jobqueue` module: | ||
# | ||
# - Library public headers: | ||
# B = /include/xrpl/jobqueue | ||
# A = /include/ | ||
# C = xrpl/jobqueue | ||
# | ||
# - Library private headers: | ||
# B = /src/libxrpl/jobqueue | ||
# A = /src/ | ||
# C = libxrpl/jobqueue | ||
# | ||
# - Test private headers: | ||
# B = /tests/jobqueue | ||
# A = / | ||
# C = tests/jobqueue | ||
# | ||
# To isolate headers from each other, | ||
# we want to create a symlink Y that points to B, | ||
# within a subdirectory X of the `CMAKE_BINARY_DIR`, | ||
# that has the same relative path C between X and Y, | ||
# and then add X as an include directory of the target, | ||
# sometimes `PUBLIC` and sometimes `PRIVATE`. | ||
# The Cs are all guaranteed to be unique. | ||
# We can guarantee a unique X per target by using | ||
# `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`. | ||
# | ||
# isolate_headers(target A B scope) | ||
function(isolate_headers target A B scope) | ||
file(RELATIVE_PATH C "${A}" "${B}") | ||
set(X "${CMAKE_CURRENT_BINARY_DIR}/include/${target}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest
|
||
set(Y "${X}/${C}") | ||
cmake_path(GET Y PARENT_PATH parent) | ||
file(MAKE_DIRECTORY "${parent}") | ||
file(CREATE_LINK "${B}" "${Y}" SYMBOLIC) | ||
target_include_directories(${target} ${scope} "$<BUILD_INTERFACE:${X}>") | ||
endfunction() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Link a library to its modules (see: `add_module`) | ||
# and remove the module sources from the library's sources. | ||
# | ||
# add_module(parent a) | ||
# add_module(parent b) | ||
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a) | ||
# add_library(project.libparent) | ||
# target_link_modules(parent PUBLIC a b) | ||
function(target_link_modules parent scope) | ||
set(library ${PROJECT_NAME}.lib${parent}) | ||
foreach(name ${ARGN}) | ||
set(module ${library}.${name}) | ||
get_target_property(sources ${library} SOURCES) | ||
list(LENGTH sources before) | ||
get_target_property(dupes ${module} SOURCES) | ||
list(LENGTH dupes expected) | ||
list(REMOVE_ITEM sources ${dupes}) | ||
list(LENGTH sources after) | ||
math(EXPR actual "${before} - ${after}") | ||
message(STATUS "${module} with ${expected} sources took ${actual} sources from ${library}") | ||
set_target_properties(${library} PROPERTIES SOURCES "${sources}") | ||
target_link_libraries(${library} ${scope} ${module}) | ||
endforeach() | ||
endfunction() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is probably not needed ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, upon some testing, this whole
target_include_directories
seem to be not needed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not needed now that all of the subdirectories in libxrpl are modules. It was necessary as I migrated them one-by-one, and it could be necessary in the future if someone adds a non-module subdirectory. Could be nice if it "just works" without tampering with the CMake. What do you think?