Search code examples
cvisual-c++clang

Why is clang linked with msvc on windows?


I have clang installed on my Windows10 PC and when I do "clang --version" I get this info:

enter image description here

But as far as I know, msvc is a compiler on its own with which you can build a (C for example) project. What is the purpose of clang if it uses msvc ? can I change the target ?

Thank you


Solution

  • The Target output you are seeing is telling you that by default your clang compiler will emit code that is binary compatable with that produced by MSVC and can therefore be linked with the MS linker against libraries compiled with MSVC.

    Yes, you can change the target using the --target option.

    General Cross-Compilation Options in Clang

    Target Triple

    The basic option is to define the target architecture. For that, use -target <triple>. If you don’t specify the target, CPU names won’t match (since Clang assumes the host triple), and the compilation will go ahead, creating code for the host platform, which will break later on when assembling or linking.

    The triple has the general format <arch><sub>-<vendor>-<sys>-<env>, where: arch = x86_64, i386, arm, thumb, mips, etc.

    sub = for ex. on ARM: v5, v6m, v7a, v7m, etc.

    vendor = pc, apple, nvidia, ibm, etc.

    sys = none, linux, win32, darwin, cuda, etc.

    env = eabi, gnu, android, macho, elf, etc.

    For example my default is:

    $ clang --version
    Ubuntu clang version 18.1.6 (++20240518023429+1118c2e05e67-1~exp1~20240518143527.144)
    Target: x86_64-pc-linux-gnu
    Thread model: posix
    InstalledDir: /usr/bin
    
    $ cat main.c
    int main(void)
    {
        return 0;
    }
    
    $ clang -c main.c
    $ file main.o
    main.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
    

    And I can change targets like so:

    $ clang --version --target=x86_64-pc-windows-msvc
    Ubuntu clang version 18.1.6 (++20240518023429+1118c2e05e67-1~exp1~20240518143527.144)
    Target: x86_64-pc-windows-msvc
    Thread model: posix
    InstalledDir: /usr/bin
    
    $ clang --target=x86_64-pc-windows-msvc -c main.c
    $ file main.o
    main.o: Intel amd64 COFF object file, not stripped, 6 sections, symbol offset=0x143, 16 symbols, created Fri Jun 14 13:09:59 2024, 1st section name ".text"
    

    This one is for 64-bit Windows GCC compatibility.

    $ clang --target=x86_64-pc-windows-gnu -c main.c
    $ file main.o
    main.o: Intel amd64 COFF object file, not stripped, 6 sections, symbol offset=0x162, 17 symbols, 1st section name ".text"
    

    This one if for 64-bit macOS.

    $ clang --target=x86_64-apple-darwin -c main.c
    $ file main.o
    main.o: Mach-O 64-bit x86_64 object, flags:<|SUBSECTIONS_VIA_SYMBOLS>
    

    In each case clang compiles the appropriate type of object file.

    To compile and link a program even as useful as Hello World you will need to place at clang's disposal the standard header files, libraries and linker for the default or specified target triplet. Effectively you will need to have already installed a toolchain for that target triplet with which you can then use clang as your compiler. For native builds clang by default will seek out the usual toolchain for the host triplet it was built for. When cross-compiling you can point clang to the foreign toolchain with the --sysroot option. Once again see General Cross-Compilation Options in Clang