Skip to main content
added 9595 characters in body
Source Link
Mike Kinghan
  • 63.5k
  • 17
  • 172
  • 205

Update for further difficulties

Snag 1

  • When you try to link your application against the static libmuparser.a you get new undefined references:

    undefined reference to `omp_get_num_threads'
    undefined reference to `omp_get_thread_num'
    undefined reference to `omp_get_max_threads'
    undefined reference to `omp_set_num_threads'
    

Snag 2

  • When you rebuild muparser with CMake as a DLL, instead of building import library libmuparser.dll.a and DLL libmuparser.dll, you get import library libmuparser.dll.a but DLL msys-muparser-2.dll.

I do not reproduce either of these snags.

About Snag 1

Now that you have succeeded in getting libmuparser.a input to the linkage of your app, the definitions of the muparser symbols have been found by the linker and those definitions have introduced references to those omp_* symbols, which are defined in the GNU Open Multi-Processing runtime library libgomp. But the linker does not find definitions of those. There are a number of possible explanations for this, all of them in the "should not happen" category; some involving things you might have done that I'm unaware of; some involving characteristics of your mingw_64 GCC installation that I'm unaware of.

These symbols are referenced because you configured the CMake build of libmuparser.a to enable the use of OpenMP shared-memory multi-processing, as per:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF
                              ^^^^^^^^^^^^^^^^^                          

When I do the same:

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser
$ mkdir build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser
$ cd build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ cmake -G 'MSYS Makefiles' -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF ..
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done (6.5s)
-- Generating done (0.2s)
-- Build files have been written to: C:/Users/imkin/so/muparser/build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ make
[  6%] Building CXX object CMakeFiles/muparser.dir/src/muParser.cpp.obj
[ 12%] Building CXX object CMakeFiles/muparser.dir/src/muParserBase.cpp.obj
[ 18%] Building CXX object CMakeFiles/muparser.dir/src/muParserBytecode.cpp.obj
[ 25%] Building CXX object CMakeFiles/muparser.dir/src/muParserCallback.cpp.obj
[ 31%] Building CXX object CMakeFiles/muparser.dir/src/muParserDLL.cpp.obj
[ 37%] Building CXX object CMakeFiles/muparser.dir/src/muParserError.cpp.obj
[ 43%] Building CXX object CMakeFiles/muparser.dir/src/muParserInt.cpp.obj
[ 50%] Building CXX object CMakeFiles/muparser.dir/src/muParserTest.cpp.obj
[ 56%] Building CXX object CMakeFiles/muparser.dir/src/muParserTokenReader.cpp.obj
[ 62%] Linking CXX static library libmuparser.a
[ 62%] Built target muparser
[ 68%] Building CXX object CMakeFiles/example1.dir/samples/example1/example1.cpp.obj
[ 75%] Linking CXX executable example1.exe
[ 75%] Built target example1
[ 81%] Building C object CMakeFiles/example2.dir/samples/example2/example2.c.obj
[ 87%] Linking CXX executable example2.exe
[ 87%] Built target example2
[ 93%] Building CXX object CMakeFiles/t_ParserTest.dir/test/t_ParserTest.cpp.obj
[100%] Linking CXX executable t_ParserTest.exe
[100%] Built target t_ParserTest

both of the examples build without linkage errors (and run without problems) and it can be seen that all of the problem omp_* symbols are statically defined in them:

$ nm example1.exe | grep omp
0000000140057a20 I __imp_omp_get_max_threads
0000000140057a28 I __imp_omp_get_num_threads
0000000140057a30 I __imp_omp_get_thread_num
0000000140057a38 I __imp_omp_set_num_threads
0000000140057050 I _head_libgomp_1_dll
000000014000c1e0 t _ZN2mu10ParserBase4EvalEPdi._omp_fn.0
0000000140006150 t _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_.isra.0
0000000140059014 I libgomp_1_dll_iname
0000000140038a78 T omp_get_max_threads
0000000140038a70 T omp_get_num_threads
0000000140038a68 T omp_get_thread_num
0000000140038a60 T omp_set_num_threads

