Document CMake build system

This commit is contained in:
Dirk Ziegelmeier 2018-10-08 22:17:03 +02:00
parent 65b1a395f4
commit ef5bc352fb
5 changed files with 163 additions and 48 deletions

107
BUILDING Normal file
View File

@ -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.

View File

@ -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)

View File

@ -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})

View File

@ -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})

View File

@ -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.
*/
/**