conan icon indicating copy to clipboard operation
conan copied to clipboard

[feature] Support for zig as a C and C++ compiler

Open dheater opened this issue 2 years ago • 7 comments

What is your suggestion?

I would like to be able to use the zig compiler to build C and C++ so I can use its support for cross-compilation and selectable libc support

Have you read the CONTRIBUTING guide?

  • [X] I've read the CONTRIBUTING guide

dheater avatar Apr 04 '23 01:04 dheater

Hi @dheater

Thanks for your suggestion. I think zig is great, and it could be great to have support for it in Conan. However we lack the necessary expertise for it, this wouldn't be a minor feature, it is necessary to create integrations for the build system like ZigDeps, ZigToolchain, Zig, etc, then add possible configuration... It is simply too much for the team. If there is enough interest from the Zig community we would of course try our best to help. In that case I'd recommend first building it as external (it can be iterated much faster, it could be a repo in our org, or maybe in the zig org if they are willing to do so) to be used as python-requires, and when it gets some usage and stabilizes, we could consider making it built-in.

memsharded avatar Apr 04 '23 09:04 memsharded

Hi @memsharded , just found this request since I was tinkering with zig.

I wanted to build a small project using zig's C++ compiler mostly because it allows me to build static binaries with musl really easily. For example, here's how I would compile a very simple hello world using CMake

cmake_minimum_required(VERSION 3.10)
add_executable(main main.cpp)
#include <iostream>

int main()
{
    std::cout << "Hello world" << std::endl;
    return 0;
}

export CXX="zig c++ -target x86_64-linux-musl"
export CC="zig cc -target x86_64-linux-musl"
mkdir build & cd build
cmake ..
cmake --build .

My question is: is there any way I can use conan to build third party dependencies (with conan install --build=all) so that I can use conan with my project? If not an official way, is there any way I can hack a new compiler into the settings.yml file?

Note that zig uses uses clang for compiling c/c++

gavin@amazo:~$ zig c++ --version
clang version 18.1.7 (https://github.com/ziglang/zig-bootstrap ec2dca85a340f134d2fcfdc9007e91f9abed6996)
Target: x86_64-unknown-linux-musl
Thread model: posix
InstalledDir: /usr/bin

GavinNL avatar Jun 27 '24 14:06 GavinNL

Hi @GavinNL

If you are using CMake, sure, Conan can integrate with that, and you can use conan install to bring your dependencies. But do you need your dependencies to be built with zig too? It is not very clear. Conan can define [buildenv] environment variables or even configuration conf tools.build:compiler_executables to inject compilers and use them for the dependencies.

If zig c++ is kind of a replacement of gcc, then I guess it might be possible to use it with a gcc-like profile, just changing the specific CXX compiler?

memsharded avatar Jun 27 '24 16:06 memsharded

Ahh thank you for the info. I ended up getting it to work by creating a zig profile:

[settings]
os=Linux
arch=x86_64
compiler=clang
compiler.version=18
compiler.libcxx=libstdc++11
build_type=Release

[buildenv]
CC="/usr/bin/zigcc"
CXX="/usr/bin/zigpp"

I had to create two shell scripts zigcc/zigpp that would pass the command line arguments directly to zig cc and zig c++. I also specifically set the zig -target to use the musl libc so that I can build a static binary.

zig c++ -target x86_64-linux-musl "$@"

I had to do this because cmake was causing problems trying to determine the compiler when I set the env variable CXX=zig

The full command line args were:

cd src
mkdir build && cd build

export CC=/usr/bin/zigcc
export CXX=/usr/bin/zigpp

conan install .. -pr zig --build=missing -s compiler.libcxx=libstdc++11 -s:h "&:build_type=Release" -of $PWD -g CMakeDeps

cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_MODULE_PATH=$PWD

I tried this using the Bullet physics library as a dependency, and it was able to build bullet and my application using the zig c++ compiler and static link it.

GavinNL avatar Jun 27 '24 17:06 GavinNL

I tried this using the Bullet physics library as a dependency, and it was able to build bullet and my application using the zig c++ compiler and static link it.

Happy to hear that!

As a couple of extra suggestions:

  • compiler.cppstd setting definition is recommended in most cases
  • Adding a [layout] section with cmake_layout in your conanfile.txt will allow to further simplify your command line, removing the -of argument and having cleaner folders
  • You can add CMakeDeps in the conanfile [generators]. If you also add CMakeToolchain it will generate a toolchain file and a presets file, so cmake --preset will be enough, and it is generally easier to keep the arguments between conan install and cmake aligned.
  • The approach above does not distinguish binaries created with clang or zig. It will have identical package_id for both and consider them fully compatible. Conan has several mechanisms to add information to package_id to differentiate them if you want, like defining new custom settings, or using conf tools.info.package_id:confs to define which confs defined in the profile become part of the package-id. Unless you want 100% fully compatibility between zig and clang and you don't need the traceability to know which binary was built with zig or clang, this would be recommended.

memsharded avatar Jun 27 '24 17:06 memsharded

  • The approach above does not distinguish binaries created with clang or zig. It will have identical package_id for both and consider them fully compatible. Conan has several mechanisms to add information to package_id to differentiate them if you want, like defining new custom settings, or using conf tools.info.package_id:confs to define which confs defined in the profile become part of the package-id. Unless you want 100% fully compatibility between zig and clang and you don't need the traceability to know which binary was built with zig or clang, this would be recommended.

Thanks for the suggestion! I changed my profile to this, is it correct?

[settings]
os=Linux
arch=x86_64
compiler=clang
compiler.version=18
compiler.libcxx=libstdc++11
build_type=Release

[buildenv]
CC="/usr/bin/zigcc"
CXX="/usr/bin/zigpp"

[conf]
user:custom_compiler=zig
tools.info.package_id:confs=["user:custom_compiler"]

GavinNL avatar Jun 27 '24 19:06 GavinNL

Yes, that looks good.

You should be able to easily verify it with a conan list "mypkg:*" for example, after building the package.

Maybe a bit more specific user.myorg:custom_compiler to avoid potential issues in the future, if integrating with other users, but that seems unlikely, relatively low risk.

memsharded avatar Jun 27 '24 19:06 memsharded