as signified by T omp_*.

Taking a step back, I think you probably did not have any settled reason for configuring the build of libmuparser.a with -DENABLE_OPENMP=ON. I think that because when you subsequently rebuilt muparser as a DLL, you configured:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=OFF -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=ON
                             ^^^^^^^^^^^^^^^^^^^
                             

This means we do not know, from the posted information, whether or not the same omp_* undefined references would appear in the linkage of your application if muparser was linked with it as a DLL, with OpenMP enabled. But if you want or prefer to link it as a static library, then I suggest that you rebuild muparser from scratch (delete the CMake build dir; delete the CMakeCache.txt, if it exists, in the muparser directory), and this time just accept the defaults except for requesting a static library. I.e. configure with:

$ cmake -DBUILD_SHARED_LIBS=OFF ..

Then try again to link the static library with your application as before.

About Snag 2

I cannot account for your msys-muparser-2.dll. When I build the DLL (per default):

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ rm -fr *

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ cmake -G 'MSYS Makefiles' ..
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done (5.8s)
-- Generating done (0.2s)
-- Build files have been written to: C:/Users/imkin/so/muparser/build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ make
[  6%] Building CXX object CMakeFiles/muparser.dir/src/muParser.cpp.obj
[ 12%] Building CXX object CMakeFiles/muparser.dir/src/muParserBase.cpp.obj
[ 18%] Building CXX object CMakeFiles/muparser.dir/src/muParserBytecode.cpp.obj
[ 25%] Building CXX object CMakeFiles/muparser.dir/src/muParserCallback.cpp.obj
[ 31%] Building CXX object CMakeFiles/muparser.dir/src/muParserDLL.cpp.obj
[ 37%] Building CXX object CMakeFiles/muparser.dir/src/muParserError.cpp.obj
[ 43%] Building CXX object CMakeFiles/muparser.dir/src/muParserInt.cpp.obj
[ 50%] Building CXX object CMakeFiles/muparser.dir/src/muParserTest.cpp.obj
[ 56%] Building CXX object CMakeFiles/muparser.dir/src/muParserTokenReader.cpp.obj
[ 62%] Linking CXX shared library libmuparser.dll
[ 62%] Built target muparser
[ 68%] Building CXX object CMakeFiles/example1.dir/samples/example1/example1.cpp.obj
[ 75%] Linking CXX executable example1.exe
[ 75%] Built target example1
[ 81%] Building C object CMakeFiles/example2.dir/samples/example2/example2.c.obj
[ 87%] Linking C executable example2.exe
[ 87%] Built target example2
[ 93%] Building CXX object CMakeFiles/t_ParserTest.dir/test/t_ParserTest.cpp.obj
[100%] Linking CXX executable t_ParserTest.exe
[100%] Built target t_ParserTest

I build the expected targets:

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ ls *muparser.dll*
libmuparser.dll  libmuparser.dll.a

I would not recommend renaming your msys-muparser-2.dll because the import library embeds the name of the associated DLL. If, after you link your app against the import library you run:

>dumpbin /dependents debug\TestMuParser.exe

and see that msys-muparser-2.dll is among the dependencies then all is as it should be.

If problems persist

Since you have an MSYS2 installation (in which you are building muparser), you might abandon the attempt to build it from source and install the MSYS2 binary package mingw-w64-x86_64-muparser with:

$ pacman -S mingw-w64-x86_64-muparser

