Dirk Ziegelmeier 7 лет назад
Родитель
Сommit
ef5bc352fb

+ 107 - 0
BUILDING

@@ -0,0 +1,107 @@
+Building lwIP
+=============
+
+lwIP uses a CMake based build system.
+
+The CMake files in this project are designed to
+be included into your own CMake files. They are
+mainly variable definitions containing a list of
+source files and predefined static libraries to
+be linked against application code.
+
+1) lwIP sources:
+   src/Filelists.cmake provides file lists containing
+   the lwIP core library.
+   The file also contains two static libraries, lwipcore
+   and lwipallapps, where you can link your app against.
+   This is the file that is useful to all lwIP users.
+
+2) Example applications:
+   contrib/Filelists.cmake provides several file lists
+   containing the example applications.
+   The file also contains several static libraries
+   for these example apps.
+   This file is only useful for you, if you can use one
+   of the examples in your application, which is normally
+   not the case.
+
+3) OS/platform port:
+   Usually the OS port needs to be provided by the user.
+   If a port to Linux, Windows or MacOS is useful for
+   you, you can use
+   contrib/ports/{win32, unix}/Filelists.cmake
+   that contains file lists and libraries for
+   these operating systems.
+
+VARIABLES
+=========
+In all cases, you need to provide two variables.
+
+"LWIP_DIR" pointing to the lwIP directory
+Example:
+set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lwip)
+
+"LWIP_INCLUDE_DIRS" that contains the include base paths
+- for lwIP itself (${LWIP_DIR}/src/include)
+- for lwIP contrib if you use it (${LWIP_CONTRIB_DIR}/)
+- to a directory for an lwIP OS port
+- to a directory containing lwipopts.h
+
+Example:
+set (LWIP_INCLUDE_DIRS
+    "${LWIP_DIR}/src/include"
+    "${LWIP_DIR}/contrib"
+    "${LWIP_DIR}/contrib/ports/unix/port/include"
+    "${LWIP_DIR}/contrib/examples/example_app"
+)
+
+Putting it all together
+=======================
+To get a working application, your CMake system
+needs to provide the variables described above, e.g.
+set (LWIP_DIR <path to lwip sources>)
+set (LWIP_INCLUDE_DIRS
+    "${LWIP_DIR}/src/include"
+    "${LWIP_DIR}/contrib"
+    "<path to my port>/include"
+    "<path to lwipopts.h>"
+)
+
+You may add some defines:
+set (LWIP_DEFINITIONS LWIP_DEBUG=1)
+
+Then include the filelists you need:
+include(${LWIP_DIR}/src/Filelists.cmake)
+include(${LWIP_DIR}/contrib/Filelists.cmake)
+
+Then, declare you executable:
+add_executable(my_app <my source files> <my lwip port files>)
+
+Add lwIP include dirs to your app:
+target_include_directories(my_app PRIVATE ${LWIP_INCLUDE_DIRS})
+
+Link your app against the lwIP libs from the filelists you need:
+target_link_libraries(my_app lwipcontribapps lwipallapps lwipcore)
+
+Working example
+===============
+Working build examples can be found in the
+contrib/ports/{win32, unix}/example_app
+subdirectory.
+To use them, create a build directory and call cmake with
+the lwIP root dir:
+
+- mkdir build
+- cd build
+- cmake <path to lwip dir>
+- cmake --build
+
+The CMakeLists.txt will autoselect the correct port
+for your system.
+
+Makefile based build system
+===========================
+lwIP also maintains file lists for Makefile-based
+build systems. Look for Filelists.mk files
+in the source tree. We try to maintain them,
+but lwIP's mainly focused build system is CMake.

+ 4 - 1
CMakeLists.txt

@@ -9,8 +9,10 @@ set (LWIP_DEFINITIONS LWIP_DEBUG=1)
 
 if (${CMAKE_SYSTEM_NAME} STREQUAL Windows)
   add_subdirectory(${LWIP_DIR}/contrib/ports/win32/example_app)
-else()
+elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
   add_subdirectory(${LWIP_DIR}/contrib/ports/unix/example_app)
