Skip to content
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

out-of-source build support? #468

Closed
Prince213 opened this issue Nov 28, 2019 · 14 comments · Fixed by #528
Closed

out-of-source build support? #468

Prince213 opened this issue Nov 28, 2019 · 14 comments · Fixed by #528

Comments

@Prince213
Copy link
Contributor

Please add support for building out-of-source. It makes the source tree cleaner and easier to build multiple version at the same time without copying files.

@minad
Copy link
Member

minad commented Nov 28, 2019

You mean that the object files are created inside some separate build directory. I would like to have that too. If someone likes to create a PR I would appreciate it.

@minad minad closed this as completed Nov 28, 2019
@minad minad reopened this Nov 28, 2019
@nijtmans
Copy link
Collaborator

nijtmans commented Dec 1, 2019

Well, I would like this too. FYI: libtommath 1.2.0 is now officially available in Cygwin (I created the "libtommath.cygport" file and registered myself as its Cygwin maintainer) ;-)

Cygport requires a separate build directory too, so I had to work around that ....

@Qix-
Copy link

Qix- commented Nov 22, 2021

Why not just switch to CMake? This gives you out of source builds, cross-platform/-compiler builds, allows the library to be used as a module in a larger build project, etc.

@assarbad
Copy link

@Qix- apologies for chiming in so rudely, but there's something I love about the flexibility libtom libraries give me in regards to which build system I want to use. Certainly there is room for improvement. But they don't impose. Your wording implies replacing the existing options for one other.

Let me state it plainly: I am fully against that.

Adding a CMakeLists.txt? Fair enough! Knock yourself out. But replacing the existing stuff for a CMakeLists.txt, please don't.

CMake is hyped, sure. But it's not a convenient tool, by any stretch. (No, this is no prejudice either, I have extensively worked with CMake both on Windows and unixoid systems and even contributed a commit.) It has its uses and, I'll agree that there are really good ideas in it. However, the ghastly syntax, the fact that the gap between multi-config and single-config generators is vast (it used to be the defining gap between MSVC vs. others at one point) and that generated projects depend on the local system are all reasons for me to dislike it. The last part also being the reason why it isn't possible to build a CMake _on and for Linux which will be able to generate VS solution/project files. There is no logical reason for this, it's a design flaw - and one that hasn't been addressed. At least now the generated VS projects are more readable. In the past all the compiler, librarian ("archiver") and linker options were stuffed into the field for the command line, completely obviating the use of a project in the first place. CMake is sloooooooow on Windows during its "configure" ("generate") phase for MSVC. So annoyingly slow that I would never impose it on any fellow developer alone for that reason. Also: the internet is full of outdated advice for CMake.

If you use other project generators such as GYP, Premake4 (or its successor Premake5), Waf you will notice that a VS solution/project can be generated without having VS installed. That's how it should be. As it stands CMake doesn't offer this. CMake wants to be everything. Other tools limit themselves to being a project generator (list above) or a fast make alternative (think Ninja). And, sticking to the Unix philosophy of doing one thing but doing that really really well, excel in their niches.

Why not go for Meson instead of CMake with the same reasoning? But again that imposes on the developers trying to use the library. Any decent developer system has some form of make. Most of those should be covered already, looking at libtommath. (Modern) VS is covered by providing an old VS2008 solution and project. Unfortunately these different makefiles/projects appear to be in a varying state of deterioration/maintenance. That's because there is no single source of truth.

In conclusion: I'm all for adding to the current array of options, but don't take away from them imposing a single subpar tool on me.