This will only install DLL version (import library /c/msys64/mingw64/lib/libmuparser.dll.a and DLL /c/msys64/mingw64/bin/libmuparser.dll, but it seems you are prepared to live with the DLL if you have to.

Update for further difficulties

Snag 1

  • When you try to link your application against the static libmuparser.a you get new undefined references:

    undefined reference to `omp_get_num_threads'
    undefined reference to `omp_get_thread_num'
    undefined reference to `omp_get_max_threads'
    undefined reference to `omp_set_num_threads'
    

Snag 2

  • When you rebuild muparser with CMake as a DLL, instead of building import library libmuparser.dll.a and DLL libmuparser.dll, you get import library libmuparser.dll.a but DLL msys-muparser-2.dll.

I do not reproduce either of these snags.

About Snag 1

Now that you have succeeded in getting libmuparser.a input to the linkage of your app, the definitions of the muparser symbols have been found by the linker and those definitions have introduced references to those omp_* symbols, which are defined in the GNU Open Multi-Processing runtime library libgomp. But the linker does not find definitions of those. There are a number of possible explanations for this, all of them in the "should not happen" category; some involving things you might have done that I'm unaware of; some involving characteristics of your mingw_64 GCC installation that I'm unaware of.

These symbols are referenced because you configured the CMake build of libmuparser.a to enable the use of OpenMP shared-memory multi-processing, as per:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF
                              ^^^^^^^^^^^^^^^^^                          

When I do the same:

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser
$ mkdir build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser
$ cd build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ cmake -G 'MSYS Makefiles' -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF ..
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done (6.5s)
-- Generating done (0.2s)
-- Build files have been written to: C:/Users/imkin/so/muparser/build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ make
[  6%] Building CXX object CMakeFiles/muparser.dir/src/muParser.cpp.obj
[ 12%] Building CXX object CMakeFiles/muparser.dir/src/muParserBase.cpp.obj
[ 18%] Building CXX object CMakeFiles/muparser.dir/src/muParserBytecode.cpp.obj
[ 25%] Building CXX object CMakeFiles/muparser.dir/src/muParserCallback.cpp.obj
[ 31%] Building CXX object CMakeFiles/muparser.dir/src/muParserDLL.cpp.obj
[ 37%] Building CXX object CMakeFiles/muparser.dir/src/muParserError.cpp.obj
[ 43%] Building CXX object CMakeFiles/muparser.dir/src/muParserInt.cpp.obj
[ 50%] Building CXX object CMakeFiles/muparser.dir/src/muParserTest.cpp.obj
[ 56%] Building CXX object CMakeFiles/muparser.dir/src/muParserTokenReader.cpp.obj
[ 62%] Linking CXX static library libmuparser.a
[ 62%] Built target muparser
[ 68%] Building CXX object CMakeFiles/example1.dir/samples/example1/example1.cpp.obj
[ 75%] Linking CXX executable example1.exe
[ 75%] Built target example1
[ 81%] Building C object CMakeFiles/example2.dir/samples/example2/example2.c.obj
[ 87%] Linking CXX executable example2.exe
[ 87%] Built target example2
[ 93%] Building CXX object CMakeFiles/t_ParserTest.dir/test/t_ParserTest.cpp.obj
[100%] Linking CXX executable t_ParserTest.exe
[100%] Built target t_ParserTest

both of the examples build without linkage errors (and run without problems) and it can be seen that all of the problem omp_* symbols are statically defined in them:

$ nm example1.exe | grep omp
0000000140057a20 I __imp_omp_get_max_threads
0000000140057a28 I __imp_omp_get_num_threads
0000000140057a30 I __imp_omp_get_thread_num
0000000140057a38 I __imp_omp_set_num_threads
0000000140057050 I _head_libgomp_1_dll
000000014000c1e0 t _ZN2mu10ParserBase4EvalEPdi._omp_fn.0
0000000140006150 t _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_.isra.0
0000000140059014 I libgomp_1_dll_iname
0000000140038a78 T omp_get_max_threads
0000000140038a70 T omp_get_num_threads
0000000140038a68 T omp_get_thread_num
0000000140038a60 T omp_set_num_threads

as signified by T omp_*.

Taking a step back, I think you probably did not have any settled reason for configuring the build of libmuparser.a with -DENABLE_OPENMP=ON. I think that because when you subsequently rebuilt muparser as a DLL, you configured:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=OFF -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=ON
                             ^^^^^^^^^^^^^^^^^^^
                             

This means we do not know, from the posted information, whether or not the same omp_* undefined references would appear in the linkage of your application if muparser was linked with it as a DLL, with OpenMP enabled. But if you want or prefer to link it as a static library, then I suggest that you rebuild muparser from scratch (delete the CMake build dir; delete the CMakeCache.txt, if it exists, in the muparser directory), and this time just accept the defaults except for requesting a static library. I.e. configure with:

$ cmake -DBUILD_SHARED_LIBS=OFF ..

Then try again to link the static library with your application as before.

About Snag 2

I cannot account for your msys-muparser-2.dll. When I build the DLL (per default):

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ rm -fr *

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ cmake -G 'MSYS Makefiles' ..
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done (5.8s)
-- Generating done (0.2s)
-- Build files have been written to: C:/Users/imkin/so/muparser/build

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ make
[  6%] Building CXX object CMakeFiles/muparser.dir/src/muParser.cpp.obj
[ 12%] Building CXX object CMakeFiles/muparser.dir/src/muParserBase.cpp.obj
[ 18%] Building CXX object CMakeFiles/muparser.dir/src/muParserBytecode.cpp.obj
[ 25%] Building CXX object CMakeFiles/muparser.dir/src/muParserCallback.cpp.obj
[ 31%] Building CXX object CMakeFiles/muparser.dir/src/muParserDLL.cpp.obj
[ 37%] Building CXX object CMakeFiles/muparser.dir/src/muParserError.cpp.obj
[ 43%] Building CXX object CMakeFiles/muparser.dir/src/muParserInt.cpp.obj
[ 50%] Building CXX object CMakeFiles/muparser.dir/src/muParserTest.cpp.obj
[ 56%] Building CXX object CMakeFiles/muparser.dir/src/muParserTokenReader.cpp.obj
[ 62%] Linking CXX shared library libmuparser.dll
[ 62%] Built target muparser
[ 68%] Building CXX object CMakeFiles/example1.dir/samples/example1/example1.cpp.obj
[ 75%] Linking CXX executable example1.exe
[ 75%] Built target example1
[ 81%] Building C object CMakeFiles/example2.dir/samples/example2/example2.c.obj
[ 87%] Linking C executable example2.exe
[ 87%] Built target example2
[ 93%] Building CXX object CMakeFiles/t_ParserTest.dir/test/t_ParserTest.cpp.obj
[100%] Linking CXX executable t_ParserTest.exe
[100%] Built target t_ParserTest

I build the expected targets:

imkin@MikesInspiron MINGW64 /c/Users/imkin/so/muparser/build
$ ls *muparser.dll*
libmuparser.dll  libmuparser.dll.a

I would not recommend renaming your msys-muparser-2.dll because the import library embeds the name of the associated DLL. If, after you link your app against the import library you run:

>dumpbin /dependents debug\TestMuParser.exe

and see that msys-muparser-2.dll is among the dependencies then all is as it should be.

If problems persist

Since you have an MSYS2 installation (in which you are building muparser), you might abandon the attempt to build it from source and install the MSYS2 binary package mingw-w64-x86_64-muparser with:

$ pacman -S mingw-w64-x86_64-muparser

This will only install DLL version (import library /c/msys64/mingw64/lib/libmuparser.dll.a and DLL /c/msys64/mingw64/bin/libmuparser.dll, but it seems you are prepared to live with the DLL if you have to.

edited body
Source Link
Mike Kinghan
  • 63.5k
  • 17
  • 172
  • 205

You have built muparser as a static library only:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON \
    -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF
                            ^^^^^^^^^^^^^^^^^^^^^^

giving you the archive that you copied into your project as:

project/libs/muparser/lib/libmuparser.a

But you have built your target debug\TestMuParser.exe with the (default) assumption that muparser is a shared library/DLL. Consequently the compiler generates references to symbols like:

undefined reference to `__imp__ZN2mu6ParserC1Ev'
undefined reference to `__imp__ZN2mu10ParserBase9DefineVarERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEPd'
undefined reference to `__imp__ZN2mu10ParserBase7SetExprERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEE'
undefined reference to `__imp__ZNK2mu10ParserBase4EvalEv'

in which the __imp_ ( = import) prefix signifies that the referenced symbols are dynamic symbols - symbols to be prefixed __declspec(dllimport) in the pre-processed source code - that are defined in the import library of the muparser DLL, neither of which you have built.

If you had not specified -DBUILD_SHARED_LIBS=OFF when you built muparser, then instead of libmuparser.a you would have built:

libmuparser.dll     # the DLL
libmuparser.dll.a   # its import library.

and if you had copied these to project/libs/muparser/lib/libmuparser then the linkage would have succeeded - although for your program to run when installed somewhere in your runtime PATH, you would then need to ensure that libmuparser.dll is also found by the dynamic linker per the Windows Dynamic-link Library Search Order.

Since all of your QT libraries are also static it appears that you intend to build a (largely) static application, including a static libmuparser. In that case you will need to direct your compiler not to generate dynamic references to the symbols of libmuparser, but just regular ones for static linkage.

The way to do that is to specify the preprocessor flag:

-DMUPARSER_STATIC

to g++ when you compile you source code, which signifies to the compiler that a static libmuparser will be linked. This fact is not mentioned in the documention - :) - either at the muparser website or at the the gitbuggithub repo, but you can discover it in the source code.

You will need to add:

DEFINES += MUPARSER_STATIC

to your QT project file to have -DMUPARSER_STATIC added to the compiler commandline.

You have built muparser as a static library only:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON \
    -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF
                            ^^^^^^^^^^^^^^^^^^^^^^

giving you the archive that you copied into your project as:

project/libs/muparser/lib/libmuparser.a

But you have built your target debug\TestMuParser.exe with the (default) assumption that muparser is a shared library/DLL. Consequently the compiler generates references to symbols like:

undefined reference to `__imp__ZN2mu6ParserC1Ev'
undefined reference to `__imp__ZN2mu10ParserBase9DefineVarERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEPd'
undefined reference to `__imp__ZN2mu10ParserBase7SetExprERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEE'
undefined reference to `__imp__ZNK2mu10ParserBase4EvalEv'

in which the __imp_ ( = import) prefix signifies that the referenced symbols are dynamic symbols - symbols to be prefixed __declspec(dllimport) in the pre-processed source code - that are defined in the import library of the muparser DLL, neither of which you have built.

If you had not specified -DBUILD_SHARED_LIBS=OFF when you built muparser, then instead of libmuparser.a you would have built:

libmuparser.dll     # the DLL
libmuparser.dll.a   # its import library.

and if you had copied these to project/libs/muparser/lib/libmuparser then the linkage would have succeeded - although for your program to run when installed somewhere in your runtime PATH, you would then need to ensure that libmuparser.dll is also found by the dynamic linker per the Windows Dynamic-link Library Search Order.

Since all of your QT libraries are also static it appears that you intend to build a (largely) static application, including a static libmuparser. In that case you will need to direct your compiler not to generate dynamic references to the symbols of libmuparser, but just regular ones for static linkage.

The way to do that is to specify the preprocessor flag:

-DMUPARSER_STATIC

to g++ when you compile you source code, which signifies to the compiler that a static libmuparser will be linked. This fact is not mentioned in the documention - :) - either at the muparser website or at the the gitbug repo, but you can discover it in the source code.

