~lattis/muon#52: 
ninja.build: multiple rules for target

muon sometimes generates multiple rules with the same name. A minimal reproducer is below:

./my_project.c:

int main(void)
{
	return 0;
}

./meson.build:

project('my_project', 'c')

samplelib_dep = dependency(
    'samplelib_nonexisting',
    fallback: ['samplelib', 'samplelib_dep'],
)

executable(
    'my_project',
    'my_project.c',
    dependencies: samplelib_dep,
    install: false,
)

./subprojects/samplelib/sample.c:

void samplelib_function(void)
{
	// Empty
}

./subprojects/samplelib/meson.build:

project('sample', 'c')
cc = meson.get_compiler('c')

lib_samplelib = library(meson.project_name(), ['sample.c'])
samplelib_dep = declare_dependency(link_with: lib_samplelib)

static_samplelib = library(meson.project_name(), ['sample.c'])
samplelib_static_dep = declare_dependency(link_with: static_samplelib)

Running meson setup build fails with the following message:

....
subprojects/samplelib/meson.build:7:0: ERROR: Tried to create target "sample", but a target of that name already exists.

Running muon setup build however generates an invalid build.ninja. Running samu or ninja on that file produces the following error:

samu: entering directory 'build'
samu: multiple rules generate 'subprojects/samplelib/libsample.a.p/sample.c.o'
Status
RESOLVED CLOSED
Submitter
~seedopaul
Assigned to
No-one
Submitted
2 years ago
Updated
2 years ago
Labels
No labels applied.

~seedopaul 2 years ago

Some more information that could be relevant: I stumbled upon this when I tried to compile this project with muon. Weirdly, meson doesn't error out on that project and even generates the correct build.ninja file.

~lattis 2 years ago

I agree that meson's error is quite helpful. It looks like the problem with the linked project is in the tomlc99 subproject. The offending meson.build does this:

library('toml', ...)
static_library('toml', ...)

Meson's default value for default_library is shared, so this becomes equivalent to:

shared_library('toml', ...)
static_library('toml', ...)

muon's default value for default_library is static, so the build instead becomes:

static_library('toml', ...)
static_library('toml', ...)

Which is invalid.

~seedopaul 2 years ago

That makes sense, thanks for the explanation!

muon's default value for default_library is static, so the build instead becomes:

Just curious: why was static chosen as the default for muon?

~lattis 2 years ago

I did it because a) static libraries were easier to implement, so it was all muon supported for awhile, b) I generally prefer static linking, c) It helps expose "broken" builds. In this case, I would say tomlc99's build is "broken" because it doesn't work for some values of default_library. Since they always want a shared library there, they should use shared_library instead of library. Or, better yet, both_libraries() which already does what they want.

~seedopaul 2 years ago

Thank you very much for the clarification!

~lattis REPORTED CLOSED 2 years ago

Register here or Log in to comment, or comment via email.