rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.76k stars 2.42k forks source link

What to do about duplicate targets in a workspace? #6293

Closed ehuss closed 5 years ago

ehuss commented 6 years ago

Currently a workspace can have multiple packages with the same target names. This causes a problem if you attempt to build both targets at the same time. One will overwrite the other when it is hardlinked in the target dir, and the result is somewhat random.

This affects binaries, examples, and libraries. Tests and benchmarks have unique hashes in their names.

I'm unsure of the best way to deal with this. One option is to issue a warning if this happens (at workspace validation phase), and turn that warning into a hard error after a sufficiently long time.

Another option is to detect if you attempt to build conflicting targets and return an error explaining you can only build one at a time (with some explanation about the naming conflict).

alexcrichton commented 6 years ago

Hm I hadn't thought of this before! I think I'd personally be a fan of the hard error though. The result is already nondeterministic and probably broken today, so as long as we don't have any false positives from the error it seems unlikely that we'll break existing working workflows!

ehuss commented 6 years ago

I download ~3300 workspaces off github to see how widespread it was. I found 63 workspaces that get tripped by this error. The rust-lang/rust repo had this problem until recently (bootstrap and rustc both had a binary called rustc until @Mark-Simulacrum changed it in rust-lang/rust#50629 — though that was changed for a different reason, rustc-the-binary and librustc had .rmeta files conflicting). There are some prominent ones like tokio, a parity project, etc. Does that change your inclination about making it a hard error right away? I don't mind, I just don't want to cause too much disruption.

CLICK - list of affected workspaces

https://github.com/Hossein-Noroozpour/vulkust/tree/master error: package more-things has a bin target with the same name `main` as package hello-world https://github.com/OpenAPITools/openapi-generator/tree/master/samples/server/petstore/rust-server error: package rust-server-test has a example target with the same name `client` as package petstore-with-fake-endpoints-models-for-testing https://github.com/vorner/spirit/tree/master error: package spirit-hyper has a example target with the same name `hws` as package spirit https://github.com/hawkw/tokio-trace-prototype/tree/master error: package tokio-trace-slog has a example target with the same name `basic` as package tokio-trace https://github.com/Arvamer/gilrs/tree/master error: package gilrs-core has a example target with the same name `ev` as package gilrs https://github.com/Avekvist/oxygen-game-engine/tree/master error: package oxygen_electron has a example target with the same name `temporary` as package oxygen_bond https://github.com/Grokmoo/sulis/tree/master error: package sulis has a bin target with the same name `main` as package sulis_editor https://github.com/diesel-rs/diesel/tree/master error: package diesel_demo_step_2_mysql has a bin target with the same name `show_posts` as package diesel_demo_step_1_mysql https://github.com/msiglreith/tanya/tree/master error: package tanya-ui has a example target with the same name `basic` as package tanya-ecs2 https://github.com/tobyjsullivan/fonts/tree/master error: package fonts has a bin target with the same name `about` as package about https://github.com/tokio-rs/tokio/tree/master error: package tokio-tls has a example target with the same name `echo` as package tokio https://github.com/rust-av/opus-rs/tree/master error: package libopus has a example target with the same name `encode` as package opus-sys https://github.com/qnighy/honeybadger-rs/tree/master error: package honeybadger-gotham has a example target with the same name `server` as package honeybadger-rocket https://github.com/Nemo157/embrio-rs/tree/master error: package pca10031 has a example target with the same name `hello` as package local https://github.com/mit-pdos/noria/tree/master error: package noria-server has a example target with the same name `basic-recipe` as package noria https://github.com/sozu-proxy/sozu/tree/master error: package sozu-command-futures has a example target with the same name `main` as package sozu-lib https://github.com/dgrunwald/rust-cpython/tree/master error: package python3-sys has a example target with the same name `version` as package python27-sys https://github.com/rustkas/rust-by-example-imp/tree/master/rust-by-example error: package types has a bin target with the same name `literals` as package primitives https://github.com/sozu-proxy/lapin-futures-tls/tree/master error: package lapin-futures-native-tls has a example target with the same name `client` as package lapin-futures-tls-internal https://github.com/diwic/dbus-rs/tree/master error: package dbus-codegen has a example target with the same name `adv_server` as package dbus https://github.com/paritytech/jsonrpc/tree/master error: package jsonrpc-minihttp-server has a example target with the same name `server` as package jsonrpc-http-server https://github.com/SergioBenitez/Devise/tree/master error: package from_form_value has a bin target with the same name `main` as package uri_display https://github.com/kureuil/batch-rs/tree/master error: package batch-example-rabbitmq-warp has a bin target with the same name `worker` as package batch-example-rabbitmq-standalone https://github.com/glebpom/rust-netif/tree/master error: package netif-bpf has a example target with the same name `test` as package ifcontrol https://github.com/cogciprocate/ocl/tree/master error: package ocl-core has a example target with the same name `info_core` as package ocl https://github.com/rust-av/speexdsp-rs/tree/master error: package speexdsp has a example target with the same name `testresample` as package speexdsp-sys https://github.com/ubnt-intrepid/doubter/tree/master error: package doctest-edition2018 has a lib target with the same name `doctest` as package doctest https://github.com/lettre/lettre/tree/master error: package lettre_email has a example target with the same name `smtp` as package lettre https://github.com/weiznich/wundergraph/tree/master error: package wundergraph_bench has a bin target with the same name `main` as package wundergraph_example https://github.com/WiSaGaN/ctp-rs/tree/master error: package ctp-trader has a example target with the same name `api` as package ctp-md https://github.com/marhel/r68k/tree/master error: package r68k-tools has a example target with the same name `asm` as package r68k-emu https://github.com/dtcristo/raylib-rust/tree/master error: package raylib-sys has a example target with the same name `raylib_rust_logo` as package raylib https://github.com/Hoverbear/rust-rosetta/tree/master error: package 24-game has a bin target with the same name `main` as package 100-doors https://github.com/LevitatingOrange/oblivious-transfer/tree/master/examples error: package beaver_triples_gen has a bin target with the same name `client` as package simple_transfer https://github.com/erlepereira/x11-rs/tree/master error: package x11-dl has a example target with the same name `hello-world` as package x11 https://github.com/johalun/rustkpi/tree/master/rust/rust-src-1.25.0/src error: package rustc-main has a bin target with the same name `rustc` as package bootstrap https://github.com/royallthefourth/platformsh-rust-rocket/tree/master error: package rust-example has a bin target with the same name `backend` as package backend https://github.com/George3d6/Inquisitor/tree/master error: package receptor_plugins has a lib target with the same name `plugins` as package agent_plugins https://github.com/hhatto/rust-snippets/tree/master/extension error: package pyo3-woothee has a lib target with the same name `woothee` as package fast-woothee https://github.com/little-dude/netlink/tree/master error: package rtnetlink has a example target with the same name `dump_links` as package iproute2 https://github.com/king6cong/moon/tree/master error: package c_replace has a bin target with the same name `render` as package c_markdown https://github.com/tailhook/abstract-ns/tree/master error: package ns-dns-tokio has a example target with the same name `resolve` as package ns-std-threaded https://github.com/elastic-rs/elastic/tree/master error: package elastic_reqwest has a example target with the same name `basic_async` as package elastic https://github.com/kabelyang/Parity-JSON-RPC/tree/master error: package jsonrpc-minihttp-server has a example target with the same name `server` as package jsonrpc-http-server https://github.com/gretchenfrage/ws_problem/tree/master error: package workspace_test has a bin target with the same name `root` as package root https://github.com/mimirblockchainsolutions/mimir-rust-alpha/tree/master error: package mimir-requester has a example target with the same name `simple` as package pubnub-hyper https://github.com/benywan/jsonrpc/tree/master error: package jsonrpc-minihttp-server has a example target with the same name `server` as package jsonrpc-http-server https://github.com/akashche/itw_win_devkit/tree/master/rust/src error: package rustc-main has a bin target with the same name `rustc` as package bootstrap https://github.com/stefan-k/kraxn/tree/master error: package kraxn has a bin target with the same name `kraxn-server` as package kraxn-server https://github.com/jjpe/amplify/tree/master error: package amplify has a bin target with the same name `amplify` as package amplify-core https://github.com/super-string/jsonrpc/tree/master error: package jsonrpc-minihttp-server has a example target with the same name `server` as package jsonrpc-http-server https://github.com/randomPoison/polygon/tree/master error: package gl-util has a example target with the same name `hello_triangle` as package polygon https://github.com/mob-rs/mob/tree/master error: package mob_server has a bin target with the same name `main` as package mob https://github.com/ryoon/rustc-1.19.0/tree/master/src error: package rustc-main has a bin target with the same name `rustc` as package bootstrap https://github.com/KeenS/onigmo-rs/tree/master error: package onigmo has a example target with the same name `simple` as package onigmo-sys https://github.com/sorpaas/devp2p-rs/tree/master error: package rlpx has a example target with the same name `local_connect` as package dpt https://github.com/sujayakar/rust-rt/tree/master/rust-cpython error: package python3-sys has a example target with the same name `version` as package python27-sys https://github.com/combustion-engine/combustion/tree/master error: package combustion_window has a example target with the same name `glfw` as package combustion_backend https://github.com/aidanhs/rust-appveyor/tree/master/src error: package rustc-main has a bin target with the same name `rustc` as package bootstrap https://github.com/zzeroo/ArcadeRS-1.0/tree/master error: package arcade-rs-1-5 has a example target with the same name `thing` as package arcade-rs-1-4 https://github.com/JBisnett/rust-mir-plugin/tree/master/src error: package rustc-main has a bin target with the same name `rustc` as package bootstrap https://github.com/Metadiff/gir/tree/master error: package gir_af has a bin target with the same name `test` as package gir_core https://github.com/lazybox/lazybox/tree/master error: package lazybox_settings has a example target with the same name `simple` as package lazybox_inputs

alexcrichton commented 6 years ago

Hm that's quite a few! I wonder, though, if we can still get away with making this a hard error. If we change it to say that in one build if more than one binary of the same name is produced with the same name that's an error, then that may mostly cover our bases. Today's behavior is "pretty wrong" in the sense that it's just giving you a random binary with the right name, so it seems unlikely that anyone's build steps are building the same named binary in the same build step.

I think it's probably best though, given this data, to start with a warning. I think the warning should be scoped to only where we'd want a hard error eventually (probably only for when you're building two binaries of the same name, not if they just exist in a workspace).