Suppress "C source seen but `CC` undefined" in automake? - ocaml

I have a Makefile.am for compiling Ocaml source code with ocamlbuild. However, even
though I have
AM_INIT_AUTOMAKE([foreign no-dependencies])
in my configure.ac, automake thinks that a C compiler must be present to install exectuables. That is, if I put in Makefile.am a target executable under bin_PROGRAMS that is to be built with ocamlbuild, autoreconf (version 1.11.3) tells me:
Makefile.am: C source seen but `CC' is undefined
Makefile.am: The usual way to define `CC' is to add `AC_PROG_CC'
Makefile.am: to `configure.ac' and run `autoconf' again.
autoreconf: automake failed with exit status: 1
I do not want to include AC_PROG_CC because my source code includes no C. It is pure Ocaml. What can I do? (I have the same problem with libexec_PROGRAMS.)

It may be unneeded, but will it hurt anything to simply add AC_PROG_CC to Makefile.am? Path of least resistance and all.
Working off this decade-old mailing list message:
http://lists.gnu.org/archive/html/automake/2003-01/msg00057.html
It sounds like you might need to define progname_SOURCES as empty. If I understand the post correctly, if you omit an explicit declaraction, progname_SOURCES will implicitly be defined as progname.c.

If you add AC_SUBST([CC]) to configure.ac, that will be enough to define the variable as far as Automake is concerned.

Related

CMake FindFLEX produces NOTFOUND on windows

