chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.78k stars 420 forks source link

Support for CMake build systems when using Chapel/C interop #20243

Closed brandon-neth closed 2 years ago

brandon-neth commented 2 years ago

I've been working on porting parts of Parflow (https://github.com/parflow/parflow) to Chapel. This has meant utilizing the C interop capabilities of Chapel.

The Chapel compiler supports generating Makefile definitions for these interop libraries using the --library-makefile flag on the compiler. However, Parflow uses CMake as its build system, so the generated definitions can not easily be incorporated into the Parflow build.

I'm proposing a similar flag, --library-cmakelists that generates a CMakeList.txt file containing the same definitions as the generated makefiles, but in CMake syntax. Then, linking it into the existing CMake system is as simple as an "include()" and a couple of target linking commands that will be included as comments to the generated file.

brandon-neth commented 2 years ago

I tagged this easy / straightforward bc I think itll be a simple replacement from the existing Makefile generation code, but I don't actually know that for sure

brandon-neth commented 2 years ago

Some relevant existing code:

The makefile generation has a couple of steps which I'm thinking will be mirrored pretty directly for a CMakeLists generator:

  1. Build filename and create file
  2. Print statements that set the environment variables
  3. Print statements that set the include flags
  4. Print statements that set the link flags
  5. Print statements that set the compiler and linker chapel used
  6. Close the file

Filename

For a CMake system, I've never seen the filename be anything other than CMakeLists.txt, so I think it'd be good to stick to that standard. This simplifies step 1.

Environment Variables

For step 2, the values of the variables are the same. All that is different is the syntax. For CMake, we would do set(CHPL_RUNTIME_LIB <path>) rather than CHPL_RUNTIME_LIB=<path>. For this we can create a setupCMakeEnvVars thats based on the setupMakeEnvVars but with the correct syntax.

Include Directories

For step 3, the situation is slightly different. For Makefiles, the necessary include directory flags are set to the CHPL_CFLAGS variable. With CMake, the command to add include directories is target_include_directories. Docs here: https://cmake.org/cmake/help/latest/command/target_include_directories.html.

While the Makefile flags include the -I at the beginning, when using target_include_directories only the path is provided. Further, you can add multiple include directories at once. So rather than using the flags -Ipath/to/thing1 -Ipath/to/thing2 you would write something like target_include_directories(myTarget PUBLIC path/to/thing1 path/to/thing2).

Thus, because the printMakefileIncludes function generates flags, the printCMakeListsIncludes will differ more significantly. Also, rather than generating the calls to target_include_directories, my plan is to define another variable, CHPL_INCLUDE_DIRS to the list of necessary include directories. This will allow the programmer to insert target_include_directories(TargetName PRIVATE ${CHPL_INCLUDE_DIRS}) where they please.

Link Directories

target_link_libraries (https://cmake.org/cmake/help/latest/command/target_link_libraries.html) allows link flags directly, so a CHPL_LINK_LIBS variable can be set to the flags generated by the printMakefileLibraries. The CHPL_LINK_LIBS variable will be used similarly to the CHPL_INCLUDE_DIRS but with the target_link_libraries command rather than target_include_directories.

Compiler and Linker

These can be pretty much the same as the Makefile versions.

Tasks

brandon-neth commented 2 years ago

While I've written the actual test files, I'm still working on integrating them into the testing system. Ben H helped me figure out how the makefile interop tests work (the .prediff files basically run the commands and write to the comparison file) so I'm now set to get this one going

milthorpe commented 8 months ago

Right now, CMake seems almost impossible to set up for Chapel because CMake assumes separate compilation and linking steps, which the chpl compiler does not support. I expect this might change in Chapel 1.34, as the 'dyno' work plan includes support for separate compilation.