+else()
+  message(WARNING "Host ${CMAKE_SYSTEM_NAME} is not supported to build example_app")
 endif()
 
 # Source package generation
@@ -24,5 +26,6 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "lwip-${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MI
 include(CPack)
 
 # Target for package generation
+include(src/Filelists.cmake)
 add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
 add_dependencies(dist lwipdocs)

+ 6 - 6
contrib/ports/unix/example_app/CMakeLists.txt

@@ -2,16 +2,16 @@ include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
 
 set (LWIP_INCLUDE_DIRS
     "${LWIP_DIR}/src/include"
-    "${LWIP_CONTRIB_DIR}/"
-    "${LWIP_CONTRIB_DIR}/ports/unix/port/include"
-    "${LWIP_CONTRIB_DIR}/examples/example_app"
+    "${LWIP_DIR}/contrib/"
+    "${LWIP_DIR}/contrib/ports/unix/port/include"
+    "${LWIP_DIR}/contrib/examples/example_app"
 )
 
 include(${LWIP_DIR}/src/Filelists.cmake)
-include(${LWIP_CONTRIB_DIR}/Filelists.cmake)
-include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
+include(${LWIP_DIR}/contrib/Filelists.cmake)
+include(${LWIP_DIR}/contrib/ports/unix/Filelists.cmake)
 
-add_executable(example_app ${LWIP_CONTRIB_DIR}/examples/example_app/test.c default_netif.c)
+add_executable(example_app ${LWIP_DIR}/contrib/examples/example_app/test.c default_netif.c)
 target_include_directories(example_app PRIVATE ${LWIP_INCLUDE_DIRS})
 target_compile_options(example_app PRIVATE ${LWIP_COMPILER_FLAGS})
 target_compile_definitions(example_app PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})

+ 6 - 6
contrib/ports/win32/example_app/CMakeLists.txt

@@ -2,16 +2,16 @@ include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
 
 set (LWIP_INCLUDE_DIRS
     "${LWIP_DIR}/src/include"
-    "${LWIP_CONTRIB_DIR}/"
-    "${LWIP_CONTRIB_DIR}/ports/win32/include"
-    "${LWIP_CONTRIB_DIR}/examples/example_app"
+    "${LWIP_DIR}/contrib/"
+    "${LWIP_DIR}/contrib/ports/win32/include"
+    "${LWIP_DIR}/contrib/examples/example_app"
 )
 
 include(${LWIP_DIR}/src/Filelists.cmake)
-include(${LWIP_CONTRIB_DIR}/Filelists.cmake)
-include(${LWIP_CONTRIB_DIR}/ports/win32/Filelists.cmake)
+include(${LWIP_DIR}/contrib/Filelists.cmake)
+include(${LWIP_DIR}/contrib/ports/win32/Filelists.cmake)
 
-add_executable(example_app ${LWIP_CONTRIB_DIR}/examples/example_app/test.c default_netif.c)
+add_executable(example_app ${LWIP_DIR}/contrib/examples/example_app/test.c default_netif.c)
 target_include_directories(example_app PRIVATE ${LWIP_INCLUDE_DIRS})
 target_compile_options(example_app PRIVATE ${LWIP_COMPILER_FLAGS})
 target_compile_definitions(example_app PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})

+ 40 - 35
doc/doxygen/main_page.h

@@ -2,14 +2,14 @@
  * @defgroup lwip lwIP
  *
  * @defgroup infrastructure Infrastructure
- * 
+ *
  * @defgroup api APIs
  * lwIP provides three Application Program's Interfaces (APIs) for programs
  * to use for communication with the TCP/IP code:
  * - low-level "core" / "callback" or @ref callbackstyle_api.
  * - higher-level @ref sequential_api.
  * - BSD-style @ref socket.
- * 
+ *
  * The raw TCP/IP interface allows the application program to integrate
  * better with the TCP/IP code. Program execution is event based by
  * having callback functions being called from within the TCP/IP
@@ -17,23 +17,23 @@
  * thread. The sequential API has a much higher overhead and is not very
  * well suited for small systems since it forces a multithreaded paradigm
  * on the application.
