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.aHow 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.aHow 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.aSo, I copied this library file
libmylib.ato 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.aHere 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.afile.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_xin fortran resolves tof_analysis_x_in C terms, so if the function's calledmyfuncin fortran, it should be declared asmyfunc_in C (yes, C-linkage is required). Finally, fortran doesn't know whatconstis, 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 symbolslibgfortranprovides with thenmtool. 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_xin fortran resolves tof_analysis_x_in C terms, so if the function's calledmyfuncin fortran, it should be declared asmyfunc_in C (yes, C-linkage is required). Finally, fortran doesn't know whatconstis, 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 symbolslibgfortranprovides with thenmtool. 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 += -lgfortranYes, 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_xand 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 += -lgfortranYes, 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_xand 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(andgrepthe output) on thelibgfortranand 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
libgfortrandoes 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 += -lgfortranYes, 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_xand 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.oNow I imported this
libmylib.afile 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.aHere 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
gfortranlibrary even using this line in the *.pro file:LIBS += -lgfortran@kshegunov about
nm libmylib.aI 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: ./appSo, 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 thisgfortranlinker 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.oNow I imported this
libmylib.afile 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.aHere 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
gfortranlibrary even using this line in the *.pro file:LIBS += -lgfortran@kshegunov about
nm libmylib.aI 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: ./appSo, 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 thisgfortranlinker 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
nmoutput from your library, but I also wanted you to list the symbols from thelibgfortranin 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
nmoutput from your library, but I also wanted you to list the symbols from thelibgfortranin 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 -fPICOk. 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 libgfortranAnd 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 -fPICOk. 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 libgfortranAnd 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