OutpostUniverse / OP2Utility

C++ library for working with Outpost 2 related files and tasks.
MIT License
4 stars 0 forks source link

Switch to a platform agnostic build generation tool #88

Closed Brett208 closed 5 years ago

Brett208 commented 6 years ago

Ideally, we would like to be able to make project level changes without having to update multiple project/solution files. IE adding a file to the source code or changing a compiler setting should not require updating both a Visual Studio project file and a MakeFile.

Brett208 commented 6 years ago

I'd like to look at cMake to accomplish this.

Since OP2Utility is a library project, it will require updating both OP2MapImager and OP2Archive to use cMake as well. We should decide on some sort of roadmap to accomplish this. Using OP2Archive is a great way to test OP2Utility's Volume and CLM file support and using OP2MapImager is a great way to test reading a map file. I think getting these compiling on Linux would allow Linux developers an easier path for testing changes to OP2Utility.

OP2Archive will probably be easier to build on Linux than OP2MapImager as it will not require integrating the FreeImage library.

I'd like to restructure the code when compiling it on cMake to consider platform specific build project files as generated by the repository instead of part of the repository. This probably means moving the source code into its own directory and leaving the cMake build file, license file, readme, and gitignore in the root directory.

A proposed rough order of things that must be accomplished:

Open to comments, changes, and suggestions... -Brett

DanRStevens commented 6 years ago

One quick comment is that it's currently a one-way problem. If a file was added or removed from Linux, the Visual Studio project file would need to be updated, but that's not an issue the other way around. The Linux makefile doesn't currently reference any specific source files. Hence it doesn't need to be updated if a file is added or removed in the Visual Studio project file. The makefile just uses find to scan for all '.cpp' files in some subtree of the filesystem.

Granted, when you named a branch "Something something involving SomeFile.cpp", it fooled my makefile into trying to compile the branch reference from the .git folder. The branch reference filename is just the exact title of the branch. I added a temporary exclude for the .git folder while that branch was open.

I definitely approve of the idea to move all source files into a subfolder. At the very least, that would allow the find command to be a little more specific about which subtree it scans, and prevent such issues in the future.


There are a few articles online that suggest project folder layouts for C++ projects. Maybe we should reference a few here. I've noticed "src" is a pretty common source folder name, as is "lib" for library code. Both seem excessively abbreviated though, so I'm not if we want to stick that closely to convention. For reference, there is a StackOverflow question on what's a good directory structure for larger C projects using makefile.


As for OP2Archive and OP2MapImager, I think the main Windows dependency was OP2Utility. A quick grep shows the only references to "windows.h" are in the OP2Utility folder. With OP2Utility compiling on Linux, the other projects should be able to compile as well.

I still need to work on linking though. Now that all source files for OP2Utility compile on Linux, I've gotten to the stage where I see linker errors. I need to adjust settings to try and link things into a library rather than an executable file. Should be a simple trivial thing, I just don't know the right flags off the top of my head.


Your overall plan sounds good. I would most appreciate a folder structure change as that can make compiling more robust. The rest of the CMake changes I feel a little apprehensive about, largely because I don't know CMake. This may be a good way to force me to learn though.

DanRStevens commented 6 years ago

I came across this article: A simple C++ project structure

Notably, the "lib" folder is used for 3rd party libraries used by the project. The "src" folder is used for actual project files.

Brett208 commented 6 years ago

Thanks for the links and thought on the project organization. What do you think about the organization below? The platform specific code (makefile, .obj, .exe, etc) would be produced in a folder that the developer would chose of their own accord. I will probably go with VisualStudio for the Windows work.

I like the Submodules directory for including other git projects as it matches git's terminology. It also makes sense when compared to the .gitmodules file required to hook in submodules in git.

We will have to figure out what to do with FreeImage in OP2MapImager at some point though. I guess we could place it in submodules, although it is a .lib and .h file and not an actual sourcecode repository.

DanRStevens commented 6 years ago

I still don't have a good sense on this one. I suppose we'll just have to try something before we have the needed experience with this.

After doing a bit more reading, I think I'm leaning a bit more towards names I'm seeing repeatedly, such as:

.git/
include/
src/
tests/
vendor/

I've seen a vendor/ for 3rd party libraries, which might be relevant for FreeImage.

Most library projects split the public import headers from the rest of the source into an include/ folder. This makes binary packaging and distribution easier. I believe this relates to how the FreeImage package is structured.

I've seen more examples were Git submodules are placed directly in the root of a parent project than within any kind of submodules folder. I'm not sure why. I think I kind of like the additional folder for organization.

I've seen mention of putting possibly multiple CMakeLists.txt in subfolders, though I didn't quite follow why. Seems like a single root folder item to me.

The other root folder files make sense to me.

Brett208 commented 6 years ago

In regards to CMakeLists.txt in subfolders, I think older implementations really required this but perhaps isn't required anymore.

I can live with a vendor folder in OP2MapImager for FreeImage.

I saw some arguments online about how to handle header files in library functions. Some people liked separate directories for .cpp and .h. Some people preferred the directories together and then just pull the header files later for distribution using some sort of filter.

I will say working on the source code to me is a lot easier if the header and .cpp files are in the same place. I am constantly referencing both and if they are in separate places, I have to flip back and forth. If they are in the same directory, it is easier to open/reivew them both when say changing a function prototype or something. VS2017 defaults to creating a filter that separates .cpp and .h into separate virtual directories within the IDE. It really annoys me and I eventually remove the filters so they sit next to each other.

I don't actually have a plan on how to distribute OP2 Utility right now, nor do I have any experience distributing a C++ library outside of OP2Archive and OP2MapImager. Perhaps right now we should just place it all in SourceCode/ and then later we can open a new issue and figure out what makes sense for distribution. This way the source code is out of the root directory for trying out CMake or other build systems. I have no problem making another move later on.

-Brett

DanRStevens commented 6 years ago

Good point about the source being easier to work on when headers and sources are in the same folder. I'd also like to add that we're not really at a point where distribution is a concern. The only real distribution we have here is through Git submodules, which hardly counts as a proper distribution system. We can deal with that problem later.

We've only got one open branch right now, and it's ready for merge. I'd say merge the open branch and jump right on moving things.

ldicker83 commented 6 years ago

The proposed directory structure is acceptable and almost expected. Any time I download the source tree for a widely used library (such as SFML, SDL, PhysFS, GLEW, etc.) they all follow the same format -- src/ and include/. NAS2D follows the same structure -- as a developer primarily in C and C++ this is basically what I've come to expect for any project.

DanRStevens commented 6 years ago

In regards to release packages, I wanted to leave a link to an article I just read on how to Automate GitHub Releases with CircleCI.

In particular, they listed a number of tools that can be used to automatically upload a release to GitHub after a build has completed: curl, github-release, gothub, ghr

The article used the last one in the example. The tool's page has a nice little gif video demo showing it being used. It looks to be cross platform.

DanRStevens commented 5 years ago

Hmm, perhaps we should close this.