1#
2# Copyright 2018, Data61
3# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4# ABN 41 687 119 230.
5#
6# This software may be distributed and modified according to the terms of
7# the BSD 2-Clause license. Note that NO WARRANTY is provided.
8# See "LICENSE_BSD2.txt" for details.
9#
10# @TAG(DATA61_BSD)
11#
12
13cmake_minimum_required(VERSION 3.7.2)
14project(libpicotcp NONE)
15
16include(external-project-helpers)
17
18set(configure_string "")
19
20config_option(LibPicotcp LIB_PICOTCP "Build libpicotcp" DEFAULT OFF)
21config_option(
22    LibPicotcpBsd
23    LIB_PICOTCP_BSD
24    "Build libpicotcp with bsd socket support"
25    DEFAULT
26    OFF
27    DEPENDS
28    LibPicotcp
29)
30mark_as_advanced(LibPicotcp LibPicotcpBsd)
31add_config_library(picotcp "${configure_string}")
32
33if(LibPicotcp)
34    # find pico tcp location
35    find_file(PICOTCP_PATH picotcp PATHS ${CMAKE_SOURCE_DIR}/projects CMAKE_FIND_ROOT_PATH_BOTH)
36    mark_as_advanced(FORCE PICOTCP_PATH)
37    if("${PICOTCP_PATH}" STREQUAL "PICOTCP_PATH-NOTFOUND")
38        message(
39            FATAL_ERROR "Failed to find picotcp. Consider cmake -DPICOTCP_PATH=/path/to/picotcp"
40        )
41    endif()
42
43    # extract compiler args from cmake
44    get_property(compile_options DIRECTORY PROPERTY COMPILE_OPTIONS)
45    separate_arguments(cmake_c_flags_sep NATIVE_COMMAND "${CMAKE_C_FLAGS}")
46    list(APPEND compile_options "${cmake_c_flags_sep}")
47
48    # add the location of muslc headers to the cflags
49    string(
50        APPEND compile_options
51        " -I$<JOIN:$<TARGET_PROPERTY:muslc,INTERFACE_INCLUDE_DIRECTORIES>, -I>"
52    )
53
54    if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
55        list(APPEND compile_options "${CMAKE_C_COMPILE_OPTIONS_TARGET}${CMAKE_C_COMPILER_TARGET}")
56        set(C_COMPILER clang)
57    else()
58        set(C_COMPILER ${CROSS_COMPILER_PREFIX}gcc)
59    endif()
60
61    if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
62        set(perf_flags "\"PERF=1\" \"DEBUG=0\"")
63    endif()
64    # generate a build.sh script to avoid nasty escape issues, we then invoke this in ExternalProject_Add
65    file(
66        GENERATE
67        OUTPUT
68        "${CMAKE_CURRENT_BINARY_DIR}/picotcp_external/picotcp/build.sh"
69        CONTENT
70        "${CMAKE_COMMAND} -E env \
71        \"PLATFORM_CFLAGS=$<JOIN:${compile_options}, >\" \
72        \"CROSS_COMPILE=${CROSS_COMPILER_PREFIX}\" \
73        \"C_COMPILER=${C_COMPILER}\" \
74        ${perf_flags} \
75        make -s -j"
76    )
77
78    add_custom_target(get_muslc)
79    add_dependencies(get_muslc muslc)
80
81    # build picotcp using its very own build system
82    include(ExternalProject)
83    ExternalProject_Add(
84        picotcp_external
85        SOURCE_DIR
86        "picotcp_external"
87        DOWNLOAD_COMMAND
88        rsync
89        -qur
90        --exclude='.git'
91        ${PICOTCP_PATH}
92        <SOURCE_DIR>
93        UPDATE_COMMAND
94        ""
95        PATCH_COMMAND
96        sed
97        -i
98        "s/(CROSS_COMPILE)gcc/(C_COMPILER)/g"
99        picotcp/Makefile
100        CONFIGURE_COMMAND
101        ""
102        BUILD_COMMAND
103        cd
104        <SOURCE_DIR>/picotcp/
105        &&
106        sh
107        build.sh
108        BUILD_IN_SOURCE
109        1
110        INSTALL_COMMAND
111        ""
112        EXCLUDE_FROM_ALL
113        BUILD_BYPRODUCTS
114        "<SOURCE_DIR>/picotcp/build/lib/libpicotcp.a"
115        DEPENDS
116        get_muslc
117    )
118
119    file(
120        GLOB
121            deps
122            ${PICOTCP_PATH}/modules/*.c
123            ${PICOTCP_PATH}/modules/*.h
124            ${PICOTCP_PATH}/stack/*.c
125            ${PICOTCP_PATH}/include/**/*.h
126    )
127
128    # Add file dependencies to picotcp
129    ExternalProject_Add_StepDependencies(
130        picotcp_external
131        download
132        DEPENDS
133        ${PICOTCP_PATH}/Makefile
134        DEPENDS
135        ${deps}
136    )
137    # get the dir that the picotcp sources have been copied to by ExternalProject_Add
138    ExternalProject_Get_Property(picotcp_external SOURCE_DIR)
139    set(BUILD_DIR "${SOURCE_DIR}/picotcp/build/")
140
141    DeclareExternalProjObjectFiles(picotcp_external "${BUILD_DIR}/lib/" FILES "libpicotcp.a")
142
143    # create a library which is the sources
144    add_library(picotcp_sources STATIC IMPORTED GLOBAL)
145    add_dependencies(picotcp_sources picotcp_external)
146    set_property(TARGET picotcp_sources PROPERTY IMPORTED_LOCATION "${BUILD_DIR}/lib/libpicotcp.a")
147
148    # create a library which is the header files, that depends on the sources
149    add_library(picotcp INTERFACE)
150    add_dependencies(picotcp picotcp_sources)
151    set_property(TARGET picotcp PROPERTY INTERFACE_LINK_LIBRARIES picotcp_sources)
152    target_include_directories(
153        picotcp
154        INTERFACE
155            "${BUILD_DIR}/include" "$<TARGET_PROPERTY:picotcp_Config,INTERFACE_INCLUDE_DIRECTORIES>"
156            "$<TARGET_PROPERTY:sel4_autoconf,INTERFACE_INCLUDE_DIRECTORIES>"
157    )
158endif()
159if(LibPicotcpBsd)
160    # find pico tcp location
161    find_file(
162        PICOTCP_BSD_PATH picotcp-bsd
163        PATHS ${CMAKE_SOURCE_DIR}/projects
164        CMAKE_FIND_ROOT_PATH_BOTH
165    )
166    mark_as_advanced(FORCE PICOTCP_BSD_PATH)
167    if("${PICOTCP_BSD_PATH}" STREQUAL "PICOTCP_BSD_PATH-NOTFOUND")
168        message(
169            FATAL_ERROR
170                "Failed to find picotcp-bsd. Consider cmake -DPICOTCP_BSD_PATH=/path/to/picotcp-bsd"
171        )
172    endif()
173
174    add_definitions(-DSTDSOCKET)
175    add_definitions(-U__linux__)
176    add_definitions(-D_SYS_POLL_H)
177
178    # create picotcp_bsd library
179    add_library(
180        picotcp_bsd
181        STATIC
182        EXCLUDE_FROM_ALL
183        ${PICOTCP_BSD_PATH}/pico_bsd_sockets.c
184        ${PICOTCP_BSD_PATH}/pico_osal_noos.c
185    )
186    target_include_directories(picotcp_bsd PUBLIC ${PICOTCP_BSD_PATH})
187    target_link_libraries(picotcp_bsd muslc picotcp picotcp_Config sel4_autoconf)
188endif()
189