CMake, Flang, and fPIC

To the gurus here: Is there anything “special” I need to do to enable fPIC/fPIE with Flang?

I ask because this simple project:

cmake_minimum_required(VERSION 3.24)
project(test LANGUAGES Fortran)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_executable(test test.F90)

doesn’t seem to do it for flang. To wit:

> cmake -B build -S . --install-prefix=$(pwd)/install --fresh
-- The Fortran compiler identification is LLVMFlang 22.0.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /discover/nobackup/projects/gmao/SIteam/comp/SLES-15/llvm-flang/2025-10-14/bin/flang - skipped
-- Configuring done (10.9s)
-- Generating done (0.0s)
-- Build files have been written to: /home/mathomp4/LLVM-CMake-FPIC/build
> tail -n 2 build/CMakeFiles/test.dir/flags.make
Fortran_FLAGS =

But if I run with gcc 15 or ifx:

> tail -n 2 build/CMakeFiles/test.dir/flags.make
Fortran_FLAGS = -fPIE

or with NAG:

> tail -n 2 build/CMakeFiles/test.dir/flags.make
Fortran_FLAGS = -PIC

I tried staring at the source and I see that Flang-Fortran.cmake has an include(Compiler/Clang), and that file does have some PIC/PIE stuff in it., but it’s a bit more convoluted than, say, the NAG-Fortran.cmake file.

Is it just that LLVM is “different” and maybe PIC is on by default? Not sure.

I will note that flang seems to not dislike the flags:

> flang -fPIC test.F90
> echo $?
0
> flang -fPIE test.F90
> echo $?
0

Take a look at the CheckPIESupported module.

Well, I just added:

message(CHECK_START "Checking for Fortran linker PIE support")

include(CheckPIESupported)
check_pie_supported(OUTPUT_VARIABLE output LANGUAGES Fortran)
set_property(TARGET test PROPERTY POSITION_INDEPENDENT_CODE TRUE)

if(CMAKE_Fortran_LINK_PIE_SUPPORTED)
  message(CHECK_PASS "yes")
else()
  message(CHECK_FAIL "no")
  message(VERBOSE "PIE is not supported at link time:\n${output}"
                  "PIE link options will not be passed to linker.")
endif()

and I get:

> cmake -B build -S . --install-prefix=$(pwd)/install --fresh
-- The Fortran compiler identification is LLVMFlang 22.0.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /discover/nobackup/projects/gmao/SIteam/comp/SLES-15/llvm-flang/2025-10-14/bin/flang - skipped
-- Checking for Fortran linker PIE support
-- Checking for Fortran linker PIE support - no
-- Configuring done (7.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/mathomp4/LLVM-CMake-FPIC/build

So huh. flang supports -fPIC and or -fPIE on the command line, but not via CMake? :man_shrugging:

I have the feeling that there is a confusion between two compilers: You mention the file Modules/Compiler/Flang-Fortran.cmake but, from the log, I see that the compiler identification is LLVMFLang. The associated configuration file is Modules/Compiler/LLVMFLang-Fortran.cmake.

And this file does not set the expected variables for the PIE configuration…

Can you check the availability of variables CMAKE_Fortran_COMPILE_OPTIONS_PIE, CMAKE_Fortran_LINK_OPTIONS_PIE and CMAKE_Fortran_LINK_OPTIONS_NO_PIE?.

Sigh. So many flang! :slight_smile:

You are right LLVMFlang-Fortran.cmake is sort of on the level of the NAG File!

Well, I could make a PR with:

set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "-fPIE")

Let me do some proving to myself that the flags work…

For a correct configuration for PIE, use, for example, Modules/Compiler/GNU.cmake file (especially the variable _CMAKE_Fortran_PIE_MAY_BE_SUPPORTED_BY_LINKER).

Well, I just tried to prove it’s needed and…I couldn’t. That is I didn’t get the usual:

relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC

like message I’ve grown to know and love.

So, huh. I wonder if LLVM Flang ‘automatically’ adds -fPIC like functionality underneath?

Heck, I just tried my “I think this should let me be confident” and forced it to use -fno-PIC and -fno-PIE thinking, “well, that’ll do it” and it also worked.

So maybe this is all moot? LLVM Flang is advanced enough now to not need PIC/PIE?

Maybe, by default, PIC and PIE are activated. But are these options supported by the compiler/linker? As well as the option to deactivate PIE at link step.