You will need to add:

DEFINES += MUPARSER_STATIC

to your QT project file to have -DMUPARSER_STATIC added to the compiler commandline.

You have built muparser as a static library only:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON \
    -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF
                            ^^^^^^^^^^^^^^^^^^^^^^

giving you the archive that you copied into your project as:

project/libs/muparser/lib/libmuparser.a

But you have built your target debug\TestMuParser.exe with the (default) assumption that muparser is a shared library/DLL. Consequently the compiler generates references to symbols like:

undefined reference to `__imp__ZN2mu6ParserC1Ev'
undefined reference to `__imp__ZN2mu10ParserBase9DefineVarERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEPd'
undefined reference to `__imp__ZN2mu10ParserBase7SetExprERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEE'
undefined reference to `__imp__ZNK2mu10ParserBase4EvalEv'

in which the __imp_ ( = import) prefix signifies that the referenced symbols are dynamic symbols - symbols to be prefixed __declspec(dllimport) in the pre-processed source code - that are defined in the import library of the muparser DLL, neither of which you have built.

If you had not specified -DBUILD_SHARED_LIBS=OFF when you built muparser, then instead of libmuparser.a you would have built:

libmuparser.dll     # the DLL
libmuparser.dll.a   # its import library.

and if you had copied these to project/libs/muparser/lib/libmuparser then the linkage would have succeeded - although for your program to run when installed somewhere in your runtime PATH, you would then need to ensure that libmuparser.dll is also found by the dynamic linker per the Windows Dynamic-link Library Search Order.