I installed flex and bison with chocolatey
choco install winflexbison3
and created this CMakeLists.txt
find_package(BISON)
find_package(FLEX)
message("FLEX_FOUND: ${FLEX_FOUND}")
message("FLEX_EXECUTABLE: ${FLEX_EXECUTABLE}")
message("FLEX_INCLUDE_DIRS: ${FLEX_INCLUDE_DIRS}")
message("FLEX_LIBRARIES: ${FLEX_LIBRARIES}")
BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
FLEX_TARGET(MyScanner lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(Foo
${BISON_MyParser_OUTPUTS}
${FLEX_MyScanner_OUTPUTS}
)
target_link_libraries(Foo ${FLEX_LIBRARIES})
I wrote a dummy parser (copied from https://aquamentus.com/flex_bison.html)
and tried to build the project
-- Found BISON: C:/ProgramData/chocolatey/bin/win_bison.exe (found version "3.7.4")
-- Found FLEX: C:/ProgramData/chocolatey/bin/win_flex.exe (found version "2.6.4")
FLEX_FOUND: TRUE
FLEX_EXECUTABLE: C:/ProgramData/chocolatey/bin/win_flex.exe
FLEX_INCLUDE_DIRS: FLEX_INCLUDE_DIR-NOTFOUND
FLEX_LIBRARIES: FL_LIBRARY-NOTFOUND
CMake Warning (dev) in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as
cmake_minimum_required(VERSION 3.23)
should be added at the top of the file. The version specified may be lower
if you wish to support older CMake versions for this project. For more
information run "cmake --help-policy CMP0000".
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring done
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
FL_LIBRARY (ADVANCED)
linked by target "Foo" in directory C:/Users/Aleksander/source/repos/C/insilico/blender/test
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
For some reason CMake can't find the library and include dir. What should I do? Where does FLEX expect the libraries to be?
This is what I did so far:
I see FlexLexer.h to be right there
C:\ProgramData\chocolatey\lib\winflexbison3\tools> ls
FlexLexer.h changelog.md custom_build_rules win_bison.exe
UNISTD_ERROR.readme chocolateyInstall.ps1 data win_flex.exe
I see that FindFLEX uses this source code to look for this file but somehow fails
https://github.com/Kitware/CMake/blob/241fc839d56ccd666fe41269e291b8d8190cf97b/Modules/FindFLEX.cmake#L117
find_library(FL_LIBRARY NAMES fl
DOC "Path to the fl library")
find_path(FLEX_INCLUDE_DIR FlexLexer.h
DOC "Path to the flex headers")
mark_as_advanced(FL_LIBRARY FLEX_INCLUDE_DIR)
set(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
set(FLEX_LIBRARIES ${FL_LIBRARY})
I found this documentation for find_path
http://devdoc.net/linux/cmake-3.9.6/command/find_path.html
and there is a list of paths that are searched. I queried them with
message("CMAKE_INCLUDE_PATH: ${CMAKE_INCLUDE_PATH}")
message("CMAKE_FRAMEWORK_PATH: ${CMAKE_FRAMEWORK_PATH}")
message("CMAKE_SYSTEM_INCLUDE_PATH: ${CMAKE_SYSTEM_INCLUDE_PATH}")
message("CMAKE_SYSTEM_FRAMEWORK_PATH: ${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message("CMAKE_LIBRARY_ARCHITECTURE: ${CMAKE_LIBRARY_ARCHITECTURE}")
message("CMAKE_FIND_ROOT_PATH: ${CMAKE_FIND_ROOT_PATH}")
message("CMAKE_SYSROOT: ${CMAKE_SYSROOT}")
and got
CMAKE_INCLUDE_PATH:
CMAKE_FRAMEWORK_PATH:
CMAKE_SYSTEM_INCLUDE_PATH:
CMAKE_SYSTEM_FRAMEWORK_PATH:
CMAKE_LIBRARY_ARCHITECTURE:
CMAKE_FIND_ROOT_PATH:
CMAKE_SYSROOT:
So it seems that find_path does absolutely nothing. Should I specify the paths myself? But is such case what is CMake even for?
It's astounding how many irritating problems are caused by a trivial library file which probably shouldn't exist anyway, and which is hardly ever needed.
The library in question was originally called libl (l for lex), and Posix requires that when you link executables which include a lex-generated scanner, you add -ll to the linker invocation. Flex, which to all intents and purposes is the current successor to the Lex tool, decided to change the name of the library to libfl, and that's generally what you'll find in a Flex installation. So the usual instructions you'll find these days (i.e., for the last several decades) say that you should use the command-line option -lfl.
Often, but not always, distributions add a symbolic link (or equivalent) for libl so that the Posix-specified -ll still works. Occasionally, the Flex distribution is modified so that the library is called libl, in which case -lfl won't work. And sometimes, the library isn't part of the distribution at all and needs to be acquired from a different package.
Posix wanted to cater for a Lex implementation which puts some functions into a library instead of generating the same code each time. But few (if any) lex implementations ever took advantage of that provision; in particular, Flex-generated scanners have no reliance on libfl for any internal function. There are only two functions defined in that library:
int main(void) { while (yylex()) {} }
int yywrap(void) { return 1; }
The first one is a default implementation of main which just calls yylex until it returns 0 (indicating EOF). That can be handy for quick-and-dirty scanner rule tests, but any real project will certainly have a main() definition.
The second provides a default yywrap implementation. However, Flex provides an even simpler way of indicating that the yywrap functionality isn't required:
%option noyywrap
If you don't require yywrap, you should just add the above to your .l file (in the prologue). If you do require yywrap, then you need to define it. In either case, you don't need the library.
So my recommendation is that rather wasting your time trying to figure out the deficiencies of the flex packaging you're using, just add the above %option to your Flex input file and eliminate the library from your build rules.

How to add preprocessor definitions on CMake's command line? [duplicate]

I try to set a preprocessor macro in the command line of CMake. I've tried:
set generator="Visual Studio 8 2005"
set params=-D MY_MACRO=1
cmake.exe -G %generator% %params% ..\some_project
but it's neither defined when I compile nor can I find the name MY_MACRO in the files generated by CMake at all, except for CMakeCache.txt where it's present in the form:
MY_MACRO:UNINITIALIZED=1
How can I do it?
A good alternative would be to define a cmake option:
OPTION(DEFINE_MACRO "Option description" ON) # Enabled by default
Followed by a condition:
IF(DEFINE_MACRO)
ADD_DEFINITIONS(-DMACRO)
ENDIF(DEFINE_MACRO)
Then you can turn that option ON/OFF via command line with cmake using the -D flag. Example:
cmake -DDEFINE_MACRO=OFF ..
To make sure the compiler is receiving the definition right, you can call make in verbose mode and check for the macro being defined or not:
make VERBOSE=1
This is a good solution also because make will recompile your code when any of cmake options changes.
Try this: -D CMAKE_CXX_FLAGS=/DMY_MACRO=1
The motivation behind the question was to batch build 3rd party libraries, which is why I wanted to avoid modifying CMakeLists. So years later, even though I don't need that anymore, I figured out that it's easily achievable by means external to CMake:
Invoke CMake as usual, no special flags.
Then:
With MSVC: The compiler reads the CL environment variable to get extra command line arguments. So
set CL=/DMY_MACRO=1 %CL%
then invoke MSBuild to do its job.
With Makefiles: The generated makefiles use the CFLAGS and CXX_FLAGS variables as makefiles are expected to do. So the build can be started by
make CXX_FLAGS=-DMY_MACRO=1
or by setting the corresponding environment variables.
Unless you have a good reason not to, you should use ADD_DEFINITIONS(<name>=<value>[, ...]).
Just add the following line to your CMakeLists.txt:
ADD_DEFINITIONS("MY_MACRO=1")
CMake will take care of the syntax of the switches (be it -D<name>=<value>, or /D<name>=<value>).

Can I manually use CMake's cpp file dependency-scanner in my cmake code?

I am trying to add a custom target with CMake that executes one command for each given .cpp file. The command should only be re-executed when the source file itself or one of the included source files changes. AFAIK to achieve this I need a list of all the included files and add them to the DEPENDS option of the add_custom_command() calls that belong to my custom target.
So is there a built-in way to get that list of included files?
I know about the IMPLICIT_DEPENDS option of the add_custom_command() function but it only works for Makefile generators. I would like to make this work for all generators.
Thank you for your time
Edit:
As requested I will post some cmake code to show what I want to achieve.
I want to add a custom target, that runs clang-tidy on all the given .cpp files. When incrementally building the custom target the clang-tidy commands should be re-run whenever a .cpp file or one of its directly or indirectly included header files is changed. Just like re-runs of the compiler are handled.
# ----------------------------------------------------------------------------------------
# mainTargetName The name of the target that shall be analyzed
# files A list of all the main targets .cpp files
#
function( addStaticAnalysisTarget mainTargetName files )
set(targetName runStaticAnalysis_${mainTargetName})
set(command "clang-tidy-4.0 -checks=* -p ${CMAKE_BINARY_DIR}")
foreach( file ${files} )
get_filename_component( baseName ${file} NAME_WE)
set(stampFile ${CMAKE_CURRENT_BINARY_DIR}/analyze_${baseName}.stamp )
set(fullFile ${CMAKE_CURRENT_SOURCE_DIR}/${file})
set(commandWithFile "${command} ${fullFile}")
separate_arguments_for_platform( commandList ${commandWithFile})
add_custom_command(
OUTPUT ${stampFile}
DEPENDS "${fullFile}"
IMPLICIT_DEPENDS CXX "${fullFile}"
COMMAND ${commandList}
COMMAND cmake -E touch "${stampFile}" # without creating a file as a touch-stone the command will always be re-run.
WORKING_DIRECTORY ${CPPCODEBASE_ROOT_DIR}
COMMENT "${commandWithFile}"
VERBATIM
)
list(APPEND stampFiles ${stampFile})
endforeach()
set_source_files_properties(${stampFiles} PROPERTIES GENERATED TRUE) # make the stamp files known to cmake as generated files.
add_custom_target(
${targetName}
DEPENDS ${stampFiles}
)
endfunction()
The problem with that is, that it does not seem to work. When I change included files clang-tidy is not re-run for the affected files.
I used the "Unix Makefile" generator for this example so it should work at least with make. Any hints why it doesn't?
My hopes where that I could achieve the desired behavior for all generators by somehow getting the file-dependencies at cmake time and then adding them to the ''''DEPENDS'''' list. But the dependency scanning must be done each time the command is run, so it can not be done at cmake time. This means that the scanning must be implemented by cmake which it currently is not.
A guy with similar problems:
https://gitlab.kitware.com/cmake/cmake/issues/16830
Edit 2:
I think the problem that the IMPLICIT_DEPENDS option was not working was because I did not use correct filenames. I changed that in the code snipped, but I have not yet tested if it works in the project.
I think the answer to my question is ...
No, you can not use cmakes dependency scanner in the cmake code.
That makes sense, because this problem can not be solved at cmake time, because the dependencies of a .cpp file may change without cmake being re-run.
The problem must be solved within cmake itself at make time. This is done when using the IMPLICIT_DEPENDS option.
Also, I tried to solve a Problem that I did not really have, because at this point I can only run clang-tidy on linux anyways. However, clang-tidy may become available on windows as well and then I may have the problem again.
To sum the comments up:
Tambre stated that CMake is not a compiler and therefore can not do that.
I think this is wrong. According to this article, CMake can parse cpp include dependencies because make has no such dependency searcher itself. That was news to me, but I mostly live on Windows so I am not that familiar with make. It could also be possible that in the meantime make was extended to do its own dependency searching. Also this explains why the IMPLICIT_DEPENDS option is only available for make.
Florian pointed out that it is not necessary to create an own custom target for running clang-tidy. Instead, one can use the CXX_CLANG_TIDY target property to run clang-tidy for each file after compiling it. This means however, that static-analysis can not be separated from the build which could lead to inacceptable buildtimes.
There is the cmake -E cmake_depends command line, that could be used to retrieve dependencies at cmake time. But as stated above, I erroneously thought that I needed the dependencies at cmake time, while I needed them at runtime.
The IMPLICIT_DEPENDS options did not work because I had an error in my cmake code.

How do I add objects with a custom extension to a cmake library?

I'd like to add some object files to a CMake static library, but they have a custom extension.
Here's what I've tried:
set(SRCS testfile.cxx jsobj.js)
add_library(testlib STATIC ${SRCS})
When made, CMake invokes ar testfile.cxx.o (ie the other file is completely ignored). How do I get it included in the archive? Here are some other tricks I've tried:
list(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS js)
list(APPEND CMAKE_C_SOURCE_FILE_EXTENSIONS js) # no luck
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/jsobj.js.o
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/jsobj.js
${CMAKE_CURRENT_BINARY_DIR}/jsobj.js.o
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/jsobj.js.o) # still no luck
(In case you're interested, I'm using the emscripten compiler, which can accept C/C++ files as source input, and JavaScript files are essentially "precompiled objects". I want to find a way to get CMake to add them to the ar commandline, that's all!)
For the record, this is how I solved my problem in a hacky way: "proper" solutions would be gladly accepted.
I made up a new file extension for my special pre-compiled objects, "jso", then added it to the list of input files CMake understands:
list(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS jso)
Then, I add my object files with the extension ".jso" to the CMake sources for inclusion in a static library target.
Finally, I hacked the compiler by setting CC=mycc, where mycc is a Python script which checks if the input has the extension ".jso": if not, it simply re-invokes the standard compiler; otherwise it copies the input to the output with no changes at all, so that mycc -c input.jso -o output.jso.o is just a file copy.
This isn't pretty, but it picks up all the dependencies perfectly for incremental builds. I can't pretend it's pretty, but doing things the way CMake likes seems to work. Here, we're just pretending all inputs are source files, even if they're actually already compiled.

Making autoconf search for C++ libraries

I'm writing my first configure.ac and need to search for a C++ library.
I tried the following line, but when run the configure script, it finds nothing.
AC_SEARCH_LIBS([xmlpp::Document::get_root_node], [xml++-2.6])
Probably something is wrong with it. So, how can I make autoconf look for C++ libraries? I don't want to supply a global method (and don't think libxml++ has one either).
You might want to try AX_CXX_CHECK_LIB from the Autoconf macro archive. you should probably make sure that you either use AC_LANG([C++]) or surround the call with AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]).
This link is about finding a C-style signature function to the library so that it can be tested by autoconf or write your own test:
https://nerdland.net/2009/07/detecting-c-libraries-with-autotools/
Maybe worth to try, but I am getting an error with the AC_LANG_PROGRAM macro. The problem is put -llibname before the foo.cpp file. My compiler cares about the order of the -l and cpp file. The linker will not be able to find the function in the library.
Hope this helps. My suggestion would be to use CMake instead of Autoconf.
This CMakeLists.txt file should get you started:
cmake_minimum_required(VERSION 2.8)
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#module:FindLibXml2
find_package(libxml2 2.6 REQUIRED) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:find_package
include_directories(${LIBXML2_INCLUDE_DIR}) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories
add_executable(myApp main.cpp other.cpp) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_executable
target_link_libraries(myApp ${LIBXML2_LIBRARIES}) # http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries
To use the file, after adjusting for your project of course. Put it in your Source dir as CMakeLists.txt, then:
mkdir build
cd build
cmake .. # This is like autoconf and generates the make files
make
If it sounds intriguing check out the giant youtube vid on all the benefits: http://www.youtube.com/watch?v=8Ut9o4OdSC0
It's good to use CMake, CTest, CDash, and CPack together in a project.