0

I want to set up a development environment for httpd(8) on OpenBSD with CLion (I'm using the Remote Project feature of CLion, but this isn't very different from working at an OpenBSD box). However, CLion forces me to use CMake, and I'm having some problem porting the Makefile into a CMakeLists.txt.

This is the Makefile from the original repo

#   $OpenBSD: Makefile,v 1.30 2017/07/03 22:21:47 espie Exp $

PROG=       httpd
SRCS=       parse.y
SRCS+=      config.c control.c httpd.c log.c logger.c proc.c
SRCS+=      server.c server_http.c server_file.c server_fcgi.c
MAN=        httpd.8 httpd.conf.5

SRCS+=      patterns.c
MAN+=       patterns.7

LDADD=      -levent -ltls -lssl -lcrypto -lutil
DPADD=      ${LIBEVENT} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL}
#DEBUG=     -g -DDEBUG=3 -O0
CFLAGS+=    -Wall -I${.CURDIR}
CFLAGS+=    -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+=    -Wmissing-declarations
CFLAGS+=    -Wshadow -Wpointer-arith
CFLAGS+=    -Wsign-compare -Wcast-qual
YFLAGS=

.include <bsd.prog.mk>

Despite the arcane syntax, it works perfectly on OpenBSD, and here is the output

openbsd$ uname -a
OpenBSD openbsd.my.domain 6.4 GENERIC#10 amd64
openbsd$ make
===> httpd
yacc  -o parse.c parse.y
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c parse.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c config.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c control.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c httpd.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c log.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c logger.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c proc.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c server.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c server_http.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c server_file.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c server_fcgi.c
cc -O2 -pipe  -Wall -I/home/nalzok/httpd/httpd -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wsign-compare -Wcast-qual  -MD -MP  -c patterns.c
cc   -o httpd parse.o config.o control.o httpd.o log.o logger.o proc.o server.o server_http.o server_file.o server_fcgi.o patterns.o -levent -ltls -lssl -lcrypto -lutil

As @Tsyvarev wisely pointed out in a comment, I must build parse.c from parse.y before linking everything together to produce an executable. Among others, bison(1) is a popular tool for making *.c from *.y, so my attempt looks like this. You must also install bison(1) and pass -DBISON_EXECUTABLE=/usr/local/bin/bison to CMake.

cmake_minimum_required(VERSION 3.10)
project(httpd)

find_package(BISON REQUIRED)
bison_target(parse httpd/parse.y "${CMAKE_CURRENT_BINARY_DIR}/parse.c")

set(CMAKE_C_FLAGS
        "-Wall -Wstrict-prototypes -Wmissing-prototypes"
        "-Wmissing-declarations -Wshadow -Wpointer-arith"
        "-Wsign-compare -Wcast-qual")

add_executable(httpd
        "${CMAKE_CURRENT_BINARY_DIR}/parse.c"
        httpd/config.c httpd/control.c httpd/httpd.c httpd/log.c httpd/logger.c httpd/proc.c
        httpd/server.c httpd/server_http.c httpd/server_file.c httpd/server_fcgi.c
        httpd/patterns.c)
target_link_libraries(httpd event tls ssl crypto util)

This problem is, CMake only provides a FindBISON module for bison(1), but what I really need to call is OpenBSD's stock yacc(1). Note that these two utilities are not perfectly interchangeable. For example, the yacc doesn't support the --version flag, whereas bison does. How do I instruct CMake to use yacc?

As a side note, this project is only intended to be deployed on OpenBSD, so feel free to use any unportable hack.

nalzok
  • 14,965
  • 21
  • 72
  • 139
  • It seems that `main` function in your case is defined in the `parser.y` file, which should be processed by Bison before passing it to compiler. Passing this file directly to `add_executable` doesn't work as you think. See duplicate question (and answer for it) about proper working with such files in CMake. Also, speciying `-l` options in `CMAKE_C_FLAGS` variable is wrong. See that question for more details: https://stackoverflow.com/q/43136418/3440745. – Tsyvarev Apr 25 '19 at 11:03
  • @Tsyvarev Thanks for the links, but I'm afraid this is not a duplicate. OpenBSD processes `*.y` files with [yacc(1)](http://man.openbsd.org/yacc) instead of `bison`, so I cannot simply use `find_package(BISON REQUIRED)`. – nalzok Apr 25 '19 at 11:26
  • As far as I undestand, `bison` and `yacc` programs are very internchangable. If `find_package(Bison)` doesn't work for you *out-of-the-box*, pass option `-DBISON_EXECUTABLE=yacc` to `cmake`. In any case, your question should describe that `main` function is defined in `parser.y`. "Guess-what-my-project-does" is not the way how Stack Overflow works. – Tsyvarev Apr 25 '19 at 11:36
  • @Tsyvarev Didn't realize I can specify the executable to cmake! The stock `yacc(1)` doesn't support the `--version` argument which cmake uses, so I ended up installing GNU bison and passing `-DBISON_EXECUTABLE=/usr/local/bin/bison`. Maybe this trick will work, but the `--version` issue clearly suggests these two are incompatible in some ways. Also, I don't think it's reasonable to expect me to realize `main` resides in `parser.y`. I'm cloning the repo from GitHub to study, and I haven't seen any `*.y` files before. – nalzok Apr 25 '19 at 11:52
  • Hm, so `yacc` and `bison` are not so interchangable. If you want your question to ask about using explicitely `yacc` in CMake, then rephrase the question, and I will reopen it. "Also, I don't think it's reasonable to expect me to realize `main` resides in `parser.y`." - You want to port the project, so you need to understand that project. At least, when face the error about missed `main`, you should be able to search its definition. Unlike to you, we cannot perform that search because we don't have the project's sources. – Tsyvarev Apr 25 '19 at 12:28
  • @Tsyvarev Please take a look at my edited question, and reopen it if you see fit. – nalzok Apr 25 '19 at 13:04
  • Ok, the question becomes clear and does not fit to the duplicate. So I have reopened it. – Tsyvarev Apr 25 '19 at 13:17
  • 1
    Note, that setting `BISON_EXECUTABLE` is needed only when the executable is not default one (e.g. you want to use `yacc` instead of `bison`, or wont to use bison which is installed locally). Normally, CMake is able to find that executable by itself, without hints. – Tsyvarev Apr 25 '19 at 13:19
  • 1
    `bison` has a special switch to emulate yacc: `bison -y`. – Matt Apr 25 '19 at 13:44

0 Answers0