PS: in my endeavor to get the VS solution/project generation unified (#525), I'll try to take into account the desire for out-of-tree builds. It should/would also be able to generate GNU makefiles, though (unless I explicitly remove the ability).

@Qix-
Copy link

Qix- commented Feb 13, 2022

apologies for chiming in so rudely

Then don't?

flexibility libtom libraries give me in regards to which build system I want to use

GNU Make is not what I would consider "flexible".

CMake is hyped, sure.

"Hyped" is a weird word given that it's present in the vast majority of C and C++ libraries in the OSS world.

the ghastly syntax

Completely subjective.

the fact that the gap between multi-config and single-config generators is vast

What does this even mean?

generated projects depend on the local system

What does this even mean?

generate VS solution/project files

There is no official specification for visual studio files, as they change often. Any attempts at building them without the help of VS tooling is futile as inevitably Microsoft will change them from release to release. As someone who writes build systems for fun, Microsoft tooling is a pain in the ass. Requiring VS tooling to be installed is the sanest way to handle VS project generation.

There is no logical reason for this

Of course there are. Have you asked the developers of CMake? Or are you assuming?

[GYP, Premake, Waf, etc.]

There are loads of reasons not to use these. Project interoperability is a huge one - wiring up dependencies is a PITA with lesser-capable libraries. Exposing targets for consumption via submodules, for example, is not very ergonomic with simpler build systems.

That's how it should be.

You should take that up with Microsoft, then. That seems to be your only real gripe - which has little to do with CMake.

Ninja

Not a fair comparison. Ninja configurations are meant to be generated, not hand-written. Not sure why you're comparing it to CMake, as CMake uses it exactly how it's intended.

And, sticking to the Unix philosophy of doing one thing but doing that really really well, excel in their niches.

Unix hasn't followed that philosophy since the 80's. Neither have GNU Make, Meson, Bazel, Buck, Premake, SCons, or GYP. Or straight shell scripts, for that matter. The only build system that comes to mind that really follows this is rebuild, and it never took off and died a decade or two ago.

Why not go for Meson instead of CMake with the same reasoning?

Because Meson imposes software development philosophies that don't mimic reality and its maintainers have proven themselves to be very dogmatic and uninterested in allowing projects any freedom in how they structure their codebases. They've also demonstrated time and time again a complete lack of understanding of how build systems work, dying on strange hills regarding duplicate symbols and the like and asserting things that simply are not true.

I'm all for adding to the current array of options

You don't seem to be. With all due respect, it sound like you either misunderstand build systems, or at least CMake/VS tooling, or you haven't worked with it a whole lot.

Adding Premake is your own opinionated change and isn't going to help a lot of people who would like to incorporate this into their own codebases - they will inevitably have to write their own build configs anyway. At least with a CMake configuration, this library is just one add_subdirectory() away for larger projects that use CMake and avoid "nicheness".

@sjaeckel
Copy link
Member

Sorry for brevity but I'm on mobile only.

The plan is

  • replace vs2008 solution by premake thing
  • add cmake support

The rest remains as is.

The ground truth is the makefile.

@Prince213
Copy link
Contributor Author

Maybe we can remove vs files and instread use cmake to generate them when needed. CMake seems to be trivial to install on windows.

@Prince213
Copy link
Contributor Author

@assarbad

As it stands CMake doesn't offer this.

Actually it does: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators

CMake indeed doesn't use a syntax that makes everyone happy, but more projects are using it (compared to Premake), and can thus benefits more people.

@eli-schwartz
Copy link

@Prince213 the argument seems to be rather that cmake will first check if VS is installed, error out if it is missing, and only if it is installed will cmake run the VS generator and produce such a project.

Because Meson imposes software development philosophies that don't mimic reality and its maintainers have proven themselves to be very dogmatic and uninterested in allowing projects any freedom in how they structure their codebases. They've also demonstrated time and time again a complete lack of understanding of how build systems work, dying on strange hills regarding duplicate symbols and the like and asserting things that simply are not true.

@Qix- I'm not sure what exactly you mean by this, but I think every time I've seen anyone complain about Meson denying a project the freedom to structure their codebase it has turned out to be one of exactly two things:

  • meson allows you to structure your code however you want, but refuses to allow you to output your build artifacts however you want and instead insists that outputs end up in the build directory corresponding to the source meson.build
    You can of course output your build artifacts to whichever directory you like, but that does force you to add new source directories and place a meson.build file in that directory to build it.
  • Meson is Mr. Angry Face and forces all thirdparty subprojects to be stored in a single directory. Adding a subproject is done via name and looked up in that directory, it is NOT done by arbitrary path.

By "strange hills regarding duplicate symbols" do you mean that Meson solves the diamond dependency issue by erroring out if both versions of dependency X cannot resolve to a shared version? I assume you prefer the way it works in nodejs, where each library contains its own private copy of the dependency and refers only to that?

It is theoretically possible to solve the diamond dependency issue in C/C++ using versioned symbols via GNU binutils version scripts. Or by regularly renaming all symbols in your headers, possibly with #defines to preserve API compatibility. But frankly this isn't a scalable or portable approach. And if you do use it, Meson doesn't care! It lets you. You just need to name the subproject dependency foo-1 and foo-2 rather than calling it foo.

Diamond dependency problems are hell, yes, but disagreeing with people about how to solve it doesn't mean that the other party doesn't know understand build systems, and insulting them about it and calling it "strange hills" is simply shameful, and intentionally arguing in bad faith.

generated projects depend on the local system

What does this even mean?

I assume this is more of "cmake doesn't let you generate a VS project unless you have VS installed", but with the additional observation that the generated VS project even when VS is installed, includes command invocations that try to run the cmake.exe that generated it.

There is no official specification for visual studio files, as they change often. Any attempts at building them without the help of VS tooling is futile as inevitably Microsoft will change them from release to release. As someone who writes build systems for fun, Microsoft tooling is a pain in the ass. Requiring VS tooling to be installed is the sanest way to handle VS project generation.

Given the previous observations, the difference of opinions is plain here.

You both agree that VS solutions should be generated. But you believe VS solutions should be generated by the person doing the building, who has cmake installed and is not building with "VS", but rather building with "cmake + VS", while @assarbad believes VS solutions should be generated (and regularly updated) by the project developers, who check the results into git and distribute it for the sake of people who have only VS, do not want to install cmake, and want to clone the repo and immediately build it with VS.

GYP in comparison was in part designed specifically so that Google could ship release tarballs that contain every target build system already pregenerated. In GYP's documentation, it specifically compares "GYP vs. CMake":

  1. Cross platform generation. CMake is not able to generate all project files on all platforms. For example xcode projects cannot be generated from windows (cmake uses mac specific libraries to do project generation). This means that for instance generating a tarball containing pregenerated projects for all platforms is hard with Cmake (requires distribution to several machine types).

Presumably @assarbad wants this.

the ghastly syntax

Completely subjective.

I dunno, it feels pretty objective to point out that cmake syntax is from the 1980s bourne shell approach of "everything is a quotes-optional string, and lists are also strings, but whitespace semicolon delimited". Even GNU bash managed to improve the bourne shell by add real arrays a decade before cmake's original release. And even the bourne shell has one real array called "$@"

@eli-schwartz
Copy link

Anyway, the project policy is already:

The ground truth is the makefile.

Any support for any other build system will be secondary and presumably primarily geared toward integration with other projects. With that in mind, I would like to posit that there is a significant reason to include both cmake and meson and probably Bazel too if someone wants to contribute one. But not premake or scons or waf.

Reason being, at least cmake and meson are popular build systems, which include mechanisms for including another project as a subproject build. And those mechanisms depend on having existing support for that build system in the subproject.

Meson allows this via https://mesonbuild.com/Wrap-dependency-system-manual.html#provide-section, just drop an ini file in subprojects/libtommath.wrap and all existing lookups for libtommath.pc can use the subproject instead (you don't even need to modify the build system). Requires meson.build for libtommath.

Cmake has at least 3 different methods -- that involve adding if/elsed code to your build system files if you want to support libtommath.pc -- as well as usually baking urls and versions and checksums into your build system files in most cases, which does feel a bit awkward, but has the same effect. Requires CMakeLists.txt for libtommath.

@Qix-
Copy link

Qix- commented Feb 13, 2022

Yep and if you have two subprojects that both have their own version of libtommath, even if they don't link against each other, Meson refuses to let you build your project. It's a nonsense build system.

Do whatever is right for the project, but you'll have premake, cmake, meson and makefiles. It's a bit ludicrous, but if you want to maintain it, go for it.

@assarbad
Copy link

assarbad commented Feb 13, 2022

@Qix-

Completely subjective.

I know several huge fans of CMake who concur with my completely subjective assessment. Doesn't bother them as fans of CMake, though. But it's subjective, true. So conversely I take it your comment is objective and authoritative and not merely an opposing view to mine?

NB: A look at generator expressions in the documentation may enlighten inclined readers of our debate, though. Just as a small example of the (subjectively! 😉) ghastly syntax.

the fact that the gap between multi-config and single-config generators is vast

What does this even mean?

If you don't know the difference between multi-config and single-config generators in CMake -- and don't know in which ways you run into trouble when targeting the (seemingly much less tested) multi-config generators (MSVC vs. GNU make is a continuous source of "joy" in that regard) -- you haven't worked with it in-depth as far as I'm concerned.

generated projects depend on the local system

What does this even mean?

It means that you can't hand the generated project to another developer without - on their machine - mimicking a large portion of what you have on your local system; including certain file system paths and CMake itself. Other generators will create projects that are agnostic to the target system other than requiring a certain Make (GNU make, NMake ...) or VS version or whatever it is that was generated.

Other project generators also won't bake references to themselves into the projects, because they don't consider themselves build systems and don't expect to run themselves on the build hosts.

generate VS solution/project files

There is no official specification for visual studio files, as they change often. Any attempts at building them without the help of VS tooling is futile as inevitably Microsoft will change them from release to release. As someone who writes build systems for fun, Microsoft tooling is a pain in the ass. Requiring VS tooling to be installed is the sanest way to handle VS project generation.

It is true that there is no official specification for those files (I don't really consider the MSBuild specifications inside the VS installation folder a specification), but they have not changed as much as you make it seem and ever since VS2010 have been based on MSBuild and its rules. Details have changed, though. Prior to VS2010 they were also XML-based, but only .NET projects used something related to MSBuild before VS2010.

There is no logical reason for this

Of course there are. Have you asked the developers of CMake? Or are you assuming?

I have not. I am observing. So what's the logical reason then (according to you)? The other project generators which don't require the target VS or Make or whatever installed are indisputable proof that there is no logical reason for the outcome CMake gives; i.e. that there is no alternative to the way CMake chose to implement it. There certainly is a reason and probably a rationale, but to me it doesn't qualify as logical as it is artificially limiting the utility of CMake.

[GYP, Premake, Waf, etc.]

There are loads of reasons not to use these. Project interoperability is a huge one - wiring up dependencies is a PITA with lesser-capable libraries. Exposing targets for consumption via submodules, for example, is not very ergonomic with simpler build systems.

The fact that you call those build systems tells me enough.

Wiring up projects via CMake isn't necessarily any easier. It's just different and depends to a very very large extent on the quality of the CMakeLists.txt files from others that you get to consume. It can be trivial to incorporate third-party code when everything falls into place, though.

That's how it should be.

You should take that up with Microsoft, then. That seems to be your only real gripe - which has little to do with CMake.

What does the way how CMake devs decided to generate VS solutions/projects to do with Microsoft on the other hand? It has to do everything with CMake, but YMMV.

Ninja

Not a fair comparison. Ninja configurations are meant to be generated, not hand-written. Not sure why you're comparing it to CMake, as CMake uses it exactly how it's intended.

Actually if you had bothered to read my comment closely you would have noticed that I had nothing negative to say about Ninja. I'm aware it expects that those files are generated (yet human and machine readable). But unlike CMake Ninja focuses on one thing and does it well (IMO).

And, sticking to the Unix philosophy of doing one thing but doing that really really well, excel in their niches.

Unix hasn't followed that philosophy since the 80's. Neither have GNU Make, Meson, Bazel, Buck, Premake, SCons, or GYP. Or straight shell scripts, for that matter. The only build system that comes to mind that really follows this is rebuild, and it never took off and died a decade or two ago.

Huh? Or in your words: What does that even mean? 😁

Haven't worked with Bazel and Buck, btw. Not worked in-depth with SCons or Meson, yet, either. So I can't even comment on more than half of your choice of tools here; and won't.

But perhaps you can enlighten me what GNU make or Premake4 or GYP do aside from their stated purpose? Somehow your claim is they violate the Unix philosophy. Conventional shell scripts embody that very philosophy.

Why not go for Meson instead of CMake with the same reasoning?

Because Meson imposes software development philosophies that don't mimic reality and its maintainers have proven themselves to be very dogmatic and uninterested in allowing projects any freedom in how they structure their codebases. They've also demonstrated time and time again a complete lack of understanding of how build systems work, dying on strange hills regarding duplicate symbols and the like and asserting things that simply are not true.

You seem to have missed that this was clearly a rhetorical question which I "asked" in order to show how ridiculous your proposition seemed from my perspective. And yes, in the subsequent sentence I made it abundantly clear that I would not consider this any better an idea than the one of switching to CMake, as opposed to adding it as another option.

I'm all for adding to the current array of options

You don't seem to be.

I am (and there is nothing more than my word that I can offer).

With all due respect, it sound like you either misunderstand build systems, or at least CMake/VS tooling, or you haven't worked with it a whole lot.

That's how your response sounds to me, too. Especially when you frame project generators as build systems - which they aren't. CMake on the other hand is both. And MSBuild (at the heart of VS tooling) is perfectly capable of much more than most people give it credit for. But why bother learning this or that tool in-depth if you can go for the latest fad instead? 😉

I'm perfectly fine with CMake being added and in that sense love the comment by @sjaeckel. Don't want it to replace everything else, though, which your wording ("switch to") implied.

I think the first version of CMake I had contact with was 2.6 or 2.8 and some of my voiced concerns have been addressed more/better than others (e.g. the quality of VS projects has improved as the properties are now encoded in the proper fashion instead of command line arguments in many cases).

But I think having worked with various build systems and the related tools (as needed by my employer and suitable for building the targets) has at least given me one or two thoughts over the last twenty years on how the tools should work to make them sustainable.

Adding Premake is your own opinionated change and isn't going to help a lot of people who would like to incorporate this into their own codebases - they will inevitably have to write their own build configs anyway. At least with a CMake configuration, this library is just one add_subdirectory() away for larger projects that use CMake and avoid "nicheness".

While Premake4 certainly doesn't try to be everything and doesn't try to be a build system either, its output is consistently closer to the projects its target consumers would normally natively generate. The same can be said for GYP (now abandoned to the best of my knowledge) and Waf, in my experience.

Again, the success of that add_subdirectory() depends a lot on the CMakeLists.txt in that directory. It can be a very painless or a very painful process. I've had mixed experiences with this.

@Prince213

Maybe we can remove vs files and instread use cmake to generate them when needed. CMake seems to be trivial to install on windows.

The latest versions of VS come with some CMake version (and also Ninja) preinstalled. I don't recall if you had to select them explicitly to be installed, though. So it would definitely add value for Windows devs using VS.

If you mean the outdated VS solution and project, yep I'm all for removing or updating it. In fact I am actively working on that and therefore won't ...

Actually it does: https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators

CMake indeed doesn't use a syntax that makes everyone happy, but more projects are using it (compared to Premake), and can thus benefits more people.

... discuss the finer points of why I think you haven't closely read my comment. I didn't write CMake doesn't offer VS project generators. Having used them extensively, I know it does. I was arguing that those very generators lacked various qualities and that a Linux build of CMake, for example, lacked the generators altogether (and for no good reason) ... and that the generated projects imposed (IMO undue) limitations on the developers.

@eli-schwartz

But not premake or scons or waf.

The the only point where I disagree (unsurprisingly, I guess 😉) with your remarks. But I'm quite content to agree to disagree.

However, it doesn't matter, since you don't have to put in the work (I am already in the process of doing that). And if you look at my pull request (#525) you can see that the premake4.lua distills the essential differences between the various VS versions quite nicely [1], whereas the makefile.msvc purportedly should work on very early VS versions, but doesn't (I tried). Not even the VS2008 solution included in the project works (but for another reason than the makefile.msvc). I'll try to get it to work not just for the range of VS2003 through 2022 (I haven't tested VS2010 through 2017 as of yet), but also for GNU make. Whether anyone wants to use that option, I don't know. My main focus is on VS projects. But perhaps the project members/maintainers are inclined to offer pre-generated VS projects and solutions if they can (p)re-generate them even from a Linux box running premake4. Either way I prefer an option that follows the single source of truth principle (somewhat related to DRY, I guess 😁).

[1] There is just one ugly aspect and I plan on factoring it out of the premake4.lua if that will be deemed permissible by the project members/maintainers. The Lua functions at the top are helpful to shape the output in a certain way, but they aren't strictly needed for it to function. Putting it into a separate file would seem logical, but on the other hand would clutter the source tree (as a maintainer I would probably have objections right there).

@eli-schwartz
Copy link

I mean, I guess opinions vary on the usefulness of premake. Given the scope of what it tries to do, I'd agree it does a pretty decent job.

However, it's very much a "users would like to directly build libtommath using an alternative build system" situation, and doesn't have the same benefit cmake/meson have in enabling third-party integrations. Different people may or may not care about that fact.

I will absolutely refuse to accept the notion of waf or scons being any good though. :D Waf came from scons, and both differ from build systems such as cmake or meson and generators like premake or GYP in that you actually run scons or ./waf to actually perform compilation. They don't generate Makefiles or ninja files or vcproj solutions or anything. Although they are straight up python, so you can do whatever you want, including some waf 'extras' library that generates a vcproj, supposedly.

The same command that does the build also accepts configuration directives, and of course it must parse the entire buildsystem state before figuring out what to build. For obvious reasons, both have a reputation for being really slow.

And so, yes, waf and scons are absolutely build systems, not generators. Really niche build systems, which in the case of waf are heavily designed to try to get in the way of anyone installing the tool. (Waf expects to be checked into git as ./waf in the repository root, a self-extracting archive, and extracts itself to a temporary working directory. This archive also contains restrictively licensed documentation literally rigged up as a ploy to pick a fight with Debian and force them to stop distributing a package for waf.)

@sjaeckel
Copy link
Member

Thanks @assarbad @eli-schwartz for your statements.

TBH I'm pretty fed up with those build system/generator wars. I don't really have an opinion on any of them. I don't really like the syntax of any of them.

We're going to have cmake as "modern option".

Why? Because someone's already working on it, a lot of people seem to like it and e.g. OpenEmbedded, VCPKG and SPM have direct support for it. Maybe there's also direct support for e.g. Meson, but from what it looks to me, cmake feels most of the time more natural.

But this doesn't mean that we have to stop here! If someone wants to make a PR with support for another build system, go for it! (If you have a mildly good reason! Not just because you can. (I'm looking especially at all the others besides meson ;) ))

It has to be integrated in the current way of how the update of all the other makefiles works (by calling helper.pl -u, also c.f. upcoming PR for cmake based on the add-cmake-support branch). ... and always keep in mind:

The ground truth is the makefile.

I.e. I will not do much maintenance of other build systems besides calling helper.pl -u when necessary.

Regarding premake I like the concept of "install it w/o a lot of other dependencies and generate your projects from it" compared to the way how cmake handles this for e.g. VS. We'll see how well it really works when we integrate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants