How to link a gfortran static library?
-
Hi, I saw this post below:
Re: [SOLVED] Compiling Fortran code with gfortran within a C++ project
I added the
@LIBS += -lgfortran@
in my *.pro file, but I still got a lot of linking errors like:undefined reference to `_gfortran_date_and_time' undefined reference to `_gfortran_st_write' undefined reference to `_gfortran_adjustl' undefined reference to `_gfortran_transfer_integer_write'
I added my static Fortran library by Qt Creator IDE Wizard, and it added these lines in my *.pro file:
unix:!macx: LIBS += -L$$PWD/../test/ -lmylib INCLUDEPATH += $$PWD/../test DEPENDPATH += $$PWD/../test unix:!macx: PRE_TARGETDEPS += $$PWD/../test/libmylib.a
How can I solve it?
-
Hi,
Might be a silly question but are the architectures compatible ?
-
Hi, I saw this post below:
Re: [SOLVED] Compiling Fortran code with gfortran within a C++ project
I added the
@LIBS += -lgfortran@
in my *.pro file, but I still got a lot of linking errors like:undefined reference to `_gfortran_date_and_time' undefined reference to `_gfortran_st_write' undefined reference to `_gfortran_adjustl' undefined reference to `_gfortran_transfer_integer_write'
I added my static Fortran library by Qt Creator IDE Wizard, and it added these lines in my *.pro file:
unix:!macx: LIBS += -L$$PWD/../test/ -lmylib INCLUDEPATH += $$PWD/../test DEPENDPATH += $$PWD/../test unix:!macx: PRE_TARGETDEPS += $$PWD/../test/libmylib.a
How can I solve it?
@fem_dev said in How to link a gfortran static library?:
I added the @LIBS += -lgfortran@ in my *.pro file
In which pro file? You should add this to the application project file, which I don't see in the snippet you provided.
-
@fem_dev said in How to link a gfortran static library?:
I added the @LIBS += -lgfortran@ in my *.pro file
In which pro file? You should add this to the application project file, which I don't see in the snippet you provided.
@kshegunov I compile my Fortran code using Ubuntu terminal and gfortran...
// Compile and get *.o file: gfortran -c -g fortran.f90 // Add *.o file to a Linux library *.a ar cr libmylib.a *.o // (Optional) Add internal library object indexes: ranlib libmylib.a
So, I copied this library file
libmylib.a
to my Qt C++ application folder and added it to my Qt project using Qt Creator IDE WizardMy Qt C++ Application PRO file:
QT -= gui CONFIG += c++11 console CONFIG -= app_bundle @LIBS += -lgfortran@ # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target unix:!macx: LIBS += -L$$PWD/../test/ -lmylib INCLUDEPATH += $$PWD/../test DEPENDPATH += $$PWD/../test unix:!macx: PRE_TARGETDEPS += $$PWD/../test/libmylib.a
Here is my Qt main.cpp file:
#include <QCoreApplication> extern "C" { void f_analysis_x(const char* data_file_path, const int job_id); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); const char project_path[44] = "/home/nycholas/Desktop/test/my_project.json"; const int job_id = 0; f_analysis_x(project_path, job_id); return a.exec(); }
The function called
f_analysis_x()
is my Fortran function that is located inside thelibmylib.a
file.But when I hit the Compile button, I got these linker errors:
undefined reference to `_gfortran_date_and_time' undefined reference to `_gfortran_st_write' undefined reference to `_gfortran_adjustl' undefined reference to `_gfortran_transfer_integer_write'
What I can do?
Both Fortran library and Qt C++ applications are builded in the same system:
- Ubuntu 18 x64
- gfortran
- Qt Creator IDE 4.10
-
@LIBS += -lgfortran@
should be without@
, this is a remnant from old forum formatting. qmake should've warned you that the line is invalid. What you should seeThe name
f_analysis_x
in fortran resolves tof_analysis_x_
in C terms, so if the function's calledmyfunc
in fortran, it should be declared asmyfunc_
in C (yes, C-linkage is required). Finally, fortran doesn't know whatconst
is, so don't lie to your C compiler. Another thing may be that you have a static libgfortran and a dynamic one in your distro, check that. And finally you can inspect what symbols are undefined in your static lib, and what symbolslibgfortran
provides with thenm
tool. My advice - if you have that particular code available in C/C++ use that and forget fortran.
Also take a look here: https://stackoverflow.com/questions/23551416/unable-to-link-to-libgfortran-a -
@LIBS += -lgfortran@
should be without@
, this is a remnant from old forum formatting. qmake should've warned you that the line is invalid. What you should seeThe name
f_analysis_x
in fortran resolves tof_analysis_x_
in C terms, so if the function's calledmyfunc
in fortran, it should be declared asmyfunc_
in C (yes, C-linkage is required). Finally, fortran doesn't know whatconst
is, so don't lie to your C compiler. Another thing may be that you have a static libgfortran and a dynamic one in your distro, check that. And finally you can inspect what symbols are undefined in your static lib, and what symbolslibgfortran
provides with thenm
tool. My advice - if you have that particular code available in C/C++ use that and forget fortran.
Also take a look here: https://stackoverflow.com/questions/23551416/unable-to-link-to-libgfortran-a@kshegunov thank you...
So, I remove the
@
sign, but I got the same linker erros about gfortran symbols.
The updated line is:LIBS += -lgfortran
Yes, by default the function name will contain a
_
at the end, but I'm using Fortran 2003 C ISO BINDING Interface:subroutine f_analysis_x(project_path, job_id) bind(C)
So the function name is only
f_analysis_x
and it is working good on Windows x64 platform. My problem is only when I try to do the same process in the Linux environment.On Windows 10 x64, I'm using Intel Visual Fortran 2019 with Microsoft Visual Studio 2019 to do my Fortran library *.lib file.
And using Microsoft Visual Studio 2019 to compile and link my C++ code together with my Fortran library.
It's working good!So, in Ubuntu, I'm using gfortran (Terminal) and Qt Creator IDE 4.10.
Why I'm getting these linker errors about gfortran?
-
@kshegunov thank you...
So, I remove the
@
sign, but I got the same linker erros about gfortran symbols.
The updated line is:LIBS += -lgfortran
Yes, by default the function name will contain a
_
at the end, but I'm using Fortran 2003 C ISO BINDING Interface:subroutine f_analysis_x(project_path, job_id) bind(C)
So the function name is only
f_analysis_x
and it is working good on Windows x64 platform. My problem is only when I try to do the same process in the Linux environment.On Windows 10 x64, I'm using Intel Visual Fortran 2019 with Microsoft Visual Studio 2019 to do my Fortran library *.lib file.
And using Microsoft Visual Studio 2019 to compile and link my C++ code together with my Fortran library.
It's working good!So, in Ubuntu, I'm using gfortran (Terminal) and Qt Creator IDE 4.10.
Why I'm getting these linker errors about gfortran?
@fem_dev said in How to link a gfortran static library?:
Why I'm getting these linker errors about gfortran?
Because for some reason the linker can't find the symbols. Why that is, I'm not sure. My best advice is to run
nm
(andgrep
the output) on thelibgfortran
and on your library and see:- that your library does in fact reference these functions (you should see them as undefined symbols in the output)
- that your
libgfortran
does expose them (i.e. they should be marked as defined in the output) exactly as they're requested from 1)
-
@kshegunov thank you...
So, I remove the
@
sign, but I got the same linker erros about gfortran symbols.
The updated line is:LIBS += -lgfortran
Yes, by default the function name will contain a
_
at the end, but I'm using Fortran 2003 C ISO BINDING Interface:subroutine f_analysis_x(project_path, job_id) bind(C)
So the function name is only
f_analysis_x
and it is working good on Windows x64 platform. My problem is only when I try to do the same process in the Linux environment.On Windows 10 x64, I'm using Intel Visual Fortran 2019 with Microsoft Visual Studio 2019 to do my Fortran library *.lib file.
And using Microsoft Visual Studio 2019 to compile and link my C++ code together with my Fortran library.
It's working good!So, in Ubuntu, I'm using gfortran (Terminal) and Qt Creator IDE 4.10.
Why I'm getting these linker errors about gfortran?
@fem_dev said in How to link a gfortran static library?:
So, I copied this library file libmylib.a to my Qt C++ application folder
then you said
The updated line is:
LIBS += -lgfortranso what is the actual name of the Fortran library you built?
is it just a name issue regarding the actual file and what you use in the .pro configuration? -
@fem_dev said in How to link a gfortran static library?:
So, I copied this library file libmylib.a to my Qt C++ application folder
then you said
The updated line is:
LIBS += -lgfortranso what is the actual name of the Fortran library you built?
is it just a name issue regarding the actual file and what you use in the .pro configuration?@Pablo-J-Rogina and @kshegunov
Thank you for your help. Now I will organize my question in a better way:
I have only 2 source-code files:- main.cpp
- fortran.f90
So, I compile the Fortran source-code and generate a Linux library called
libmylib.a
:// Compile and get *.o file: gfortran -c -g fortran.f90 // Add *.o file to a Linux library *.a ar rcs libmylib.a fortran.o
Now I imported this
libmylib.a
file to Qt Creator IDE using the IDE import external library Wizard.Here is my entire *.pro file:
QT -= gui CONFIG += c++11 console CONFIG -= app_bundle LIBS += -lgfortran DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target unix:!macx: LIBS += -L$$PWD/../test/ -lmylib INCLUDEPATH += $$PWD/../test DEPENDPATH += $$PWD/../test unix:!macx: PRE_TARGETDEPS += $$PWD/../test/libmylib.a
Here is my main.cpp file:
#include <QCoreApplication> extern "C" { // yes, I updated the function input arguments: void f_subroutine(const char* c_str, const size_t len, const int job_id); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); const char c_str[] = "/home/nycholas/Desktop/test/my_project.json"; f_subroutine(c_str, strlen(c_str), 0); return a.exec(); }
But when I hit the Compile button, I got these linker errors:
undefined reference to `_gfortran_date_and_time' undefined reference to `_gfortran_st_write' undefined reference to `_gfortran_adjustl' undefined reference to `_gfortran_transfer_integer_write' undefined reference to `_gfortran_string_trim' undefined reference to `_gfortran_concat_string'
I think that Qt Creator IDE is not linking with
gfortran
library even using this line in the *.pro file:LIBS += -lgfortran
@kshegunov about
nm libmylib.a
I got basically this result:0000000000000000 T f_subroutine U _gfortran_adjustl U _gfortran_concat_string U _gfortran_date_and_time U _gfortran_stop_numeric U _gfortran_string_trim U _gfortran_st_write U _gfortran_st_write_done U _gfortran_transfer_integer_write U _GLOBAL_OFFSET_TABLE_
Finally, if I go outside Qt world and try to compile and link just using the Linux Terminal, all goes Ok, no errors and works great!
// Compile C++ and link the Fortran library g++ -Wall -g main.cpp -L . -lmylib -lgfortran -o app // run application: ./app
So, what is the difference between the compile/link sequence that I have done just using the Linux Terminal and using Qt Creator IDE?
How can I solve thisgfortran
linker errors on Qt Creator IDE? -
@Pablo-J-Rogina and @kshegunov
Thank you for your help. Now I will organize my question in a better way:
I have only 2 source-code files:- main.cpp
- fortran.f90
So, I compile the Fortran source-code and generate a Linux library called
libmylib.a
:// Compile and get *.o file: gfortran -c -g fortran.f90 // Add *.o file to a Linux library *.a ar rcs libmylib.a fortran.o
Now I imported this
libmylib.a
file to Qt Creator IDE using the IDE import external library Wizard.Here is my entire *.pro file:
QT -= gui CONFIG += c++11 console CONFIG -= app_bundle LIBS += -lgfortran DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target unix:!macx: LIBS += -L$$PWD/../test/ -lmylib INCLUDEPATH += $$PWD/../test DEPENDPATH += $$PWD/../test unix:!macx: PRE_TARGETDEPS += $$PWD/../test/libmylib.a
Here is my main.cpp file:
#include <QCoreApplication> extern "C" { // yes, I updated the function input arguments: void f_subroutine(const char* c_str, const size_t len, const int job_id); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); const char c_str[] = "/home/nycholas/Desktop/test/my_project.json"; f_subroutine(c_str, strlen(c_str), 0); return a.exec(); }
But when I hit the Compile button, I got these linker errors:
undefined reference to `_gfortran_date_and_time' undefined reference to `_gfortran_st_write' undefined reference to `_gfortran_adjustl' undefined reference to `_gfortran_transfer_integer_write' undefined reference to `_gfortran_string_trim' undefined reference to `_gfortran_concat_string'
I think that Qt Creator IDE is not linking with
gfortran
library even using this line in the *.pro file:LIBS += -lgfortran
@kshegunov about
nm libmylib.a
I got basically this result:0000000000000000 T f_subroutine U _gfortran_adjustl U _gfortran_concat_string U _gfortran_date_and_time U _gfortran_stop_numeric U _gfortran_string_trim U _gfortran_st_write U _gfortran_st_write_done U _gfortran_transfer_integer_write U _GLOBAL_OFFSET_TABLE_
Finally, if I go outside Qt world and try to compile and link just using the Linux Terminal, all goes Ok, no errors and works great!
// Compile C++ and link the Fortran library g++ -Wall -g main.cpp -L . -lmylib -lgfortran -o app // run application: ./app
So, what is the difference between the compile/link sequence that I have done just using the Linux Terminal and using Qt Creator IDE?
How can I solve thisgfortran
linker errors on Qt Creator IDE?@fem_dev said in How to link a gfortran static library?:
So, what is the difference between the compile/link sequence that I have done just using the Linux Terminal and using Qt Creator IDE?
There's quite a lot of them, as I imagine the Qt compile line is as long as the distance between London and New York. But first thing first:
- Do yourself a favor and enable relocations; compile with
-fPIC
. - Would you humor me and move the LIBS += -lgfortran at the end of your project file, after you've linked your library?
- Also you provided only half of what I asked for. Not only did I request the
nm
output from your library, but I also wanted you to list the symbols from thelibgfortran
in your path and grep against one of the missing symbols, say_gfortran_date_and_time
.
-
@fem_dev said in How to link a gfortran static library?:
So, what is the difference between the compile/link sequence that I have done just using the Linux Terminal and using Qt Creator IDE?
There's quite a lot of them, as I imagine the Qt compile line is as long as the distance between London and New York. But first thing first:
- Do yourself a favor and enable relocations; compile with
-fPIC
. - Would you humor me and move the LIBS += -lgfortran at the end of your project file, after you've linked your library?
- Also you provided only half of what I asked for. Not only did I request the
nm
output from your library, but I also wanted you to list the symbols from thelibgfortran
in your path and grep against one of the missing symbols, say_gfortran_date_and_time
.
@kshegunov thank you a lot for your informations! Today I learned a little bit more about Qt compile/link process.
1. Do yourself a favor and enable relocations; compile with -fPIC
Ok. I did it now!
2. Would you humor me and move the LIBS += -lgfortran at the end of your project file, after you've linked your library?
Ok! I moved this line to the end of *.pro file and now I can compile and link with my Fortran static library with no errors!
This solved my problem! Thanks!3. [...] but I also wanted you to list the symbols from the libgfortran in your path and grep against one of the missing symbols, say _gfortran_date_and_time.
In the library *.a folder I typed:
nm libmylib.a | grep libgfortran
And I got no results. Total clean.
- Do yourself a favor and enable relocations; compile with
-
@kshegunov thank you a lot for your informations! Today I learned a little bit more about Qt compile/link process.
1. Do yourself a favor and enable relocations; compile with -fPIC
Ok. I did it now!
2. Would you humor me and move the LIBS += -lgfortran at the end of your project file, after you've linked your library?
Ok! I moved this line to the end of *.pro file and now I can compile and link with my Fortran static library with no errors!
This solved my problem! Thanks!3. [...] but I also wanted you to list the symbols from the libgfortran in your path and grep against one of the missing symbols, say _gfortran_date_and_time.
In the library *.a folder I typed:
nm libmylib.a | grep libgfortran
And I got no results. Total clean.
@fem_dev said in How to link a gfortran static library?:
This solved my problem! Thanks!
Great, so don't forget to mark your post as solved then. Thanks