libprima / prima

PRIMA is a package for solving general nonlinear optimization problems without using derivatives. It provides the reference implementation for Powell's derivative-free optimization methods, i.e., COBYLA, UOBYQA, NEWUOA, BOBYQA, and LINCOA. PRIMA means Reference Implementation for Powell's methods with Modernization and Amelioration, P for Powell.
http://libprima.net
BSD 3-Clause "New" or "Revised" License
296 stars 38 forks source link

CMake had difficulty finding the Fortran compiler #53

Closed zaikunzhang closed 12 months ago

zaikunzhang commented 12 months ago

Hi @jschueller ,

Could you fix this? See https://fortran-lang.discourse.group/t/prima-cmake-building-system-and-c-interface-available/6499/3?u=zaikunzhang

Excellent work. The organization and code/documentation quality is remarkable. I just built the library in WSL. CMake had difficulty finding the Fortran compiler with -- The Fortran compiler identification is unknown, despite having 5 Fortran compilers in the OS bin directory. I could readily solve it by specifying -DCMAKE_Fortran_COMPILER=/usr/bin/gfortran-13. This may be an exception, but it might be worth having a brief troubleshooting discussion in the installation guidelines just in case people unfamiliar with Fortran or CMake face the same problem. I have used Powell methods in the past and look forward to using the modernized version in the coming months.

This reminds me of the following, which I hope you could also kindly handle. We should provide options so that users can choose to

Of course, since the C library depends on the Fortran one (before we have a pure C implementation), the second case would necessitate the compilation of the Fortran library as well, but the user does not need to say so.

Why do we separate these cases? Because a Fortran user does not necessarily have a C compiler installed. Anyway, he/she does not intend to use the C library, so it is illogical (indeed confusing) to compile it.

Thank you very much for taking care of these.

Best regards, Zaikun

jschueller commented 12 months ago
zaikunzhang commented 12 months ago
  • cmake will only find compilers in the PATH with default names, I think it will be fine if there was a gfortran symlink

I have sent this to @shahmoradi and invited him to join the conversation.

How does CMake decide the default name of a compiler (or tell whether something is a Fortran compiler in the first place?) Does it look up a list? Thanks.

Since @shahmoradi has five compilers installed in the system bin, there is a good chance that at least one of them is in the PATH with default names.

jschueller commented 12 months ago

I guess it looks through standard names, for example in the CI jobs I never had to specify the compiler location as it was always found.

zaikunzhang commented 12 months ago

*there is already a cmake option PRIMA_ENABLE_C=ON/OFF to disable the C binding

I removed /usr/bin/gcc and some other C compilers on my computer. Doing

$git clone --depth 1 https://github.com/libprima/prima.git
cd prima
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=OFF -DPRIMA_ENABLE_C=OFF  
cmake --build build --target install

I got the following:

Cloning into 'prima'...
remote: Enumerating objects: 907, done.
remote: Counting objects: 100% (907/907), done.
remote: Compressing objects: 100% (733/733), done.
remote: Total 907 (delta 416), reused 464 (delta 154), pack-reused 0
Receiving objects: 100% (907/907), 6.20 MiB | 1.74 MiB/s, done.
Resolving deltas: 100% (416/416), done.
-- The C compiler identification is unknown
-- The Fortran compiler identification is GNU 13.1.0
CMake Error at CMakeLists.txt:5 (project):
  No CMAKE_C_COMPILER could be found.

  Tell CMake where to find the compiler by setting either the environment
  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
  the compiler, or to the compiler name if it is in the PATH.

-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /usr/bin/f95 - skipped
-- Configuring incomplete, errors occurred!
See also "/home/zaikunzhang/tmp/prima/build/CMakeFiles/CMakeOutput.log".
See also "/home/zaikunzhang/tmp/prima/build/CMakeFiles/CMakeError.log".
gmake: Makefile: No such file or directory
gmake: *** No rule to make target 'Makefile'.  Stop.

If did not misunderstand, even with -DPRIMA_ENABLE_C=OFF, cmake still looks for a C compiler, and fails if no such compiler exists. Is this reasonable?

jschueller commented 12 months ago

I guess we could defer the detection of the C compiler, but ihmo its hard to find a machine with a Fortran compiler but without C compiler :]

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0916733..c8c0d92c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.13)

 set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")

-project (prima C Fortran)
+project (prima Fortran)

 option (BUILD_SHARED_LIBS "shared/static" ON)
 if (WIN32)
@@ -45,6 +45,7 @@ add_subdirectory(fortran)

 option (PRIMA_ENABLE_C "C binding" ON)
 if (PRIMA_ENABLE_C)
+  enable_language(C)
   add_subdirectory(c)
   set(primac_target "primac")
 endif ()
zaikunzhang commented 12 months ago

ihmo its hard to find a machine with a Fortran compiler but without C compiler :]

Agree. But logically, it is still better to check the C compiler only when needed. After your new PR, it works now.

BTW, I saw -- Performing Test HAVE_WARN_EXECSTACK - Failed. Should I worry?

jschueller commented 12 months ago

no, its probably just a bit too old

zaikunzhang commented 12 months ago

no, its probably just a bit too old

Who is "it"?

jschueller commented 12 months ago

your compiler

zaikunzhang commented 12 months ago

I modified README for this issue:

https://github.com/libprima/prima/blob/7565f6f42358062e56734a91fc62e0aa66ab7575/README.md?plain=1#L217-L219

Is it correct?

jschueller commented 12 months ago

yes