Thanks to visit codestin.com
Credit goes to github.com

Skip to content

cmake: Use CMake targets #6872

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

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open

cmake: Use CMake targets #6872

wants to merge 43 commits into from

Conversation

flagarde
Copy link

This PR generalise the use of targets. One of the goal is to allow libgit2 to be included upstream using FetchContent mechanism and to better express target dependencies.

Up to now libgit2 use variables to populate header path and libraries to the targets like :

set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE)
set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE)
set(LIBGIT2_DEPENDENCY_INCLUDES ${LIBGIT2_DEPENDENCY_INCLUDES} PARENT_SCOPE)
set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE)
set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE)
set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE)

using INTERFACE targets for external dependencies allow to wrap these informations. This is the favorite methode for post CMake 3.0 and allow better encapsulation.

For this to work (especially in CMake ~< 3.13), libraries in libgit2 should be STATIC or SHARED. The use of OBJECT is discouraged even by CMake developpers https://discourse.cmake.org/t/project-modularization-using-object-libraries/3825/5 and it seems libgit2 don't need their use.

This PR compiles and passes the tests but a second one would be necessary to polish and clean some useless variables not needed anymore

Copy link
Member

@ethomson ethomson left a comment

Choose a reason for hiding this comment

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

Thanks for putting this together. cmake is not exactly my forte, but I think that directionally, this probably makes sense. I had a few stylistic questions:

This moves us from using globs / wildcards to match always to usually not using globs. Why (or when) is explicitly listing the source files preferred?

It seems like we're needing to specify more of the libraries than I would have expected. I don't understand it yet.

list(SORT SRC_XDIFF)

add_library(xdiff OBJECT ${SRC_XDIFF})
add_library(xdiff STATIC
Copy link
Member

Choose a reason for hiding this comment

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

Why is this preferable to just using a glob?

Copy link
Author

Choose a reason for hiding this comment

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

CMake recommands to avoid GLOB especially with source files :

https://cmake.org/cmake/help/latest/command/file.html#glob
``
Note

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. The CONFIGURE_DEPENDS flag may not work reliably on all generators, or if a new generator is added in the future that cannot support it, projects using it will be stuck. Even if CONFIGURE_DEPENDS works reliably, there is still a cost to perform the check on every rebuild.
``

I made the changes in some places when I had to modify a lot the CMake logic. However it should be possiblle to supress all the GLOBs. This is quite easy and could be finish in an other dedicated PR.

@@ -157,11 +159,9 @@ endif()

if(USE_THREADS)
if(NOT WIN32)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
Copy link
Member

Choose a reason for hiding this comment

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

TODO: what is this?

Copy link
Author

Choose a reason for hiding this comment

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

CMake advices to use set this variable to TRUE :

https://cmake.org/cmake/help/latest/module/FindThreads.html

To be honnest I don't know why adding the flag -pthread is better but it seems encouraged by CMake.

@@ -1,20 +1,89 @@
# util: a shared library for common utility functions for libgit2 projects
configure_file(git2_features.h.in git2_features.h)

add_library(util STATIC
Copy link
Member

Choose a reason for hiding this comment

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

Same question here - why is this preferred over a glob?


if(MSVC)
target_compile_definitions(libgit2_pcre PRIVATE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS)
Copy link
Member

Choose a reason for hiding this comment

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

Inconsistent indentation here...

transports/*.c transports/*.h)
list(SORT SRC_GIT2)

add_library(libgit2 STATIC ${SRC_GIT2})
Copy link
Member

Choose a reason for hiding this comment

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

This was a bit confusing when we had an object library called libgit2, but (I think) it was only referenced as "$<TARGET_OBJECTS:libgit2>" so it wasn't so bad... now (I think) we are doing things like target_link_libraries(... libgit2). But that libgit2 refers (I think) to this libgit2, not the actual... libgit2. 🫤

Also, this produces a liblibgit2.a on disk which is not very attractive. Even if it is an intermediate step that consumers don't see, I think that we can improve this.

git2common or something? idk, maybe you have a better idea here.

Copy link
Author

Choose a reason for hiding this comment

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

If I understand correclty a shared library canot be used for some reason. If so if user wants a shared library libgit2.so we could compile shared and static (with name libgit2_static) and link specificly wiith the later and install the former. If user wants only static then libgit2.a could be used for both uses. I guess this could be solve in an other PR ?

add_library(libgit2 OBJECT)
set_target_properties(libgit2 PROPERTIES C_STANDARD 90)
set_target_properties(libgit2 PROPERTIES C_EXTENSIONS OFF)
file(GLOB SRC_GIT2 *.c *.h
Copy link
Member

Choose a reason for hiding this comment

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

Why glob here?

Copy link
Author

Choose a reason for hiding this comment

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

this GLOB should dissappear (cf. previous comments)

@ethomson
Copy link
Member

Hi @flagarde - thanks for the details (and for your patience with my limited understanding of cmake, and my hurried PR review, where I still left TODO comments for myself 😢

I am excited about improving our cmake configuration, so I'll 👀 this soon. 🙏

@ethomson ethomson mentioned this pull request Dec 23, 2024
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