-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide 'rename' capability for installing executables and libraries #4019
Comments
Renaming of build targets can't be done reliably for many reasons. For instance, the soname would be wrong, on macOS the We should try to find some other way to solve your problem, because it seems to be a workflow that should work for all targets. I looked at your build files, and it seems the list of multilib targets is dynamic, and multiple library targets are defined with different This means the library targets must be placed in subdirs dynamically, which is what happens when you define
Alternatively you could do multilib at a higher level, by only building for one target in the build files, and use separate build directories for each target. The configuration time should be trivial, and since you can't share object files between multilib targets anyway, it's not any less efficient. PS: Instead of passing |
Thanks for taking a look at my little issue. I did start by wrapping meson in a script that generated separate build directories; that 'works', but it's quite clunky to use; getting debian packaging wrapped around that would require a fairly sophisticated script, which starts to feel like autotools all over again. Having all of the magic contained in meson configuration files seems so clean and it very nearly works already (well, actually it does work, except for the dire warnings). As for using different temporary names; we have both names available at link time, so (at least on linux), we could pass -soname= so that the file contained the correct information for run-time. I wonder if there are similar flags for OS X and Windows? Oh, I tried adding 'b_staticpic=false' to my project default_options and it didn't work -- the compiler was still getting -fPIC on the command line. |
The problem happens when other things in your project link to that library, then you need to rewrite the DT_NAME/install_name and RPATHs for everything (on Linux/BSD/macOS), and afaik there's no way to change the contents of an implib, but we could write a manual rewriter. So overall, it's all doable, but it's a question of whether it's worth the greatly increased complexity. Thinking about this more, I think the general case for this is to build the same target multiple times with different See: #3304 and #3819. The original idea was to be able to be able to map each Build the same library as static and shared with different tspec = {
'static': {'c_args': ['-DFOO_STATIC'], 'target_type': 'static_library'},
'shared': {'c_args': [], 'target_type': 'shared_library'},
}
library('foo', sources, target_spec: tspec) Build multiple static libraries for different multilib archs tspec = {
'32' : {'c_args': ['-m32'], 'install_dir': 'lib32'},
'64' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
'x32' : {'c_args': ['-blah'], 'install_dir': 'lib'},
}
static_library('foo', sources, target_spec: tspec)
Thinking about the implementation details (resolving library paths, RPATHs, etc) it all seems easy to implement. The return value of As plus, this resolves the question we've had about how to pass kwargs to functions since it doesn't require new syntax in the parser.
I will investigate this. This use-case was exactly why that builtin-option was added and we have tests for this. |
Trying to build two architectures (-m32 and -m64) at the same time in the same project is fraught with danger. Usually it makes more sense to have two build directories, one set up to 32 bit and one to 64 bit and compile and install them both separately. |
Agreed that it's generally better to use separate build directories, but in this case I'm actually detecting which multilib configurations are available right in the build system; I don't know beforehand what those are. The existing autotools build system for this project works this way; I'd like to replicate that within meson rather than needing external kludges, of course. |
Thinking more, I realized that another reason for having this mechanism to build the same library twice with different So I think we need to implement a mechanism that allows this anyway. Then, whether or not people decide to take the risk of passing 'interesting' compiler args like |
I really like this Example: tspec = {
'32' : {'c_args': ['-m32'], 'install_dir': 'lib32'},
'64' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
'x32' : {'c_args': ['-blah'], 'install_dir': 'lib'},
}
lib = static_library('foo', sources, target_spec: tspec) I guess {
'32' : StaticLibraryHolder,
'64' : StaticLibraryHolder,
'x32' : StaticLibraryHolder,
} I don't think we should allow doing exe_tspec = {
'32' : {'c_args': ['-m32'], link_with : lib['32']},
'64' : {'c_args': ['-m64'], link_with : lib['64']},
'x32' : {'c_args': ['-blah'], , link_with : lib['x32']},
}
exe = executable('app', app_sources, target_spec : exe_tspec)
Now how would it work with tspec = {
'32' : {'c_args': ['-m32'], 'install_dir': 'lib32'},
'64' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
'x32' : {'c_args': ['-blah'], 'install_dir': 'lib'},
}
lib = both_libraries('foo', sources, target_spec: tspec) Following the same logic, {
'32' : BothLibrariesHolder,
'64' : BothLibrariesHolder,
'x32' : BothLibrariesHolder,
} And if we want different tspec = {
'32' : [{'c_args': ['-m32', '-DSTATIC_COMPILATION'], 'install_dir': 'lib32', target_type : 'static_library'},
{'c_args': ['-m32'], 'install_dir': 'lib32', target_type : 'shared_library'}]
'64' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
'x32' : {'c_args': ['-blah'], 'install_dir': 'lib'},
}
lib = both_libraries('foo', sources, target_spec: tspec) So if the value in tspec dict is a list, it picks the one that has tspec = {
'32' : {
'static_library' : {'c_args': ['-m32', '-DSTATIC_COMPILATION'], 'install_dir': 'lib32'},
'shared_library' : {'c_args': ['-m32'], 'install_dir': 'lib32'},
}
'64' : {
'static_library' : {'c_args': ['-m64', '-DSTATIC_COMPILATION'], 'install_dir': 'lib64'},
'shared_library' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
}
'x32' : {
'static_library' : {'c_args': [''-blah'', '-DSTATIC_COMPILATION'], 'install_dir': 'lib'},
'shared_library' : {'c_args': [''-blah''], 'install_dir': 'lib'},
}
} It's getting complicated structure, but it covers all cases. Also it means if we want different c_args for shared and static, we are forced to have tspec = {
'static_library' : {'c_args': ['-DSTATIC_COMPILATION']},
}
lib = both_libraries('foo', sources, target_spec : tspec) Where |
To summary, I see 3 different formats possible for tspec, and possibly a mix of them:
We could probably check the values of keys in the dict to determine which case we have, but stuff are getting a bit 'magical' IMHO. |
otoh, we are not force to fit everything in a single dict. It would make a lot of sense to split this into 2 separate features: multilib_args = {
'32' : {'c_args': ['-m32'], 'install_dir': 'lib32', name_prefix : 'lib1'},
'64' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
'x32' : {'c_args': ['-blah'], 'install_dir': 'lib'},
}
tspec = {
'static_library' : {'c_args': ['-DSTATIC_COMPILATION'], name_prefix : 'lib2'},
}
lib = library('foo', sources, multilib : multilib_args, target_spec : tspec, c_args : ['-DFOO'], name_prefix : 'lib3')
|
Is tspec approach will allow us to build a same library with different dependencies, but for same arch? |
I don't like the fact that we are putting many different target specifications into one target invocation. It is not readable and very confusing. For example it is hard to tell which compiler flags are in effect, basically you need to replicate the detection logic inside your head. I also particularly don't like the fact that the output of |
@jpakkane I expected that answer, and I mostly agree tbh. I think the multilib part is far fetched, that's why in my last comment, I made a proposal that split This bug here is about the multilib part, the most controversial because it would require Bugs #3304 and #4133 are about passing different args for static and shared libraries when using
But that's orthogonal to this bug, since I think we shouldn't have one kwarg for both use cases. |
Back to initial problem; multilib can be implemented like that, a bit verbose but not that bad IMHO: multilib_spec = {
'32' : {'c_args': ['-m32'], 'install_dir': 'lib32'},
'64' : {'c_args': ['-m64'], 'install_dir': 'lib64'},
'x32' : {'c_args': ['-blah'], 'install_dir': 'lib'},
}
lib = {}
foreach arch, spec : multilib_spec
lib += {arch : library('foo', sources, c_args : spec['c_args'], install_dir : spec['install_dir'])}
endforeach The only problem is it's going to create a target id collision. To fix that collision, Target.get_id() needs to somehow take into account the Or we could add a new kwarg to let user explicitly uniquify the id, the above example could become: |
(I removed a comment I accidentally posted on the wrong thread.) |
I need the 'rename' capability as well, but for a very different reason. Since meson doesn't support user-defined subroutines, the only sensible solution is to have the |
I actually ran into a use for this as well (I think my use is closer to @le-jzr's), in xts, tests are installed in a nested structure, with many subdirectories containing binaries that are invoked as subprocesses, and have overlapping names (extensions added for clarity):
Due to our target name duplication restriction I have to have an install script that renames them, if I could simply have something like: executable(
'feature-test1',
...
install_as : 'test1',
install_dir : unique_dir_path,
) That would be convenient. |
Instead of looking for the `-uninstalled` suffix in the program name (that requires renaming the binaries after the installation), check if the program is called from BUILDDIR. This allows to switch from autotools to meson, where the latter does not handle renaming installed file properly: mesonbuild/meson#4019
I also would appreciate this feature for another reason. I'm trying to use a cmake project as a subproject, but this project uses LIBRARY_OUTPUT_NAME, for which there is no equivalent meson flag. This means I can't use this subproject as a fallback for a dependency (if the subproject was installed to the system via cmake) without some weird hackiness. |
I'm building a multilib library, which means the library is built multiple times, once per multilib target. For installation, each library ends up in a target-specific directory using their 'plain' name. For compilation, I'm creating per-target names for the library. That means the compiled library file name doesn't match the install library file name, so I'm hoping to have something like the 'rename' option that other install methods support to let me set the install filename for each target to match the 'plain' name.
I actually have a kludge which is working for now -- the per-target name I'm using has the target as a directory prefix, which makes the install 'work', but causes meson to emit dire warnings about abuse of the system.
Here's the system I'm creating, if you would like to see what it does.
https://salsa.debian.org/electronics-team/newlib-nano
The text was updated successfully, but these errors were encountered: