Skip to content

Adds CMake build support#155

Open
sardylan wants to merge 1 commit into
LX3JL:masterfrom
sardylan:master
Open

Adds CMake build support#155
sardylan wants to merge 1 commit into
LX3JL:masterfrom
sardylan:master

Conversation

@sardylan

@sardylan sardylan commented Mar 1, 2020

Copy link
Copy Markdown

This commit will add CMake build system support, useful for building and editing project in JetBrains CLion.
It also adds required entries in gitignore.

@yo2loj

yo2loj commented Mar 1, 2020

Copy link
Copy Markdown
Contributor

Ambed has a single makefile, no variants, no shared code, sits in a single folder and compiles flawless doing a simple make. Using CMake adds an additional step and an additional tool to install, which in the end comes down to the same make to be used.
What gets improved by using cmake in this project, other than the ability to use a specific development environment, which most of the users don't use, and the need to maintain additional files?

@sardylan

sardylan commented Mar 1, 2020

Copy link
Copy Markdown
Author

I agree with you that maintaining two different build systems could be a pain and requires more effort to keep them aligned, but using CMake could be very useful if you want to have a standard build, an automated install system, or if you want to package the software as a DEB or an RPM.
It's also useful if you want to install your software on a custom directory, or if you want to link with libftdi2xx installed in custom position, as I do on my servers using /opt for custom added stuffs.
CMake is now, more or less, one of the main build tool used in C/C++ development that works in different platforms and is already available on every Linux distribution.

I also noticed that all the configuration params are hardcoded on main.h, especially for xlxd. Modifying them (to have working files in a specific directory, or to let daemons easily run on non-root users) it's a problem if you want to keep the source code aligned with git repository. Some params could be moved on a dedicated header file produced by cmake configuration (even better in a dedicated config file read in runtime).

About CLion, it requires CMake on project for importing, analyzing source code and other stuffs, but it's just my favorite IDE for C/C++, absolutely not a requirement for the project.

@sardylan

sardylan commented Mar 1, 2020

Copy link
Copy Markdown
Author

Sorry, I wrongly pushed two more commits on my master branch.
Pull request is referred only to commit 543ef65

@F4FXL

F4FXL commented Mar 2, 2020

Copy link
Copy Markdown
Contributor

Sorry, I wrongly pushed two more commits on my master branch.
Pull request is referred only to commit 543ef65

It is good practice to do work in progress on a different branch and to pull only finished stuff into master. ;)

@F4FXL

F4FXL commented Mar 2, 2020

Copy link
Copy Markdown
Contributor

The current Makefile had the beauty to automatically include new source files in the build. It looks to me that now we would have to update CMakeLists.txt. Isn't there a way to automate this?

@cyanide-burnout

Copy link
Copy Markdown

... and technically CMake works on top of Makefile... )))

@sardylan

sardylan commented Mar 2, 2020

Copy link
Copy Markdown
Author

The current Makefile had the beauty to automatically include new source files in the build. It looks to me that now we would have to update CMakeLists.txt. Isn't there a way to automate this?

Yes. It's possible to set a variable with GLOB and include all *.cpp and *.h files, and it works, but it's considered a bad way to use cmake, because generated makefiles still contains an explicit list of source files to build.
Altought cmake works if you build code inside source directory, is designed to build outside the main project folder. In this way you can keep a good separation between pure source code (under versioning) and build environment, with all .o and executable files.
In case of new source files, if you use glob, build system will not be aware of new added files, and you may have to re-run cmake from scratch.
It's considered a bad practice, especially for big projects in which you have the possibility to "recycle" object files that are not changed in commits.

It's also discouraged in the official documentation:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. The CONFIGURE_DEPENDS flag may not work reliably on all generators, or if a new generator is added in the future that cannot support it, projects using it will be stuck. Even if CONFIGURE_DEPENDS works reliably, there is still a cost to perform the check on every rebuild.

I still prefer explicit file list in CMakeLists, fut for a small project like this, I think that It's can be considered a solution.

@F4FXL

F4FXL commented Mar 5, 2020

