Skip to content

Build matrix based on cmake#74

Closed
giallu wants to merge 28 commits intoIUPAC-InChI:devfrom
giallu:build_matrix
Closed

Build matrix based on cmake#74
giallu wants to merge 28 commits intoIUPAC-InChI:devfrom
giallu:build_matrix

Conversation

@giallu
Copy link
Contributor

@giallu giallu commented Jan 14, 2025

This commits add a GH workflow to build and run tests in several (Ubuntu 22.04, Windows 2019, OSX) operating systems at once, including Alpine (build only) and gcc-latest image.

Some notes:

  • the build is based on my port_to_cmake branch, so we can work on this and close Move build system to cmake #37
  • the original build system is untouched so both can live in parallel until the project decide if going cmake-only is viable
  • every build uses the native compilers (Ubuntu -> gcc, Windows -> MSVC, OSX -> clang)
  • there are few commits to fix build issues I found: de05b50, 9ca7c52, 80955ae, 3bdb6b6

@giallu giallu mentioned this pull request Jan 14, 2025
Copy link
Collaborator

@JanCBrammer JanCBrammer left a comment

Choose a reason for hiding this comment

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

I tested the steps "Build InChI" (line 45 in build.yml) followed by "Run executable tests) (line 67) locally in the devcontainer. I needed to install ninja-build in the devcontainer for the compilation to work. I.e., we should install ninja-build along with the other test dependencies:

apt update && apt install -y python3-pip cmake

The artifacts (executable and shared library) are built successfully and the tests pass.
I can also confirm that all artifacts (executable and shared library) have been uploaded from the latest workflow run: https://github.com/giallu/InChI/actions/runs/12657834492.

As an aside, I rebased build_matrix onto the latest main locally and didn't encounter any issues.

@djb-rwth, are there any compilation behaviors that are configured in the current makefiles, which are not reproduced by CMake? If so, and if we want to preserve those behaviors, how can we reproduce them with CMake?

*.egg-info/
# Ignore core dump files
core.*[0-9]
gcc_crash_report.txt
Copy link
Collaborator

Choose a reason for hiding this comment

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

gcc_crash_report.txt used to be on main at the time build_matrix was branched off. It has since been removed.


