BrianGladman / mpir

Multiple Precision Integers and Rationals
GNU General Public License v3.0
75 stars 36 forks source link

[Solved] MultiThread instead of MultiThreadDLL #21

Closed soerenmuehlbauer closed 2 years ago

soerenmuehlbauer commented 2 years ago

How to compile with static CRT?

BrianGladman commented 2 years ago

The MPIR builds use the libraries that match their own form. That is, MPIR static libraries link to static CRT libraries while MPIR DLL's link to the DLL CRT libraries.

If you wish to change this you will need to manually edit the MPIR build files to achieve this.

soerenmuehlbauer commented 2 years ago

Would you be interested in a PR to provide this in a parametrized way (default will be the current setting)?

BrianGladman commented 2 years ago

I can't really answer that without a better understanding of the requirement for this. MPIR has existed in its current form for over a decade now without the need for this and I don't want to add features for which there is not a clear and widespread need.

soerenmuehlbauer commented 2 years ago

We use mpir on windows as a dll. We import this dll from c#. Currently the dll is build with a linkage to the msvc runtime. So it requires the installation of some microsoft packages. We would prefer that we link the msvsc runtime into the mpir dll (MT/MTd). It is just about reducing the dependencies from mpir. Under Linux we have a different way of thinking about shared libraries.

SanderBouwhuis commented 2 years ago

For many years I have built the statically linked MPIR/MPFR libraries. I just recently switched from MT to MD for MPIR/MPFR. So, as Brian stated : it works out of the box. You only need to select the static library projects of MPIR/MPFR and you will get the .LIB import libraries and the .PDB crashdump info files.

soerenmuehlbauer commented 2 years ago

Sure, the libs are created with the static linkage. But we need the dll (we use it in C#) and we want that dll without dependencies to msvcrt. This is also the reason why we use mpir and not gmplib. Because to compile gmplib for windows you need to use mingw which also links to some microsoft crt dlls. Sure, I could create a new (dll) project, link the static lib and configure static runtime library for it. My proposal is something like

  <PropertyGroup Condition="'$(Configuration)'!='Debug' and '$(Configuration)'!='Release'">
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'!='Static'">MultiThreadedDLL</VC_RuntimeLibrary>
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'=='Static'">MultiThreaded</VC_RuntimeLibrary>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'!='Static'">MultiThreadedDLL</VC_RuntimeLibrary>
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'=='Static'">MultiThreaded</VC_RuntimeLibrary>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'!='Static'">MultiThreadedDebugDLL</VC_RuntimeLibrary>
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'=='Static'">MultiThreadedDebug</VC_RuntimeLibrary>
  </PropertyGroup>

and use that in the CL compile task

 <ClCompile>
      <AdditionalIncludeDirectories>..\..\..\</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>NDEBUG;WIN32;HAVE_CONFIG_H;MSC_BUILD_DLL;%(PreprocessorDefinitions) 
      </PreprocessorDefinitions>
      <RuntimeLibrary>$(VC_RuntimeLibrary)</RuntimeLibrary>
  </ClCompile>

in dll_mpir_gc.vcxproj. In the msbuild.bat we could add a new switch to configure it to use static linkage.

By the way, it would also be nice if the DLL would have proper version information.

SanderBouwhuis commented 2 years ago

So, basically an extra setting to set the /LD switch to create a static library which includes the ms runtime to prevent external dependencies?

I think your idea is actually a good idea!

Note : You do have to be careful that your MPIR/MPFR DLL in that case does not share the same memory manager as your main project. That means that any heap allocation, deallocations and reallocations can result in either leaks or sometimes even crashes. This is the reason I decided to switch to /MD.

soerenmuehlbauer commented 2 years ago

First thing: I do not talk about the lib projects. Only the project which results in a dll. For c++ users it may be of value to have the dependency to the mscrt, because they want to have only one memory manager and so on. But for users using mpir in other languages it does not make sense, because they need to ensure that on the target systems the runtime is installed.

If you use plain msbuild to compile the vcxproj you can just add /p:VC_RuntimeLibrary=Static to get a dll without any dependencies to the ms crt. If you do not add the switch you will get the usual dll. The lib* projects are not affected. I would open a PR but I'm not good in shell development. There is this msbuild.bat which would need to be changed to provide the new switch. As for now I compile using plain msbuild. Works for me so far. I just thought that it would be a good idea to have this also upstream.

BrianGladman commented 2 years ago

Sure, the libs are created with the static linkage. But we need the dll (we use it in C#) and we want that dll without dependencies to msvcrt. This is also the reason why we use mpir and not gmplib. Because to compile gmplib for windows you need to use mingw which also links to some microsoft crt dlls. Sure, I could create a new (dll) project, link the static lib and configure static runtime library for it. My proposal is something like

[snip]

MPIR CRT linking is not controlled by the MPIR *.vcxproj files and I certainly don't want to change how this is done.

CRT linking is controlled by four files in the msvc sub-directory:

 mpir_debug_dll.props
 mpir_debug_lib.props
 mpir_release_dll.props
 mpir_release_lib.props

whose names match the configuration concerned.

So you should be able to meet your need by modifying (or replacing) two of these four files. A simple script in your own build process should be able to do this without any need to modify the MPPIR build itself.

The MPIR *.vcxproj files are auto-generated so changes in these files would require changes elsewhere in the MPIR build process. That would not be an easy task.

soerenmuehlbauer commented 2 years ago

Even better. Could maybe MPIR_Props_External an solution for me? I could just provide such an file and can define my things there...

soerenmuehlbauer commented 2 years ago

I will close this issue because mpir build is flexible enough to do everything I wanted. For reference: I just created a props file and added it with MPIR_Props_External.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup Condition="'$(Configuration)'!='Debug' and '$(Configuration)'!='Release'">
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'!='Static'">MultiThreadedDLL</VC_RuntimeLibrary>
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'=='Static'">MultiThreaded</VC_RuntimeLibrary>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'!='Static'">MultiThreadedDLL</VC_RuntimeLibrary>
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'=='Static'">MultiThreaded</VC_RuntimeLibrary>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'!='Static'">MultiThreadedDebugDLL</VC_RuntimeLibrary>
    <VC_RuntimeLibrary Condition="'$(RuntimeLinkage)'=='Static'">MultiThreadedDebug</VC_RuntimeLibrary>
  </PropertyGroup>

  <ItemGroup>
    <ClInclude Include="$(MSBuildThisFileDirectory)resource.h" />
    <ClInclude Include="$(MSBuildThisFileDirectory)libversion.h" />
  </ItemGroup>

  <ItemGroup>
    <ResourceCompile Include="$(MSBuildThisFileDirectory)version.rc" />
  </ItemGroup>  
</Project>

Finally I have a proper version information and can toggle the static/dynamic runtime. Thanks to you all.

SanderBouwhuis commented 2 years ago

Could you please rename this thread to state that you have a solution? That way if anyone else also needs it, (s)he can more easily find your helpful posts.