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

fix: Partial fix for FetchContent #36

Merged
merged 3 commits into from
Jun 14, 2023
Merged

Conversation

LecrisUT
Copy link
Contributor

Partial fix for FetchContent issue regarding:

CMake Error in CMakeLists.txt:
  Target "fdict" contains relative path in its INTERFACE_INCLUDE_DIRECTORIES:

Issue is that generator expression should not have quotation marks there. A few other issues here are:

  • Use CMake_Fortran_MODULE_DIRECTORY instead of setting the specific target property. This makes it consistent with downstream user's configuration
  • target_include_directories should be PUBLIC, not INTERFACE there. I.e. the library should be using it as well. This is a compiler dependent behaviour because some might be automatically be using Fortran_MODULE_DIRECTOR or not, and this addresses the issue of the latter

Note on the "partial" fix. This is because the install interface is not fixed yet according to #32

Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
- Move `Fortran_MODULE_DIRECTORY` to global `CMAKE_Fortran_MODULE_DIRECTORY` option
- Fix wrong usage of quotes in generator expression

Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
# This is to avoid name-clashing (similar to how C projects structure their include)
install(FILES
${CMAKE_Fortran_MODULE_DIRECTORY}/dictionary.mod
${CMAKE_Fortran_MODULE_DIRECTORY}/variable.mod
Copy link
Owner

Choose a reason for hiding this comment

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

Add quotation for paths with spaces

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See earlier disccussion

src/CMakeLists.txt Outdated Show resolved Hide resolved
)

# Install all modules (omitting the directory)
install(DIRECTORY "${LIB_MOD_DIR}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
# TODO: Move to single module interface and move the other modules to subfolder
# This is to avoid name-clashing (similar to how C projects structure their include)
Copy link
Owner

Choose a reason for hiding this comment

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

What do you meen here? Currently all modules from fdict is exposed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The convention in C/C++ projects is to install only 1 header file per project with a unique name. In cases where multiple header files are needed (header only libraries for example), than all the header files are in a subdirectory with the unique name of the project. Otherwise when you install another project that has similar header file names, they will overwrite each other and become unusable.

Same convention applies here. There is a potential of overlap with another project that uses variable.mod for example. In this case, simply add both ${CMAKE_Fortran_MODULE_DIRECTORY} and ${CMAKE_Fortran_MODULE_DIRECTORY}/fdict to the target_include_directories(), then depending on which target_link_libraries, the appropriate modules are used.

Copy link
Owner

Choose a reason for hiding this comment

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

Ah, I see.

@@ -9,6 +9,10 @@ project(fdict
DESCRIPTION "Fortran dictionary for arbitrary data-types"
)

if (NOT DEFINED CMAKE_Fortran_MODULE_DIRECTORY)
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fortran_modules)
Copy link
Owner

Choose a reason for hiding this comment

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

add quotation, to ensure paths with spaces

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have tested locally and the quotation does not appear to be necessary. In general I would avoid quotations where unnecessary (in this case the variable CMAKE_CURRENT_BINARY_DIR is already sanitized to be a string) because sometimes the quotations are taken to be literal (as you've seen here in the generator expression). My rule of thumb is to sanitize everything at the set(), option() level rather than where the variables are used.

Copy link
Owner

Choose a reason for hiding this comment

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

I see, this is something where CMake is horrible, it is hard to know why some of the expansions works seamlessly, and others are problematic... Hence my guarding was just to put quotation everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I fully agree. This is a relic of the original cmake design, and although there are rumors that the lead devs are working on a more robust, non text-based interface for camke 4, these are here to stay :(.

I was doing the same thing until I had various things break down because of the quotation. I realized though that most cmake commands are designed to work on variables (e.g. the if() command), so I work on the assumption that most commands are designed and tested to work for unquoted formats, and just use the quotation when it is needed to enforce it.

@zerothi
Copy link
Owner

zerothi commented Jun 12, 2023

Thanks for your PR! Some minor details

Signed-off-by: Cristian Le <cristian.le@mpsd.mpg.de>
@LecrisUT
Copy link
Contributor Author

  • I have removed some redundant CMAKE_CURRENT_BINARY_DIR, CMAKE_CURRENT_SOURCE_DIR to make the listsfile more readable. Those are implicit where I have removed them
  • Added a bit more TODOs about modern practices.
  • There are more issues that I want to address in a separate PR, e.g. using project(VERSION), incorrect usage of write_basic_package_version_file(COMPATIBILITY)

Copy link
Owner

@zerothi zerothi left a comment

Choose a reason for hiding this comment

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

I'll fix the remaining issues.

CMakeLists.txt Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
@zerothi zerothi merged commit 50df9d8 into zerothi:main Jun 14, 2023
@zerothi
Copy link
Owner

zerothi commented Jun 14, 2023

* There are more issues that I want to address in a separate PR, e.g. using `project(VERSION)`, incorrect usage of `write_basic_package_version_file(COMPATIBILITY)`

Don't add the project(VERSION) it is annoying it doesn't allow arbitrary version specification. For instance with git-hashes.

And why is the write_basic_package_version_file wrong? That is how it is documented: https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#generating-a-package-version-file

@LecrisUT
Copy link
Contributor Author

* There are more issues that I want to address in a separate PR, e.g. using `project(VERSION)`, incorrect usage of `write_basic_package_version_file(COMPATIBILITY)`

Don't add the project(VERSION) it is annoying it doesn't allow arbitrary version specification. For instance with git-hashes.

Hmm good point. But the version tells you about the release intent with e.g. major change telling you that api has breaking changes. Git hashes are only for development, but I can see why that can be useful. How about exporting that information manually. It is highly advised to use project(VERSION) because that sets and resets both PROJECT_VERSION and fdict_VERSION as well as do any sanitization so that this can be used by any other cmake projects downstream.

(Btw I have a cmake project to get and set the project version directly from git/git archive, compatible with python's setuptools_scm setup files)

And why is the write_basic_package_version_file wrong? That is how it is documented: https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#generating-a-package-version-file

That ony controls the cmake find_package(fdict 0.3) syntax, telling the user if the apis are compatible or not. It does not control the actual linkage of the libraries so in that sense it is abi independent. The library linkage is done by the os and the compiler and cmake has no say or way to enforce library version compatibility. Or in other words, COMPATIBILITY tells if the cmake projects are compatible, not if the compilers or libraries used are compatible.

@LecrisUT LecrisUT deleted the fix/fetchcontent branch June 14, 2023 08:40
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