Since all of your QT libraries are also static it appears that you intend to build a (largely) static application, including a static libmuparser. In that case you will need to direct your compiler not to generate dynamic references to the symbols of libmuparser, but just regular ones for static linkage.

The way to do that is to specify the preprocessor flag:

-DMUPARSER_STATIC

to g++ when you compile you source code, which signifies to the compiler that a static libmuparser will be linked. This fact is not mentioned in the documention - :) - either at the muparser website or at the the github repo, but you can discover it in the source code.

You will need to add:

DEFINES += MUPARSER_STATIC

to your QT project file to have -DMUPARSER_STATIC added to the compiler commandline.

Source Link
Mike Kinghan
  • 63.5k
  • 17
  • 172
  • 205

You have built muparser as a static library only:

cmake .. -DENABLE_SAMPLES=ON -DENABLE_OPENMP=ON \
    -DENABLE_WIDE_CHAR=OFF -DBUILD_SHARED_LIBS=OFF
                            ^^^^^^^^^^^^^^^^^^^^^^

giving you the archive that you copied into your project as:

project/libs/muparser/lib/libmuparser.a

But you have built your target debug\TestMuParser.exe with the (default) assumption that muparser is a shared library/DLL. Consequently the compiler generates references to symbols like:

undefined reference to `__imp__ZN2mu6ParserC1Ev'
undefined reference to `__imp__ZN2mu10ParserBase9DefineVarERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEEPd'
undefined reference to `__imp__ZN2mu10ParserBase7SetExprERKNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEE'
undefined reference to `__imp__ZNK2mu10ParserBase4EvalEv'

