用Visual Studio 2022创建CMake项目
* CmakeLists.txt
- # CMakeList.txt : Top-level CMake project file, do global configuration
- # and include sub-projects here.
- #
- cmake_minimum_required (VERSION 3.12)
-
- project ("llist")
-
- # Include sub-projects.
- add_subdirectory ("llist")
* llist/CMakeLists.txt
- # CMakeList.txt : CMake project for llist, include source and define
- # project specific logic here.
- #
- cmake_minimum_required (VERSION 3.12)
-
- # Add source to this project's executable.
- add_executable (llist "llist.c" "llist.h")
-
- if (CMAKE_VERSION VERSION_GREATER 3.12)
- set_property(TARGET llist PROPERTY CXX_STANDARD 11)
- endif()
-
- # TODO: Add tests and install targets if needed.
* llist/llist.h
- // llist.h : Include file for standard system include files,
- // or project specific include files.
-
- #pragma once
-
- #ifndef NULL
- #define NULL (void *)0
- #endif
- /*
- * List definitions.
- */
- #define LIST_HEAD(name, type) \
- struct name { \
- struct type *lh_first; /* first element */ \
- }
-
- #define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
- #define LIST_ENTRY(type) \
- struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
- }
-
- /*
- * List functions.
- */
- #define LIST_INIT(head) do { \
- (head)->lh_first = NULL; \
- } while (/*CONSTCOND*/0)
-
- #define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
- } while (/*CONSTCOND*/0)
-
- #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
- } while (/*CONSTCOND*/0)
-
- #define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
- } while (/*CONSTCOND*/0)
-
- #define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
- } while (/*CONSTCOND*/0)
-
- #define LIST_FOREACH(var, head, field) \
- for ((var) = ((head)->lh_first); \
- (var); \
- (var) = ((var)->field.le_next))
-
- /*
- * List access methods.
- */
- #define LIST_EMPTY(head) ((head)->lh_first == NULL)
- #define LIST_FIRST(head) ((head)->lh_first)
- #define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-
- // TODO: Reference additional headers your program requires here.
llist/llist.c
- /* llist.c : Defines the entry point for the application.* /
- /* #include
*/ - #include
- #include
/* malloc, free */ - #include
/* strcpy */ - #include "llist.h"
-
- struct entry {
- char s[256];
- LIST_ENTRY(entry) entries;
- };
- LIST_HEAD(listhead, entry);
-
- int main()
- {
- struct listhead head;
- struct entry* n1, * n2, * np;
-
- /* Initialize the list */
- LIST_INIT(&head);
- /* Insert at the head */
- n1 = malloc(sizeof(struct entry));
- strcpy_s(n1->s, 256, "line#1");
- LIST_INSERT_HEAD(&head, n1, entries);
- /* Insert after */
- n2 = malloc(sizeof(struct entry));
- strcpy_s(n2->s, 256, "line#2");
- LIST_INSERT_AFTER(n1, n2, entries);
-
- struct entry* n3;
- n3 = malloc(sizeof(struct entry));
- strcpy_s(n3->s, 256, "line#3");
- LIST_INSERT_BEFORE(n2, n3, entries);
-
- LIST_FOREACH(np, &head, entries) {
- printf("%s\n", np->s);
- }
- LIST_REMOVE(n2, entries);
- free(n2);
- LIST_FOREACH(np, &head, entries) {
- printf("%s\n", np->s);
- }
- /* Destroy */
- while (LIST_FIRST(&head) != NULL) {
- LIST_REMOVE(LIST_FIRST(&head), entries);
- free(LIST_FIRST(&head));
- }
-
- return 0;
- }
选择最外层的CMakeLists.txt 右键Build
CMakePresets.json
- {
- "version": 3,
- "configurePresets": [
- {
- "name": "windows-base",
- "hidden": true,
- "generator": "Ninja",
- "binaryDir": "${sourceDir}/out/build/${presetName}",
- "installDir": "${sourceDir}/out/install/${presetName}",
- "cacheVariables": {
- "CMAKE_C_COMPILER": "cl.exe",
- "CMAKE_CXX_COMPILER": "cl.exe"
- },
- "condition": {
- "type": "equals",
- "lhs": "${hostSystemName}",
- "rhs": "Windows"
- }
- },
- {
- "name": "x64-debug",
- "displayName": "x64 Debug",
- "inherits": "windows-base",
- "architecture": {
- "value": "x64",
- "strategy": "external"
- },
- "cacheVariables": {
- "CMAKE_BUILD_TYPE": "Debug"
- }
- },
- {
- "name": "x64-release",
- "displayName": "x64 Release",
- "inherits": "x64-debug",
- "cacheVariables": {
- "CMAKE_BUILD_TYPE": "Release"
- }
- },
- {
- "name": "x86-debug",
- "displayName": "x86 Debug",
- "inherits": "windows-base",
- "architecture": {
- "value": "x86",
- "strategy": "external"
- },
- "cacheVariables": {
- "CMAKE_BUILD_TYPE": "Debug"
- }
- },
- {
- "name": "x86-release",
- "displayName": "x86 Release",
- "inherits": "x86-debug",
- "cacheVariables": {
- "CMAKE_BUILD_TYPE": "Release"
- }
- },
- {
- "name": "linux-debug",
- "displayName": "Linux Debug",
- "generator": "Ninja",
- "binaryDir": "${sourceDir}/out/build/${presetName}",
- "installDir": "${sourceDir}/out/install/${presetName}",
- "cacheVariables": {
- "CMAKE_BUILD_TYPE": "Debug"
- },
- "condition": {
- "type": "equals",
- "lhs": "${hostSystemName}",
- "rhs": "Linux"
- },
- "vendor": {
- "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
- "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
- }
- }
- },
- {
- "name": "macos-debug",
- "displayName": "macOS Debug",
- "generator": "Ninja",
- "binaryDir": "${sourceDir}/out/build/${presetName}",
- "installDir": "${sourceDir}/out/install/${presetName}",
- "cacheVariables": {
- "CMAKE_BUILD_TYPE": "Debug"
- },
- "condition": {
- "type": "equals",
- "lhs": "${hostSystemName}",
- "rhs": "Darwin"
- },
- "vendor": {
- "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
- "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
- }
- }
- }
- ]
- }
See also: SysTutorials LIST_INSERT_AFTER (3) - Linux Manuals
Linked Lists in the Linux Kernel - An example in userspace
Doubly linked list