Link error building a project under Win32

I have a project which has been working fine under x64, now I have a requirement to get it working under Win32. I have created a new platform Win32 in the sln and vfproj files. However I keep getting this link error:

dflc.obj : fatal error LNK1112: module machine type ‘x86’ conflicts with target machine type ‘x64’

if I exclude this file from the project, it gives me the same error but with another file and stops. And so on. So it’s not a problem with the file itself.

However for some reason it is thinking the target machine type is ‘x64’ whereas I have specified Debug / Win32 as my build configuration.

It is getting x64 from somewhere, but I have no idea where.

MS Visual Studio 2022 17.4.4 / Intel Fortran Version 2021.8.0 Build 20221119_000000

1 Like

Hi ferrad, welcome to the forum :smile:

The problems you report may be due to one or more projects in your solution still having “x64” as the platform. If you open the Configuration Manager (under Build) you can see the exact properties of each project. I have seen in the past that that is not always properly aligned.

Another thing that might be occurring is that some of the libraries that you include in the build are 64-bits versions.

Hi Arjen,
Configuration Manager shows all projects under the Active solution platform Win32 with Win32 as the target. Similarly for x64.
Regarding libraries, the offending project does include delayimp.lib. If I start a command prompt from VS and I look at my LIBPATH, it contains both:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\lib\x86
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\lib\x64
which both contain delayimp.lib, although x86 is first, so one would think it would find the win32 version first?

I have no idea how this is handled. Perhaps the build log will give more information?

I found the problem.
Properties → Linker → Advanced → Target Machine
It was “Not Set”
I changed to MachineX86.

1 Like

Wow, that is not the most obvious place to look, is it? Congratulations.

The annoying thing is that when I migrated the Fortran projects to Win32, that entry becomes “Not Set”. But the C++ migration (all part of the same SLN), C++ populates that field correctly.

Are you sure it is changed? I saw the same “Not Set” in one of my VS solutions and that is simply x64.

Yes Not Set means x64. But I am building a Win32 project. Hence the mismatch.

@ferrad ,

Have you attempted a simple check first on your system, presumably running 64-bit Windows OS, that you are able to execute 32-bit targets ok? If not, you may want to try that out.

Click for quick test code

See this link from Microsoft:

  • C++ DllMain.cpp file
#include "windows.h"

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpvReserved )  // reserved
{
    int msgboxID;

    // Perform actions based on the reason for calling.
    switch( fdwReason ) 
    { 
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            msgboxID = MessageBox(
                NULL,
                (LPCSTR)"DllMain invoked",
                (LPCSTR)"Test DLL",
                MB_OK );
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
        
            if (lpvReserved != nullptr)
            {
                break; // do not do cleanup if process termination scenario
            }
            
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}
  • silly Fortran “library” code: m.f90
module m
contains
   function f( n ) result(r)
      integer, intent(in) :: n
      integer :: r
      r = n + 42
   end function 
end module 
  • Microsoft-recommended DLL definition file, m.def
LIBRARY m
EXPORTS
    M_mp_F        @1

Build steps:on a command-line window toward 32-bit target

C:\temp>cl /c /W3 /EHsc dllmain.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31937 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

dllmain.cpp

C:\temp>ifort /c /standard-semantics /Qm32 m.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on IA-32, Version 2021.8.0 Build 20221119_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.


C:\temp>link m.obj dllmain.obj user32.lib /dll /def:m.def /out:m.dll
Microsoft (R) Incremental Linker Version 14.34.31937.0
Copyright (C) Microsoft Corporation.  All rights reserved.

   Creating library m.lib and object m.exp

C:\temp>ifort /c /standard-semantics /Qm32 p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on IA-32, Version 2021.8.0 Build 20221119_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.


C:\temp>link p.obj m.lib /subsystem:console /out:p.exe
Microsoft (R) Incremental Linker Version 14.34.31937.0
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\temp>
  • Program execution that proves success:

image

image

If the above works, then you can proceed to your Visual Studio solution and project file and where the DLL gets placed, etc. and fix any loose ends to resolve your problem. The above test should provide all the things to check.

But if not, you have to look at your OS config and how you are building the 32-bit target.

Thanks @FortranFan good ammo there for future issues. But setting the Target Machine (which vfproj project upgrade did not do, but VC++ project upgrade did) sorted out the problem.