in which the __imp_ ( = import) prefix signifies that the referenced symbols are dynamic symbols - symbols to be prefixed __declspec(dllimport) in the pre-processed source code - that are defined in the import library of the muparser DLL, neither of which you have built.

If you had not specified -DBUILD_SHARED_LIBS=OFF when you built muparser, then instead of libmuparser.a you would have built:

libmuparser.dll     # the DLL
libmuparser.dll.a   # its import library.

and if you had copied these to project/libs/muparser/lib/libmuparser then the linkage would have succeeded - although for your program to run when installed somewhere in your runtime PATH, you would then need to ensure that libmuparser.dll is also found by the dynamic linker per the Windows Dynamic-link Library Search Order.

Since all of your QT libraries are also static it appears that you intend to build a (largely) static application, including a static libmuparser. In that case you will need to direct your compiler not to generate dynamic references to the symbols of libmuparser, but just regular ones for static linkage.

The way to do that is to specify the preprocessor flag:

-DMUPARSER_STATIC

to g++ when you compile you source code, which signifies to the compiler that a static libmuparser will be linked. This fact is not mentioned in the documention - :) - either at the muparser website or at the the gitbug repo, but you can discover it in the source code.

You will need to add:

DEFINES += MUPARSER_STATIC

to your QT project file to have -DMUPARSER_STATIC added to the compiler commandline.