{"id":17794366,"url":"https://github.com/pyk/cmake-tutorial","last_synced_at":"2025-04-09T09:11:00.440Z","repository":{"id":29461094,"uuid":"121752682","full_name":"pyk/cmake-tutorial","owner":"pyk","description":"A Brief Beginner’s Guide to CMake or How to quickly get up and running with CMake","archived":false,"fork":false,"pushed_at":"2024-01-23T10:12:34.000Z","size":1073,"stargazers_count":225,"open_issues_count":2,"forks_count":34,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-02T07:09:46.235Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pyk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-16T13:16:27.000Z","updated_at":"2025-03-27T12:41:45.000Z","dependencies_parsed_at":"2024-10-27T11:16:05.090Z","dependency_job_id":"a18945bc-8457-401d-9744-544dcf489718","html_url":"https://github.com/pyk/cmake-tutorial","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyk%2Fcmake-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyk%2Fcmake-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyk%2Fcmake-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pyk%2Fcmake-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pyk","download_url":"https://codeload.github.com/pyk/cmake-tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248008630,"owners_count":21032556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-27T11:16:01.215Z","updated_at":"2025-04-09T09:11:00.417Z","avatar_url":"https://github.com/pyk.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CMake Tutorial\n\nThis tutorial cover the following:\n\n1. Build the project using simple `c++(1)` and `make(1)`.\n2. Build the project using `cmake(1)`.\n3. Build the project using `cmake(1)` with third party library.\n\nIn this tutorial we will use the following project structure:\n\n```\ncmake-tutorial/\n├── CMakeLists.txt\n├── README.md\n├── src\n│   ├── main.cc\n│   ├── math.cc\n│   └── math.h\n└── test\n    └── math_test.cc\n```\n\nDirectory structure:\n\n- `src` : Directory for source code.\n- `test` : Directory for test.\n\n`src/main.cc` is our main executable and `src/math.{cc,h}` is an internal library that used by `src/main.cc`.\n\nWe will start from the basic on how to build the project using `c++(1)` only\nand a simple `Makefile`. Then we define the build in `CMakeLists.txt` and\nusing `cmake(1)` to generate complex `Makefile` for us.\n\n\n## Install CMake\n\nFirst of all, you need to install `cmake`. \n\nOn Ubuntu:\n\n```\nsudo apt-get install cmake\n```\n\nOn macOS:\n\n```\nbrew install cmake\n```\n\nMake sure the `cmake` is installed correctly:\n\n```\n% cmake --version\ncmake version 3.10.2\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n```\n\n## Compiling \u0026 Linking\n\nWe can build this project using the following command: \n\n```\nc++ src/main.cc src/math.cc -o cmake-tutorial\n```\n\nOr we can do the compile and linking on the separate steps\n\n```\nc++ -c src/math.cc -o math.o \nc++ src/main.cc math.o -o cmake-tutorial\n```\n\n## Using Makefile\n\nWe can automate the step to compile and link above using `Makefile`.\nFirst we need to create new `Makefile` in the root directory with the following content:\n\n```makefile\n# Add definition to generate math.o object file\nmath.o: src/math.cc src/math.h\n    c++ -c src/math.cc -o math.o\n\n# Add definition to generate cmake-tutorial binary\ncmake-tutorial: math.o\n    c++ src/main.cc math.o -o cmake-tutorial\n```\n\nNow we can run:\n\n```\nmake cmake-tutorial\n```\n\nto build `cmake-tutorial` binary. If there are no changes in `src/{main,math}.cc` and `src/math.h`,\nthe subsequent command will do nothing:\n\n```\n% make cmake-tutorial\nmake: Nothing to be done for `cmake-tutorial'.\n```\n\nthis is useful when working on larger project, we only compile the object that changes.\n\n## Using CMake\n\nNow we know how to perform compiling and linking using the `C++` and `make` command.\nNow we can use `cmake` to do all of this for us.\n\nCreate new `CMakeLists.txt` with the following content:\n\n```cmake\ncmake_minimum_required (VERSION 3.10)\n\n# Define the project\nproject(cmake-tutorial)\n\n# Add definition for math library\nadd_library(math src/math.cc)\n\n# Add definition for the cmake-tutorial binary\nadd_executable(cmake-tutorial src/main.cc)\ntarget_link_libraries(cmake-tutorial math)\n```\n\nWe can generate the `Makefile` based on the definition above using the following command:\n\n```\ncmake .\n```\n\nOr create a `build` directory to store the generated files by CMake:\n\n```\nmkdir build\ncd build/\ncmake ..\n```\n\nNow we can run `make cmake-tutorial` to build the binary.\n\n```\n% make cmake-tutorial\nScanning dependencies of target math\n[ 25%] Building CXX object CMakeFiles/math.dir/src/math.cc.o\n[ 50%] Linking CXX static library libmath.a\n[ 50%] Built target math\nScanning dependencies of target cmake-tutorial\n[ 75%] Building CXX object CMakeFiles/cmake-tutorial.dir/src/main.cc.o\n[100%] Linking CXX executable cmake-tutorial\n[100%] Built target cmake-tutorial\n```\n\nOr we can use the CMake directly via:\n\n```\ncmake --build . --target cmake-tutorial\n```\n\n## Using CMake with 3rd-party library\n\nSuppose that we want to write a unit test for `math::add(a, b)`.\nWe will use a [googletest](https://github.com/google/googletest) library to create and run the unit test.\n\nAdd the following definition to `CMakeLists.txt`:\n\n```cmake\n# Third-party library\ninclude(ExternalProject)\nExternalProject_Add(googletest\n    PREFIX \"${CMAKE_BINARY_DIR}/lib\"\n    GIT_REPOSITORY \"https://github.com/google/googletest.git\"\n    GIT_TAG \"main\"\n    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/lib/installed\n)\n# Prevent build on all targets build\nset_target_properties(googletest PROPERTIES EXCLUDE_FROM_ALL TRUE)\n\n# Define ${CMAKE_INSTALL_...} variables\ninclude(GNUInstallDirs)\n\n# Specify where third-party libraries are located\nlink_directories(${CMAKE_BINARY_DIR}/lib/installed/${CMAKE_INSTALL_LIBDIR})\ninclude_directories(${CMAKE_BINARY_DIR}/lib/installed/${CMAKE_INSTALL_INCLUDEDIR})\n\n# This is required for googletest\nfind_package(Threads REQUIRED)\n\n# Test\nadd_executable(math_test test/math_test.cc)\ntarget_link_libraries(math_test math gtest Threads::Threads)\n# Make sure third-party is built before executable\nadd_dependencies(math_test googletest)\nset_target_properties(math_test PROPERTIES EXCLUDE_FROM_ALL TRUE)\n```\n\nRe-generate the build files using the following command:\n\n```\ncd build/\ncmake ..\n```\n\nBuild the unit test:\n\n```\ncmake --build . --target math_test\n```\n\nRun the test:\n\n```\n% ./math_test \n[==========] Running 6 tests from 3 test cases.\n[----------] Global test environment set-up.\n[----------] 2 tests from MathAddTest\n[ RUN      ] MathAddTest.PositiveNum\n[       OK ] MathAddTest.PositiveNum (0 ms)\n[ RUN      ] MathAddTest.ZeroB\n[       OK ] MathAddTest.ZeroB (0 ms)\n[----------] 2 tests from MathAddTest (0 ms total)\n\n[----------] 2 tests from MathSubTest\n[ RUN      ] MathSubTest.PositiveNum\n[       OK ] MathSubTest.PositiveNum (0 ms)\n[ RUN      ] MathSubTest.ZeroB\n[       OK ] MathSubTest.ZeroB (0 ms)\n[----------] 2 tests from MathSubTest (0 ms total)\n\n[----------] 2 tests from MathMulTest\n[ RUN      ] MathMulTest.PositiveNum\n[       OK ] MathMulTest.PositiveNum (0 ms)\n[ RUN      ] MathMulTest.ZeroB\n[       OK ] MathMulTest.ZeroB (0 ms)\n[----------] 2 tests from MathMulTest (0 ms total)\n\n[----------] Global test environment tear-down\n[==========] 6 tests from 3 test cases ran. (0 ms total)\n[  PASSED  ] 6 tests.\n```\n\nDone.\n\n\n### IDE Support\n\nIf you are using `CLion`, the google test will automatically detected.\n\n![CLion](https://s9.postimg.org/ugqkdw6nh/Screen_Shot_2018-02-16_at_21.03.10.png)\n\nVisual studio also support cmake\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyk%2Fcmake-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpyk%2Fcmake-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpyk%2Fcmake-tutorial/lists"}