project(
inchi
VERSION 1.07
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have to think about how to parametrize the version. Preferably we would have a single source of truth for the version. But maybe outside of this PR's scope.

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 agree on the single source for the version string; I guess it is possible to use several approaches, depending on how the release is handled: it can be read from a file, an env variable, from a workflow context variable, etc.

I would just avoid putting it in the sources, it's harder to extract for other tools and usually harder to find.

add_subdirectory( INCHI-1-SRC/INCHI_API/demos/test_ixa/src )
add_subdirectory( INCHI-1-SRC/INCHI_EXE/inchi-1/src )

add_custom_target( run-tests
Copy link
Collaborator

Choose a reason for hiding this comment

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

I will add a target for running the tests against the shared library as well.
Since this will require some refactoring of the test environment I'd prefer to do so in another PR in order to not bloat the present one.

@JanCBrammer JanCBrammer requested a review from djb-rwth January 23, 2025 12:44
@djb-rwth
Copy link
Collaborator

djb-rwth commented Feb 4, 2025

Hi @giallu,
Thank you for the revisions of your initial PR.

I would like to like to draw your attention to some very important issues:

  1. InChI CLI (INCHI_EXE), InChI API (INCHI_API/libinchi), and sub-projects located in INCHI_API/demos folder should be compiled separately, just as they had been created. Conseqently, each sub-project has to be provided with a separate CMake build system.
  2. No code should be displaced from one file to another at this moment, especially the parts of the source code from the files that are used in almost all projects (within folder INCHI_BASE/src) to files which are project-specific (e.g. INCHI_EXE/inchi-1/src). We have to take into account that numerous users include just selected .c/.h files from the InChI project in their software development (the majority of which we do not have any access to), hence keeping the source code structure as intact as possible should be one of the primary goals.
  3. Compiler-specific flags/optimisations and linker-specific flags should fully correspond to the current build systems, namely Microsoft Visual Studio solutions and makefile/makefile32s. This is important because we had experienced some issues with the GCC compiler's optimisation flags, and with GCC compilers on Microsoft Windows platforms where Microsoft Visual Studio is not present. Also, the consistency of different build solutions is preferable for performance homogeneousness. This task can be completed using CMake 3.18+ versions.
  4. In line with item 3., specific extensions for libinchi libraries should be produced for different OSs: .dlls on Microsoft Windows, and .so.<INCHI_VERSION>s files on other OSs.

This will require a review of this PR, or even creating a new PR if many changes are needed.

You are more than welcome to participate in creating, reviewing and/or testing this revised CMake build system.

@JanCBrammer JanCBrammer force-pushed the rwth branch 2 times, most recently from 6d97b2d to fb1f8b1 Compare February 12, 2025 13:59
@giallu
Copy link
Contributor Author

giallu commented Feb 14, 2025

Thanks @djb-rwth for the review. My remarks follow:

  1. InChI CLI (INCHI_EXE), InChI API (INCHI_API/libinchi), and sub-projects located in INCHI_API/demos folder should be compiled separately, just as they had been created. Conseqently, each sub-project has to be provided with a separate CMake build system.

While in theory you can reproduce 1:1 the current situation, I wouldn't recommend it for at least two reasons:

  • is not the expectation of anyone using cmake. With any IDE, you just want to open the project's cmake main file and see all the targets it defines (usually, libraries and executables), decide what to compile/run/debug and go. No one digs the subdirectories in search of other root project files.
  • a single project file makes it trivial to build a library and link to it. if you split the subprojects then you need to bake into them the logic to find the main library, leading to path hardcoding and duplicate definitions, and generally speaking an harder developer experience.
  1. No code should be displaced from one file to another at this moment, especially the parts of the source code from the files that are used in almost all projects (within folder INCHI_BASE/src) to files which are project-specific (e.g. INCHI_EXE/inchi-1/src). We have to take into account that numerous users include just selected .c/.h files from the InChI project in their software development (the majority of which we do not have any access to), hence keeping the source code structure as intact as possible should be one of the primary goals.

That commit was part of another PR #55, and is needed otherwise the build fails (see details in the other PR).
Besides, I don't think one can take a random .c/.h file from inchi and include it in another project because the dependencies between them will not allow it; in fact I believe the only two ways of using inchi code in other projects are by copy/pasting a specific function (assuming it doesn't call any other function) or by linking the whole library, and neither are affected by where the code is located in the sources.
By the way, If the project has a policy on the source code like "no function can be renamed" or "no function can be moved from a file to another" I suggest this should be prominently shown on the developers documentation

  1. Compiler-specific flags/optimisations and linker-specific flags should fully correspond to the current build systems, namely Microsoft Visual Studio solutions and makefile/makefile32s. This is important because we had experienced some issues with the GCC compiler's optimisation flags, and with GCC compilers on Microsoft Windows platforms where Microsoft Visual Studio is not present. Also, the consistency of different build solutions is preferable for performance homogeneousness. This task can be completed using CMake 3.18+ versions.

Cmake maintains a list of supported features and standards for each compiler. It's usually a good idea to leave to cmake the work of deciding which flags to pass to compilers and linkers, unless absolutely necessary; however, if the project wants to maintain specific settings for certain combinations of OS/compilers it is possible using the Presets feature

Since it does not directly affect the topic of this PR I suggest to discuss it in a new issue to be opened after the merge.

  1. In line with item 3., specific extensions for libinchi libraries should be produced for different OSs: .dlls on Microsoft Windows, and .so.<INCHI_VERSION>s files on other OSs.

I think this is already working this way

@djb-rwth
Copy link
Collaborator

Hi @giallu,
Thanks for your reply.
Please refer to my comments below:

While in theory you can reproduce 1:1 the current situation, I wouldn't recommend it for at least two reasons:

  • is not the expectation of anyone using cmake. With any IDE, you just want to open the project's cmake main file and see all the targets it defines (usually, libraries and executables), decide what to compile/run/debug and go. No one digs the subdirectories in search of other root project files.

I am not convinced about this. Many users would just probably like to have an alternative build system to Make and Microsoft Visual Studio, and be engaged in configuring a CMake project as less as possible.

InChI is not a novel project and since its inception has consisted of several sub-projects, which the majority of users are already acquainted with. Moreover, many users are focused just on just one sub-project, and are not familiar with CMake build system at all.

At this moment, users can easily open a Microsoft Visual Studio project on Windows OS or use a Make build system just by typing make in their CL on other OSs; everything else is more-or-less already preconfigured.
My aim is to provide the same user experience with CMake.

  • a single project file makes it trivial to build a library and link to it. if you split the subprojects then you need to bake into them the logic to find the main library, leading to path hardcoding and duplicate definitions, and generally speaking an harder developer experience.

I do not see the reason why would there be any other library except (shared) libinchi.dll/libinchi.so.1.07/libinchi.1.07.dylib; I am aware that "meta-libraries" make things easier for developers, but I am sure this project can be built without them. Also, I do not expect the occurrence of either any duplicate definitions or conflicts between main libraries, esp. if only one (shared) library exists.

Adding a "wrapper" CMake build option for all sub-projects can be added to the INCHI-1-SRC root.

That commit was part of another PR #55, and is needed otherwise the build fails (see details in the other PR). Besides, I don't think one can take a random .c/.h file from inchi and include it in another project because the dependencies between them will not allow it; in fact I believe the only two ways of using inchi code in other projects are by copy/pasting a specific function (assuming it doesn't call any other function) or by linking the whole library, and neither are affected by where the code is located in the sources.

I have already started to build a separate CMake build system for InChI CLI without touching the source code, and thus far none of the build failures mentioned in issue #55 have been encountered -- at least not on Microsoft Windows or Ubuntu Linux.

Various users have reported that parts of the InChI code are indeed "copy-pasted" in their development environments. On the other hand, files within INCHI-1-SRC/INCHI_BASE have been used without any changes in many projects such as wInChI without any other files from the project; consequently, extracting any code from the files in this folder might compromise the functionality of these kinds of projects, especially if they are placed in project-specific files (e.g. from INCHI_BASE to INCHI_EXE). Since we do not have an insight in the majority of development frameworks using InChI, we cannot be sure which files are used, how and where.
In addition, the major issue of legacy surfaces again.

By the way, If the project has a policy on the source code like "no function can be renamed" or "no function can be moved from a file to another" I suggest this should be prominently shown on the developers documentation

With all the above in mind, I think that might be a good idea in the foreseeable future.

Cmake maintains a list of supported features and standards for each compiler. It's usually a good idea to leave to cmake the work of deciding which flags to pass to compilers and linkers, unless absolutely necessary; however, if the project wants to maintain specific settings for certain combinations of OS/compilers it is possible using the Presets feature

The default CMake compiler options probably fulfill the basic needs of a large share of projects, but in some projects such as InChI, can create a real mess, esp. performance-wise. For example, CMake build system's default compiler options apply RTC1 runtime error check in the (default) Debug mode if MSVC compiler is detected, which is in conflict with O2 and O1 compiler optimisiations. Also, applying certain linker flags to inchi_main ELF file is essential for its proper functionality if compiled with GCC on Linux (this can be simply tested with InChI_TestSet_ext.sdf input as it produces 75 errors instead of warnings).

Fortunately, new versions of CMake offer a plenty of possibilities for compiler and linker options tweaking, which is IMHO one of CMake's major strengths.
All of these tweaks can be added to CMakefiles themselves; the presets are commonly used for exporting CMake settings to another system.

Since it does not directly affect the topic of this PR I suggest to discuss it in a new issue to be opened after the merge.

I agree.

  1. In line with item 3., specific extensions for libinchi libraries should be produced for different OSs: .dlls on Microsoft Windows, and .so.<INCHI_VERSION>s files on other OSs.

I think this is already working this way

According to this PR, the shared libinchi library is generated as libinchi.so.1 instead of libinchi.so.1.07. This can be amended very easily.

@JanCBrammer JanCBrammer force-pushed the dev branch 2 times, most recently from 2fb8edb to d863ffc Compare August 25, 2025 13:17
@djb-rwth djb-rwth closed this Sep 3, 2025
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.

3 participants