{"id":15651528,"url":"https://github.com/friendlyanon/cxx-static-shared-example","last_synced_at":"2026-01-08T05:04:35.102Z","repository":{"id":39776410,"uuid":"336080922","full_name":"friendlyanon/cxx-static-shared-example","owner":"friendlyanon","description":null,"archived":false,"fork":false,"pushed_at":"2021-10-07T14:38:35.000Z","size":46,"stargazers_count":37,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T08:44:58.502Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/friendlyanon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-04T20:59:19.000Z","updated_at":"2025-01-27T03:06:37.000Z","dependencies_parsed_at":"2022-08-09T15:25:44.699Z","dependency_job_id":null,"html_url":"https://github.com/friendlyanon/cxx-static-shared-example","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/friendlyanon%2Fcxx-static-shared-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendlyanon%2Fcxx-static-shared-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendlyanon%2Fcxx-static-shared-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/friendlyanon%2Fcxx-static-shared-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/friendlyanon","download_url":"https://codeload.github.com/friendlyanon/cxx-static-shared-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246262491,"owners_count":20749171,"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-03T12:38:53.973Z","updated_at":"2026-01-08T05:04:30.083Z","avatar_url":"https://github.com/friendlyanon.png","language":"CMake","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CMake Example: support building as either shared or static\n\n![Continuous Integration](https://github.com/friendlyanon/cxx-static-shared-example/workflows/Continuous%20Integration/badge.svg)\n\nThis example project shows you how to build a C++ project that can be built as\nstatic or shared, by using the corresponding CMake functionality.\n\nThe [`master`](https://github.com/friendlyanon/cxx-static-shared-example)\nbranch uses CMake 3.14 as minimum. For older minimum requirements, see the\n[`cmake-3.12`](https://github.com/friendlyanon/cxx-static-shared-example/tree/cmake-3.12)\nand\n[`cmake-3.8`](https://github.com/friendlyanon/cxx-static-shared-example/tree/cmake-3.8)\nbranches. Only the `install(TARGETS)` command is different in older versions of\nCMake, but for the purpose of being a proper educational example they are also\nincluded.\n\nAnything older than CMake 3.8 is not practical to use.\n\n# How?\n\nBelow are what a developer has to take into account to successfully aid users\nof the library in making the decision on how to build the library. Users in\nthis case can be other developers depending on the library or package\nmaintainers who distribute your library.\n\n## `BUILD_SHARED_LIBS`\n\nCMake provides a way to let the user choose the type of libraries to build if\nthose do not specify their type explicitly.\n[`add_library`](https://cmake.org/cmake/help/latest/command/add_library.html#normal-libraries)\nwill check for the value of `BUILD_SHARED_LIBS` when called without an type and\nhonor its value.\n\nThis variable should never be set anywhere in your `CMakeLists.txt` files and\nthere should be no \"special\" ways to achieve the same thing CMake provides by\ndefault.  \nMaking package maintainers' life more difficult for no reason benefits noone.\n\n```cmake\nadd_library(your_target source/main.cpp)\n```\n\n## SONAME and REAL LIBRARY\n\nOn Linux platforms, a shared library consists of a single REAL LIBRARY and\nsymlinks to it, one of which is the SONAME. The REAL LIBRARY has a filename\nsimilar to `libyour_target.so.1.2.3`, where the full version number is embedded\nas a suffix. This does not affect runtime loading, the REAL LIBRARY is for\nhumans.\n\nThe SONAME on the other hand is what the runtime loader will go looking for.\nThe corresponding SONAME of the above shared library would be\n`libyour_target.so.1`, where `1` is the library's SOVERSION. Different\nlibraries may choose different versioning strategies and it doesn't necessarily\nhave to be related to the suffix in the REAL LIBRARY name.  \nIn this example, the major version of the project will be assumed to mean\nSOVERSION as well.\n\n```cmake\nset_target_properties(\n    your_target PROPERTIES\n    VERSION \"${PROJECT_VERSION}\"\n    SOVERSION \"${PROJECT_VERSION_MAJOR}\"\n)\n```\n\n## Visibility\n\nOn the Windows platform, symbols must be explicitly exported from a DLL and\nmust be marked as DLL imports in the header files in the consuming end.  \nThis is the desired behavior on all platforms, however the defaults are wrong\non other platforms like Linux.\n\nTo hide symbols on platforms, where the default is not hiding symbols, you must\nadd some properties to your (possibly) shared targets:\n\n```cmake\nset_target_properties(\n    your_target PROPERTIES\n    CXX_VISIBILITY_PRESET hidden\n    VISIBILITY_INLINES_HIDDEN YES\n)\n```\n\n## Export macros\n\nCMake supports generating cross-platform export macros via the\n[`GenerateExportHeader`](https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html)\nmodule. A library must annotate every symbol that the user is intended to or\nmight be able to observe. Additionally, when the library is being built as a\nstatic library, then these macros should expand to nothing. This can be\nachieved by conditionally setting the `YOUR_TARGET_STATIC_DEFINE` definition.\n\n```cmake\ninclude(GenerateExportHeader)\n\ngenerate_export_header(\n    your_target\n    EXPORT_FILE_NAME include/your_project/your_target_export.h\n)\n\nif(NOT BUILD_SHARED_LIBS)\n  target_compile_definitions(your_target PUBLIC YOUR_TARGET_STATIC_DEFINE)\nendif()\n\ntarget_include_directories(\n    your_target ${your_project_warning_guard}\n    PUBLIC\n    \"$\u003cBUILD_INTERFACE:${PROJECT_BINARY_DIR}/include\u003e\"\n)\n```\n\n```cpp\n#include \u003cyour_project/your_target_export.h\u003e\n\nclass YOUR_TARGET_EXPORT your_class {};\n```\n\n## NAME LINK\n\nOn Linux, besides the SONAME, there is another symlink pointing to the REAL\nLIBRARY, which is the NAME LINK. While the SONAME and REAL LIBRARY are part of\nthe runtime component, this symlink is part of the development component of a\nlibrary, as it is used at build time for linking by dependent projects.\n\nDepending on your CMake version, this is installed in different ways. Here it\nis for CMake 3.14+ using the default install locations from\n[`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html):\n\n```cmake\ninclude(GNUInstallDirs)\n\ninstall(\n    TARGETS your_target\n    RUNTIME #\n    COMPONENT your_project_Runtime\n    LIBRARY #\n    COMPONENT your_project_Runtime\n    NAMELINK_COMPONENT your_project_Development\n    ARCHIVE #\n    COMPONENT your_project_Development\n)\n```\n\n# The big picture\n\nThe above points were focusing on single aspects that must be taken into\naccount.  \nTo see the big picture and how the pieces fit together, please take a look at\nthe [`CMakeLists.txt`](CMakeLists.txt) file.\n\n# References\n\n* [Deep CMake for Library Authors](https://www.youtube.com/watch?v=m0DwB4OvDXk)\n  by Craig Scott - CppCon 2019\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffriendlyanon%2Fcxx-static-shared-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffriendlyanon%2Fcxx-static-shared-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffriendlyanon%2Fcxx-static-shared-example/lists"}