Copy link
Copy Markdown
Contributor

The current Makefile had the beauty to automatically include new source files in the build. It looks to me that now we would have to update CMakeLists.txt. Isn't there a way to automate this?

Yes. It's possible to set a variable with GLOB and include all *.cpp and *.h files, and it works, but it's considered a bad way to use cmake, because generated makefiles still contains an explicit list of source files to build.
Altought cmake works if you build code inside source directory, is designed to build outside the main project folder. In this way you can keep a good separation between pure source code (under versioning) and build environment, with all .o and executable files.
In case of new source files, if you use glob, build system will not be aware of new added files, and you may have to re-run cmake from scratch.
It's considered a bad practice, especially for big projects in which you have the possibility to "recycle" object files that are not changed in commits.

It's also discouraged in the official documentation:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. The CONFIGURE_DEPENDS flag may not work reliably on all generators, or if a new generator is added in the future that cannot support it, projects using it will be stuck. Even if CONFIGURE_DEPENDS works reliably, there is still a cost to perform the check on every rebuild.

I still prefer explicit file list in CMakeLists, fut for a small project like this, I think that It's can be considered a solution.

Thank you for taking time to explain, I am a noob concerning CMake...
So what would the steps be when adding a new could file ? I remember once ircddbgateway switched to auomake/autoconf crap and it was a nightmare when adding new files.

@sardylan

sardylan commented Mar 5, 2020

Copy link
Copy Markdown
Author

So what would the steps be when adding a new could file ? I remember once ircddbgateway switched to auomake/autoconf crap and it was a nightmare when adding new files.

Adding a new file in CMake consists on just adding the filename in related CMakeLists.txt, no more steps.

This is an example:

Original CMakeLists.txt:

add_executable(myapp
        config.hpp
        main.cpp main.hpp
        utilities.cpp utilities.hpp)

target_link_libraries(myapp
        LINK_PUBLIC
        Threads::Threads)

target_compile_options(myapp
        PRIVATE
        -Wall)

You want to add a class named SocketTool, so you have to:

  • create both files socket_tool.cpp and socket_tool.hpp
  • just add them in CMakeLists.txt, like this:
add_executable(myapp
        config.hpp
        main.cpp main.hpp
        utilities.cpp utilities.hpp
        socket_tool.cpp socket_tool.hpp)

target_link_libraries(myapp
        LINK_PUBLIC
        Threads::Threads)

target_compile_options(myapp
        PRIVATE
        -Wall)

File order is not important, I just prefer to put them in different lines, one for each couple of .cpp and .hpp, and to keep stand-alone files in single line (like config.hpp).

Files can be also added if using a variable (discouraged way to use cmake):

set(MYAPP_SOURCES
        main.cpp
        utilities.cpp
        socket_tool.cpp)

set(MYAPP_HEADERS
        config.hpp
        main.hpp
        utilities.hpp
        socket_tool.hpp)

add_executable(myapp
        ${MYAPP_SOURCES}
        ${MYAPP_HEADERS})

target_link_libraries(myapp
        LINK_PUBLIC
        Threads::Threads)

target_compile_options(myapp
        PRIVATE
        -Wall)

As last example, GLOBs can be used to avoid modifying CMake each time a new class is created:

file(GLOB MYAPP_SOURCES *.cpp)
file(GLOB MYAPP_HEADERS *.hpp)

add_executable(myapp
        ${MYAPP_SOURCES}
        ${MYAPP_HEADERS})

target_link_libraries(myapp
        LINK_PUBLIC
        Threads::Threads)

target_compile_options(myapp
        PRIVATE
        -Wall)

Last one is not recommended: https://cmake.org/cmake/help/v3.17/command/file.html?highlight=glob#filesystem.

@cyanide-burnout

cyanide-burnout commented Aug 2, 2020

Copy link
Copy Markdown

Adding a new file in CMake consists on just adding the filename in related CMakeLists.txt, no more steps.

Same way possible in Makefile :) You just need to be able to cook 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 this pull request may close these issues.

4 participants