- * 
+ *
  * The raw TCP/IP interface is not only faster in terms of code execution
  * time but is also less memory intensive. The drawback is that program
  * development is somewhat harder and application programs written for
  * the raw TCP/IP interface are more difficult to understand. Still, this
  * is the preferred way of writing applications that should be small in
  * code size and memory usage.
- * 
+ *
  * All APIs can be used simultaneously by different application
  * programs. In fact, the sequential API is implemented as an application
  * program using the raw TCP/IP interface.
- * 
+ *
  * Do not confuse the lwIP raw API with raw Ethernet or IP sockets.
  * The former is a way of interfacing the lwIP network stack (including
  * TCP and UDP), the latter refers to processing raw Ethernet or IP data
  * instead of TCP connections or UDP packets.
- * 
+ *
  * Raw API applications may never block since all packet processing
  * (input and output) as well as timer processing (TCP mainly) is done
  * in a single execution context.
@@ -59,7 +59,7 @@
  * receive. This API is also used by the core stack for interaction between
  * the various protocols. It is the only API available when running lwIP
  * without an operating system.
- * 
+ *
  * @defgroup sequential_api Sequential-style APIs
  * @ingroup api
  * Sequential-style APIs, blocking functions. More overhead, but can be called
@@ -70,7 +70,7 @@
  * paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP
  * code and the application program must reside in different execution
  * contexts (threads).
- * 
+ *
  * @defgroup socket Socket API
  * @ingroup api
  * BSD-style socket API.\n
@@ -83,9 +83,9 @@
  * on other platforms (e.g. unix / windows etc.). However, due to limitations
  * in the specification of this API, there might be incompatibilities
  * that require small modifications of existing programs.
- * 
+ *
  * @defgroup netifs NETIFs
- * 
+ *
  * @defgroup apps Applications
  */
 
@@ -112,7 +112,7 @@
  * * Add sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
  *   (for FreeRTOS, mainly)
  * * socket API: support poll(), sendmsg() and recvmsg(); fix problems on close
- * 
+ *
  * Detailed Changelog
  * ------------------
  * @verbinclude "CHANGELOG"
@@ -123,6 +123,11 @@
  * @verbinclude "contrib.txt"
  */
 
