-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Windows support via CMake. #40
base: master
Are you sure you want to change the base?
Conversation
I'd very much like this to be merged. @Oblomov I have seen your comment in #20 and I would like to give a counter-argument: While adding an additional dependency to build this program may seem to add complexity, the opposite effect is true. Let's compare the current state of building clinfo with using CMake. Currently there are:
By adopting CMake, you would replace those 5 files with exactly one (+ template for the version header) that works on every operating system CMake supports (and that's quite a lot). CMake has become so ubiquitous that even fairly niche Unix systems like Solaris have it available in their system package manager. In other words, requiring users to install it is almost the same as just installing make itself at this point. This alone removes a lot of code maintenance burden. The other important point is package management, both consuming OpenCL and packaging clinfo itself. Consuming OpenCLFor Windows there is
Packaging clinfo
Last but not least: Adding a CMakeLists doesn't remove anything. It merely adds a new build system with all disadvantages of additional code, but the old stuff keeps working until removed. This is the second PR for adding a CMake build system and the third person asking for it. If people wouldn't have issues with the current situation they wouldn't keep submitting patches. I hope you reconsider your position. |
First of all I would like to congratulate @Oblomov on the utility. I arrived at this repo checking the exact I am the maintainer of the OpenCL dev package for Vcpkg and I would like to enhance the package with minimal utilities, such as As far as the script goes, I would like to propose a little bikeshedding… |
CMakeLists.txt
Outdated
@@ -0,0 +1,19 @@ | |||
cmake_minimum_required(VERSION 3.6) | |||
|
|||
if (WIN32 AND DEFINED ENV{VCPKG_ROOT}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be here. The entire point of Vcpkg is that the build scripts can be agnostic of using Vcpkg or not. Vcpkg is not Windows only, so there is no reason to check for targeting Windows or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I've removed the WIN32 component there.
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") | ||
endif () | ||
|
||
set(n clinfo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not be so lazy and rather use ${CMAKE_PROJECT_NAME}
when referring later to the name. At least make it something memorable, like ${Name}
. (I tend to use different capitalization for temporary vars.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean n
? I like it as it is, and it's nothing to do with laziness. You can suggest the change you suggest if the owner accepts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single letter variable names are not great. I'd just use clinfo everywhere instead of ${n}.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @ProGTX. Just writing clinfo
everywhere is much clearer than a cryptic ${n}
CMakeLists.txt
Outdated
target_include_directories(${n} PUBLIC ${OpenCL_INCLUDE_DIRS}) | ||
target_link_libraries(${n} ${OpenCL_LIBRARIES}) | ||
|
||
if (WIN32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property is not Windows specific but generator specific. If you want to guard it, correct check is
if (CMAKE_GENERATOR MATCHES "Visual Studio")
However, I would omit the check, as this directory property has no effect on generators other than VS. Perhaps a comment might suffice. If you really would like to cater to IDE users, I'd also add source_group properties for Filters in the project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've omitted the check. I'll leave you to suggest a source_group properties addition. I think they look ugly on small projects, and we don't need complexity at this stage in negotiations with the repo owner.
Thank you, I'd very much like to see this merged as well. Building with Makefiles is a pain, and this is much more portable - VS2017 supports CMake out of the box. I just use my own fork of the repo when I need to build it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this. The only thing that has to be added is CMAKE_DL_LIBS - I don't think it works on Linux without that.
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") | ||
endif () | ||
|
||
set(n clinfo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single letter variable names are not great. I'd just use clinfo everywhere instead of ${n}.
CMakeLists.txt
Outdated
add_executable(${n} src/${n}.c) | ||
target_include_directories(${n} PUBLIC src) | ||
target_include_directories(${n} PUBLIC ${OpenCL_INCLUDE_DIRS}) | ||
target_link_libraries(${n} ${OpenCL_LIBRARIES}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to link against CMAKE_DL_LIBS as well, if available. That's what the Makefile does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is on Linux:
[2/2] Linking C executable clinfo
FAILED: : && /usr/lib/ccache/cc CMakeFiles/clinfo.dir/src/clinfo.c.o -o clinfo /usr/lib/libOpenCL.so && :
/usr/bin/ld: error: undefined symbol: dlsym
>>> referenced by clinfo.c
>>> CMakeFiles/clinfo.dir/src/clinfo.c.o:(oclIcdProps)
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are of course correct :) I've added the change you suggest.
set(n clinfo) | ||
project(${n}) | ||
|
||
find_package(OpenCL REQUIRED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another sensible requirement would be CMAKE_C_STANDARD, 99 works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we keep this file simple for now. I hope for the repo owner to recognise how minor this addition is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine by me
add_executable(${n} src/${n}.c) | ||
target_include_directories(${n} PUBLIC src) | ||
target_include_directories(${n} PUBLIC ${OpenCL_INCLUDE_DIRS}) | ||
target_link_libraries(${n} ${OpenCL_LIBRARIES} ${CMAKE_DL_LIBS}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we require CMake 3.7 we could use an imported target instead and get rid of that include directory:
target_link_libraries(${n} PRIVATE OpenCL::OpenCL)
In any case, always use the PRIVATE/PUBLIC/INTERFACE keywords with target_link_libraries
. It is incompatible with the new syntax.
find_package(OpenCL REQUIRED) | ||
|
||
add_executable(${n} src/${n}.c) | ||
target_include_directories(${n} PUBLIC src) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified to a single function call:
target_include_directories(${n} PRIVATE src ${OpenCL_INCLUDE_DIRS})
If we use an imported target (see below), this comment can obviously be ignored.
cmake_minimum_required(VERSION 3.6) | ||
|
||
if (DEFINED ENV{VCPKG_ROOT}) | ||
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Toolchain files are evaluated very early, even before all the compiler checks. Setting this variable has no effect at all, it is supposed to be passed on the command line.
Did you mean to include()
this file instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not my PR, but honestly I'm still very much against adding automagic Vcpkg detection for multiple reasons:
- It cannot be turned off. If I wanted to pick up an OpenCL version other than what ships with Vcpkg it is impossible if it's hardcoded in the script.
- It is unorthodox. It goes against the biggest feature of Vcpkg, that scripts need not know of it's existence. That is the primary reason why Vcpkg is better than Conan. Scripts need to be Conan aware, while using Vcpkg is transparent to downstreams.
Users of Vcpkg already have a way of not spamming the command-line with toolchain file specification. If they use an IDE, in VS the toolchain file can be set in CMakeSettings.json (now with GUI) in a set-it-and-forget it manner once and for all. VS Code users are probably using CMake Tools and set the toolchain file via Kits, again: set-it-and-forget-it. Even if someone is a console junkie on Linux (and not using VS Code on Linux), they probably got tired of -D CMAKE_TOOLCHAIN_FILE=$(VCPKG_ROOT)/scripts/buildsystems/vcpkg.cmake ...
so they most likely have an alias set that adds this one variable to the invocation.
Long story short, I don't see the benefit of this, other than alienating non-Vcpkg users of ever reyling on it by giving the impression the scripts need to use this or just simply plaguing projects with it. Removing makes the script shorter, leaner and nicer in every regard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind either way, but you can always override the default search paths for a package by passing -DOpenCL_ROOT=C:/myopencl
. But speaking as a Conan user, I don't like the idea of using CMAKE_TOOLCHAIN_FILE
to inject package management like this. How does cross-compilation work with vcpkg?
That is the primary reason why Vcpkg is better than Conan. Scripts need to be Conan aware, while using Vcpkg is transparent to downstreams.
This is OT, but Conan's cmake_paths generator integrates exactly like vcpkg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does cross-compilation work with vcpkg?
Either our toolchain can be pulled in at the bottom of your own toolchain, or you can ask us to chainload yours via -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=xyz
.
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake") | ||
endif () | ||
|
||
set(n clinfo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @ProGTX. Just writing clinfo
everywhere is much clearer than a cryptic ${n}
Tested on Visual Studio 2017.