+/**
+ * @page cmake CMake build system
+ * @verbinclude "BUILDING"
+ */
+
 /**
  * @page pitfalls Common pitfalls
  *
@@ -131,21 +136,21 @@
  *
  * The most common source of lwIP problems is to have multiple execution contexts
  * inside the lwIP code.
- * 
- * lwIP can be used in two basic modes: @ref lwip_nosys (no OS/RTOS 
+ *
+ * lwIP can be used in two basic modes: @ref lwip_nosys (no OS/RTOS
  * running on target system) or @ref lwip_os (there is an OS running
  * on the target system).
- * 
+ *
  * See also: @ref multithreading (especially the part about @ref LWIP_ASSERT_CORE_LOCKED()!)
  *
  * Mainloop Mode
  * -------------
  * In mainloop mode, only @ref callbackstyle_api can be used.
- * The user has two possibilities to ensure there is only one 
+ * The user has two possibilities to ensure there is only one
  * exection context at a time in lwIP:
  *
  * 1) Deliver RX ethernet packets directly in interrupt context to lwIP
- *    by calling netif->input directly in interrupt. This implies all lwIP 
+ *    by calling netif->input directly in interrupt. This implies all lwIP
  *    callback functions are called in IRQ context, which may cause further
  *    problems in application code: IRQ is blocked for a long time, multiple
  *    execution contexts in application code etc. When the application wants
@@ -171,7 +176,7 @@
  * implemented in tcpip_input().​​
  * Again, ensure lwIP is _NEVER_ called from an interrupt, e.g.
  * some SPI IRQ wants to forward data to udp_send() or tcp_write()!
- * 
+ *
  * 1) tcpip_callback() can be used get called back from TCPIP thread,
  *    it is safe to call any @ref callbackstyle_api from there.
  *
@@ -186,7 +191,7 @@
  *
  * DMA-capable ethernet hardware and zero-copy RX
  * ----------------------------------------------
- * 
+ *
  * lwIP changes the content of RECEIVED pbufs in the TCP code path.
  * This implies one or more cacheline(s) of the RX pbuf become dirty
  * and need to be flushed before the memory is handed over to the
@@ -225,7 +230,7 @@
  * *not* *from* *interrupt* *context*. You can allocate a @ref pbuf in interrupt
  * context and put them into a queue which is processed from mainloop.\n
  * Call sys_check_timeouts() periodically in the mainloop.\n
- * Porting: implement all functions in @ref sys_time, @ref sys_prot and 
+ * Porting: implement all functions in @ref sys_time, @ref sys_prot and
  * @ref compiler_abstraction.\n
  * You can only use @ref callbackstyle_api in this mode.\n
  * Sample code:\n
@@ -265,12 +270,12 @@ Call these functions in the order of appearance:
 
   The init function pointer must point to a initialization function for
   your Ethernet netif interface. The following code illustrates its use.
-  
+
 @code{.c}
   err_t netif_if_init(struct netif *netif)
   {
     u8_t i;
-    
+
     for (i = 0; i < ETHARP_HWADDR_LEN; i++) {
       netif->hwaddr[i] = some_eth_addr[i];
     }
@@ -278,11 +283,11 @@ Call these functions in the order of appearance:
     return ERR_OK;
   }
 @endcode
-  
+
   For Ethernet drivers, the input function pointer must point to the lwIP
   function ethernet_input() declared in "netif/etharp.h". Other drivers
   must use ip_input() declared in "lwip/ip.h".
-  
+
 - netif_set_default(struct netif *netif)
   Registers the default network interface.
 
@@ -317,7 +322,7 @@ Call these functions in the order of appearance:
  * from pbuf- and memory management functions). Application threads using
  * the sequential- or socket API communicate with this main thread through
  * message passing.
- * 
+ *
  * As such, the list of functions that may be called from
  * other threads or an ISR is very limited! Only functions
  * from these API header files are thread-safe:
@@ -328,43 +333,43 @@ Call these functions in the order of appearance:
  * - pppapi.h
  * - sockets.h
  * - sys.h
- * 
+ *
  * Additionaly, memory (de-)allocation functions may be
  * called from multiple threads (not ISR!) with NO_SYS=0
  * since they are protected by @ref SYS_LIGHTWEIGHT_PROT and/or
  * semaphores.
- * 
+ *
  * Netconn or Socket API functions are thread safe against the
  * core thread but they are not reentrant at the control block
  * granularity level. That is, a UDP or TCP control block must
  * not be shared among multiple threads without proper locking.
- * 
+ *
  * If @ref SYS_LIGHTWEIGHT_PROT is set to 1 and
  * @ref LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1,
  * pbuf_free() may also be called from another thread or
  * an ISR (since only then, mem_free - for PBUF_RAM - may
  * be called from an ISR: otherwise, the HEAP is only
  * protected by semaphores).
- * 
+ *
  * How to get threading done right
  * -------------------------------
- * 
+ *
  * It is strongly recommended to implement the LWIP_ASSERT_CORE_LOCKED()
  * macro in an application that uses multithreading. lwIP code has
  * several places where a check for a correct thread context is
  * implemented which greatly helps the user to get threading done right.
- * See the example sys_arch.c files in unix and Win32 port 
+ * See the example sys_arch.c files in unix and Win32 port
  * in the lwIP/contrib subdirectory.
- * 
- * In short: Copy the functions sys_mark_tcpip_thread() and 
+ *
+ * In short: Copy the functions sys_mark_tcpip_thread() and
  * sys_check_core_locking() to your port and modify them to work with your OS.
  * Then let @ref LWIP_ASSERT_CORE_LOCKED() and @ref LWIP_MARK_TCPIP_THREAD()
  * point to these functions.
- * 
+ *
  * If you use @ref LWIP_TCPIP_CORE_LOCKING, you also need to copy and adapt
  * the functions sys_lock_tcpip_core() and sys_unlock_tcpip_core().
- * Let @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE() point 
- * to these functions. 
+ * Let @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE() point
+ * to these functions.
  */
 
 /**